0%

Oracle自动删除归档日志

Oracle日志的分类

Alter log files:警报日志
Trace files:跟踪日志(用户和进程)
redo log :重做日志(记录数据库的更改)

重做日志

分为在线重做日志和归档重做日志
在线重做日志:又称联机重做日志,指Oracle以SQL脚本的形式记录数据库的数据更新,换句话说,实时保存已执行的SQL脚本到在线日志文件中
归档重做日志:简称归档日志,是指当条件满足时,Oracle将在线重做日志以文件形式保存到硬盘(持久化)
重做日志的简单原理:在数据更新操作commit前,将更改的SQL脚本写入重做日志。主要用于数据库的增量备份和增量恢复。
重做日志直接对应于硬盘的重做日志文件(有在线和归档俩种),重做日志文件以组的形式组织,一个重做日志组包括一个或多个日志文件。

归档重做日志

其实,所谓的归档,就是指,将在线日志进行归档,持久化成固定的文件到硬盘,便于以后的恢复和查询。当然,前提条件是数据库要处于归档模式。
在线重做日志大小毕竟是有限的,当都写满了的时候,就面临着俩个选择,第一个就是把以前在线重做日志从头擦除开始继续写,第二种就是把以前的在线重做日志先进行备份,然后对被备份的日志擦除开始写新的在线Redo File。这种备份的在线重做日志就是归档日志。而数据库如果采用这种生成归档日志的模式的话,就是归档日志模式(ARCHIVELOG模式),反之如果不生成归档日志,就是非归档日志模式(NOARCHIVELOG模式)。
有了归档日志有什么好处?
比如在这个月1号的时候备份了一次数据,然后过了10天,这个10天生成了很多在线重做日志,突然发现其中有一个数据磁盘出问题了,不能用了,那我该如何是好呢?
如果没有采用归档日志,那么实际上磁盘中只会有几个最新的在线重做日志。那么我只能把出问题的数据磁盘上所占据的表空间都删除掉。但是如果是SYSTEM表空间所设计的磁盘出错了,就没办法这么做了,只能用第二种方法。第二种方法就是把1号备份的数据拿出来恢复。那么1号到10号之间的10天的数据都丢了,如果是关键系统,比如证券金融什么的系统,就要让你赔钱赔死掉。
但是如果有了归档日志,那么你这10天的重做日志都会存放起来,那么DBA首先会把1号的备份数据恢复,然后再拿这10天的Redo日志来进行一次数据操作重放,那么就可以完全恢复最新的数据库,不会有什么后果了。
在软件开发的时候,由于测试服务器的配置有限,特别是磁盘空间有限,所以可能要限制Redo文件的大小,有可能把系统设置为NOARCHIVELOG模式了。但是在实际的生产环境下,基本上一定要使用ARCHIVELOG模式,否则万一出了问题,真是苦都来不及。
有人可能会怕归档日志造成性能损失。其实这个完全是杞人忧天的,归档日志只是做一个备份,其实也就是多耗一些磁盘空间而已。在当前的软件系统中,硬盘的存储容量成本已经属于低到可以忽略的地步,而最重要的是数据库的安全。DBA的任务本来就是确保数据的安全,如果连安全都保证不了,那点微乎其微的性能提高又有什么用呢。
归档日志(Archive Log)是非活动的重做日志备份。通过使用归档日志,可以保留所有重做历史记录,当数据库处于Archive Log模式并进行日志切换时,后台进程ARCH会将重做日志的内容保存到归档日志中,当数据库出现介质失败时,使用数据文件备份,归档日志和重做日志可以完全恢复数据库。

查看数据库当前是否为归档模式

SELECT LOG_MODE FROM V$DATABASE;
ARCHIVELOG(归档模式)、NOARCHIVELOG(非归档模式)

切换数据库为归档模式

shutdown immediate #关闭数据库
startup mount #开启数据库到挂载状态
alter database archivelog; #改变模式为ARCHIVELOG
archive log start; #开启归档日志
alter datebase open; #打开数据库

查找归档日志目录

SELECT destination FROM V$archive_dest;

在线重做日志的原理

对于在线重做日志,Oracle 11g默认对于每个数据库实例,建立3个在线日志组,每组一个日志文件,文件名称为REDO01.LOG,REDO02.LOG,REDO03.LOG。(用户可以通过视图操作添加/修改/删除日志组合日志文件来自定义在线重做日志)每组内的日志文件的内容完全相同,且保存在不同的位置,用于磁盘日志镜像,以做多次备份提高安全性。默认情况这3组通常只有一组处于活动状态,不断地同步写入已操作的脚本,当日志文件写满时(达到指定的空间配额),如果当前数据库处于归档模式,则将在线日志归档到硬盘,成为归档日志;若当前数据库处于非归档模式,则不进行归档操作,而当前在线日志的内容会被下一次重新写入覆盖而无法保存。因此,通常数据库在运行时,是处于归档模式下的,以保存数据更新的日志。当前归档日志组写满够,Oracle会切换到下一日志组,继续写入,这样循环切换;处于归档模式下,切换至原已写满的日志组,若该日志组归档完毕则则覆盖写入,若没有则只能使用日志缓冲区,等待归档完毕之后才能覆盖写入。当然,处于非归档模式下是直接覆盖写入的。

删除归档日志

由于归档日志日积月累,占用空间很大,我们只需要保留最近一段时间的日志即可,所以我们要对之前的内容做删除处理。

用oracle用户登陆rman并连接数据库

hostname@oracle$ rman target /

列出并确认归档日志路径

RMAN>list archivelog all;

删除7天以前的归档日志

RMAN>DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7'; 表明删除当前的系统时间7天前的日志

Windows下自动删除归档日志

新建E:\database_backup\rm_archivelog.txt文件

1
2
3
4
5
6
connect target  /
run{
crosscheck archivelog all;
DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7';
delete expired archivelog all;
}

新建E:\database_backup\rm_archivelog.bat文件

1
2
3
4
5
6
7
8
9
10
11
12
@echo off
set "filename=rm_archivelog_task_log_%date:~0,4%%date:~5,2%%date:~8,2%.txt"
(
echo.
echo ========================= 正在清除过期归档文件,请稍等...... %date% %time% =========================
echo.
rman cmdfile=E:\database_backup\rm_archivelog.txt
echo.
echo ========================= 【结束清理 %date% %time%】 =========================
echo.
)>>E:\database_backup\%filename% 2>&1<nul
pause

设置计划任务

每日凌晨执行E:\database_backup\rm_archivelog.bat脚本

Linux下自动删除归档日志

编写脚本

vim /home/oracle/.rm_archivelog.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
#Author 南山小樵
#Date 2019/12/16

if [ -f ~/.bash_profile ]; then
. ~/.bash_profile
fi
#set env

ORACLE_SID=orcl
ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1/

$ORACLE_HOME/bin/rman target sys/passwd@orcl log=/tmp/rman.log <<EOF
run{
crosscheck archivelog all;
delete noprompt expired archivelog all;
delete noprompt archivelog all completed before 'sysdate - 7';
}
exit;
EOF

给脚本赋予可执行权限

chmod +x /home/oracle/.rm_archivelog.sh

设置计划任务

crontab -l

1
00 3 * * * /home/oracle/.rm_archivelog.sh

参考链接:
https://www.jianshu.com/p/3bc8f372fe16
https://www.cnblogs.com/kerrycode/p/9046372.html