长时间不去维护的oracle数据库的归档日志,日志会撑爆磁盘空间,最终数据库会因归档日志无法写入而停库。
在清理归档前首先要检查归档文件位置
$ sqlplus as sysdbasys@NEUHIP 20:27:27> archive log listDatabase log mode Archive ModeAutomatic archival EnabledArchive destination USE_DB_RECOVERY_FILE_DESTOldest online log sequence 1296Next log sequence to archive 1303Current log sequence 1303sys@NEUHIP 20:27:31> show parameter FILE_DESTNAME TYPE VALUE------------------------------------ ----------- ------------------------------audit_file_dest string u01/app/oracle/admin/neuhip/adumpdb_create_file_dest string oradatadb_recovery_file_dest string fradb_recovery_file_dest_size big integer 500G
通过启动参数可以确定数据库是否启动了归档模式,以及归档文件存放的位置。如果归档存放在文件系统中,后续可以通过文件系统对归档文件的数据量进行统计。
日常可以通过脚本自动对归档文件进行删除,免去忘记维护导致磁盘空间被撑爆的风险。
#!/bin/bashsource ~/.bash_profiledeltime=`date +"20%y%m%d%H%M%S"`rman target nocatalog msglog home/oracle/scripts/del_arch_${deltime}.log<<EOFcrosscheck archivelog all;delete noprompt archivelog until time 'sysdate-7';delete noprompt force archivelog until time 'SYSDATE-10';EOF
将删归档的脚本放到crontab中每天定时执行
$ crontab -l12 00 * * * /home/oracle/scripts/del_arch.sh
定时清除归档可以使控制文件中的备份记录与实际文件保持一致。如果长时间不清理,此时控制文件中的归档文件记录可能与实际不符。存在以下两种情况:
控制文件中归档日志文件还在,但磁盘上的文件不在了。
磁盘上的文件在,但控制文件中因过期或内容覆盖不再存了。
第一种情况可以通过 crosscheck archivelog all 验证控制文件中的归档日志记录是否还存在,如果不存在则将归档日志记录标记为 expired 。此时可以通过 rman 删掉控制文件中的 expired 记录,此时并没有删文件,只是删了控制文件中记录。
RMAN> crosscheck archivelog all;RMAN> list expired archivelog all;RMAN> delete expired archivelog all;
第二种情况就是控制文件中没有归档日志的记录,但磁盘或ASM磁盘组中却有相关文件。此时可以直接删除磁盘上的文件,但如果不方便删除。比如在磁盘组中删文件并不像文件系统中那么方便。此时可以通过catalog装载日志目录,重新识别归档日志,再通过 rman 删除早期日志。
RMAN> catalog start with '+FRA/hlwsdb/archivelog/';

重新识别之后,就可以通过rman对早期文件进行删除了
RMAN> delete noprompt archivelog until time 'sysdate-7';
除了这两种情况,还有一种情况,就是备份的归档日志。归档日志除了原生的归档,如果有备份软件通过rman对归档日志进行了备份。此时备份记录也会存在控制文件中,但归档日志实际上已经被备份软件转移走了。
RMAN> list backup of archivelog all summary;
从rman输出可以看到这些归档的备份类型是 SBT_TAPE 类型

具体的单个备份集的信息如下:

此时如果要删除这些控制文件中的备份记录,可以分配 SBT_TAPE 通道,然后对不存在的记录执行 delete 动作。
RMAN> allocate channel for maintenance device type sbt parms 'SBT_LIBRARY=oracle.disksbt,ENV=(BACKUP_DIR=/tmp)';RMAN> crosscheck backup;RMAN> delete expired backup;
此时不能使用 crosscheck archivelog all; 因为归档文件是在备份集中,而备份集是磁带类型,分配了磁盘通道之后只能检查备份集状态,而不能检查原始归档日志状态。
删除 expired 状态的备份集之后,控制文件内容就干净了:
RMAN> list expired archivelog all;specification does not match any archived log in the repositoryRMAN> list expired backup;specification does not match any backup in the repository
最后释放磁带类型的通道
RMAN> release channel;released channel: ORA_MAINT_SBT_TAPE_1




