Zeuk, Zozo's father

Oracle 归档日志学习笔记

2019.01.21

Oracle 数据库在数据出错时可以使用 重做日志 (Redo Log)进行恢复,重做日志分为两部分:

  • 在线重做日志文件 (Online Redo Log Files)
  • 归档日志文件 (Archive Redo Log Files)

这里主要说一下归档日志 (Archive Log),在线重做日志大小毕竟是有限的,当都写满了的时候,就面临着2个选择,第一个就是把以前在线重做日志从头擦除开始继续写,第二种就是把以前的在线重做日志先进行备份,然后对被备份的日志擦除开始写新的在线 Redo Log,数据库如果采用这种生成归档日志的模式的话,就是归档日志模式 (ARCHIVELOG),反之如果不生成归档日志,就是非归档日志模式 (NOARCHIVELOG)。

Oracle 数据库默认采用的是非归档模式,假如说一共有三个重做日志组,当三个日志组全部写满之后将从第一个日志组开始循环记录,并且第一个日志组中的内容将被彻底覆盖,这样,如果数据库崩溃了,就没办法恢复很早之前的数据了。而使用归档模式后,这样写入日志循环的时候,会先把日志组中的数据写入到归档日志中,然后才会被覆盖,这样恢复问题就解决了,下面是一些常用的操作。

改变数据库归档模式

查看当前数据库归档模式

# 切换到 oracle 用户
su - oracle
# 进入 sqlplus 命令环境
sqlplus /nolog
# 使用管理员连接数据库
SQL> conn /as sysdba;
Connected.
# 查看当前归档模式,显示为非归档模式
SQL> select log_mode from v$database;     

LOG_MODE
------------
NOARCHIVELOG

关闭数据库

改变归档日志模式前要先关闭数据库

SQL> shutdown immediate;

打开控制文件

数据库以 mount 方式启动

SQL> startup mount;

启用归档模式

SQL> alter database archivelog;

关闭归档模式

SQL> alter database noarchivelog;

打开数据库

SQL> alter database open;

查看归档日志信息

SQL> archive log list;
Database log mode	       Archive Mode
Automatic archival	       Enabled
Archive destination	       USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     330
Next log sequence to archive   332
Current log sequence	       332

其他操作

查看默认闪回归档存储路径

SQL> show parameter db_recovery_file_dest;

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest		     string	 /data/oracle/flash_recovery_area
db_recovery_file_dest_size	     big integer 4977M

Oracle11g 版本,Oracle 默认的日志归档路径为闪回恢复区 ($ORACLE_BASE/flash_recovery_area)。对于这个路径,Oracle 有一个限制,就是默认只有 4G 的空间,而且不只是归档日志的默认路径,也是备份文件和闪回日志的默认地址,所以空间很容易不足,可以通过以下几个方式修改:

一、增大闪回空间大小

SQL> alter system set db_recovery_file_dest_size=8G scope=spfile;

二、修改归档日志存储路径

SQL> alter system set log_archive_dest_1='location=/data/oracle/archive_log' scope=spfile;

修改归档日志格式

SQL> alter system set log_archive_format='arch_%d_%t_%r_%s.arc' scope=spfile;

归档日志清理

随着时间的推移,归档日志可能会占满磁盘空间,这将导致无法连接到数据库,所以需要定期的清理一部分归档日志。那么我们就直接物理删除一些归档日志呗,可是别高兴的太早,在 Oralce 的 Control File 中仍然记录着这些 archivelog 文件的相关信息,当我们手工清除这些文件后,这些记录并没有被我们从 Control File 中清除掉,也就是 Oracle 并不知道这些文件已经不存在了。正确的方法是利用 Oracle 提供的 RMAN 工具进行清理。

正确删除归档日志的过程

# 切换为 oralce 用户
su - oracle
# 进入 rman 交互环境
rman
# 连接到本地数据库
RMAN> connect target /
# 核对控制文件和实际物理文件
RMAN> crosscheck archivelog all;
# 删除失效的归档日志文件,同步控制文件和物理文件信息。
RMAN> delete expired archivelog all;
# 删除 7 天前的归档日志
RMAN> delete archivelog all completed before 'sysdate-7';

定时清理归档日志

每次手工清理比较麻烦,而且也容易忘记,可以写一个自动清理脚本,然后利用定时任务定时进行清理。

# 切换为 oralce 用户
su - oracle
# 在用户目录下新建一个存放脚本和日志的文件夹
mkdir ~/auto_del_arc
# 新建脚本文件
vi ~/auto_del_arc/del_arc.sh
# 赋予可执行权限
chmod a+x ~/auto_del_arc/del_arc.sh

del_arc.sh 内容如下

#!/bin/bash
echo "----------------------------------------`date`---------------------------------------"
if [ -f ~/.bash_profile ]; then
. ~/.bash_profile
fi

export Today=`date +%Y%m%d`

$ORACLE_HOME/bin/rman target / log=~/auto_del_arc/${Today}.log <<EOF
run{
crosscheck archivelog all;
delete noprompt expired archivelog all;
delete noprompt archivelog all completed before 'sysdate - 7';
}
exit;
EOF
echo -e "\n"
echo "------------------------------------ FINISHED ------------------------------------"

脚本新建好以后,就可以添加到定时任务了

# 切换为 oralce 用户
su - oracle
# 编辑定时任务
crontab -e

# 在文件中添加如下行,代表每天凌晨2点执行清理
00 02 * * * ~/auto_del_arc/del_arc.sh
发表评论