多年驰骋沙场,维护了不少小客户。
一直有一个很无语的问题,萦绕我胸中:
归档空间都满了,查原因是备份没正常运转。再查归档能看到好早以前的记录还在。
这个数据库整个周期都是我维护的,备份脚本是我写的,现场测试了是能正常运行。这事为什么呢。
我们习惯的备份周期是以周为单位,oracle的CONTROL_FILE_RECORD_KEEP_TIME默认也是7天。而且我们习惯性的把delete obsolete写到备份的最后。
CONTROL_FILE_RECORD_KEEP_TIME的保留机制类似于维护一个长度一定的循环链表,当在设定期限内,超出链表规模则会扩充链表大小。若没有超出了保留时间,但是没有超出链表规模,这个记录仍然是可以查到的,直到新的记录把这条撑出链表为止。
在备份和这个保留时间上有一个暧昧的时间差:
假如备份是每周日的23点,备份完成时间是次日的4点,obsolete清理记录是根据次日4点的时间点,在23-4之间的新增的归档是有可能一部分历史记录跟顶出去。
1.查看初始状态下归档日志目录的情况
ASMCMD> cd 2023_10_31/
ASMCMD> ls
thread_1_seq_19.262.1151692045
thread_2_seq_7.261.1151690465
ASMCMD> pwd
+ARCH/ORCLSTDB/ARCHIVELOG/2023_10_31
2.查看数据库中的V$CONTROLFILE_RECORD_SECTION视图,看到ARCHIVED LOG行的records_total=280意味着控制文件中只能保留280条归档日志文件信息。
3.通过大量测试数据生成产生了大量归档文件
10月31日归档文件数量为213
10月1日归档文件数量增长至258,继续生成归档至280开始进行删除归档测试。
可以看到当归档日志数量达到286的时候V$CONTROLFILE_RECORD_SECTION的records_total从之前的280变成了2800,说明数据库根据当前的归档日志增长数据自动增加了原有的归档文件限制值。但是在11月31日的时候归档文件数量还是 2.查出来的结果。
4.根据mos文档(Doc ID 1056085.1)的说明
CONTROL_FILE_RECORD_KEEP_TIME指定控制文件中可重用记录可重用的最小天数。不是最大天数CONTROL_FILE_RECORD_KEEP_TIME控制文件的记录被重用时,V$CONTROLFILE_RECORD_SECTION…RECORD_USED=RECORD_TOTAL对于每个使用循环记录(存档日志的部分。重做日志等)
查看当前数据库CONTROL_FILE_RECORD_KEEP_TIME参数:
按照文档的意思,CONTROL_FILE_RECORD_KEEP_TIME参数并不是强制在控制文件中保留多少天的归档日志条目,而是由V$CONTROLFILE_RECORD_SECTION视图中的ARCHIVED LOG条目去控制的,当RECORDS_TOTAL=RECORDS_USED时旧的归档日志就会被覆盖掉。我们11月31日查看到的RECORDS_TOTAL为280,如果目前的归档文件数量超过了280在清理归档日志的时候出现保留280数量以外的情况。因为当归档日志记录数量超过当前数据库的RECORDS_TOTAL旧的归档日志信息会被覆盖掉控制文件将不会记录这些信息。
5.归档删除测试来验证是否可以将10月31日的归档清理干净
SQL> select count(*) from v$archived_log;
COUNT(*)
----------
315
[grid@attest2 ~]$ asmcmd
ASMCMD> cd +ARCH/ORCLSTDB/ARCHIVELOG/
ASMCMD> ls
2023_10_31/
2023_11_01/
2023_11_02/
Used_MB Mirror_used_MB
44054 88108
##删除归档
[oracle@attest1 ~]$ rman target /
Recovery Manager: Release 19.0.0.0.0 - Production on Thu Nov 2 18:24:37 2023
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
connected to target database: ORCLSTDB (DBID=2739297357)
RMAN> delete force archivelog all completed before 'sysdate-1';
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=65 instance=orclstdb1 device type=DISK
List of Archived Log Copies for database with db_unique_name ORCLSTDB
=====================================================================
Key Thrd Seq S Low Time
------- ---- ------- - ---------
2 1 19 A 31-OCT-23
Name: +ARCH/ORCLSTDB/ARCHIVELOG/2023_10_31/thread_1_seq_19.262.1151692045
3 1 20 A 31-OCT-23
Name: +ARCH/ORCLSTDB/ARCHIVELOG/2023_10_31/thread_1_seq_20.263.1151692093
......
Do you really want to delete the above objects (enter YES or NO)? 选择yes
##删除了307个对象
再到asmcmd查看是否有未清理的归档:
[grid@attest1 ~]$ asmcmd
ASMCMD> lsdg
State Type Rebal Sector Logical_Sector Block AU Total_MB Free_MB Req_mir_free_MB Usable_file_MB Offline_disks Voting_files Name
MOUNTED NORMAL N 512 512 4096 4194304 97600 95232 0 47616 0 N ARCH/
MOUNTED NORMAL N 512 512 4096 4194304 58560 57596 19520 19038 0 Y CRS/
MOUNTED NORMAL N 512 512 4096 4194304 195264 68064 0 34032 0 N DATA/
ASMCMD> cd +ARCH/ORCLSTDB/ARCHIVELOG/
ASMCMD> ls
2023_11_01/
2023_11_02/
ASMCMD> cd 2023_11_01/
ASMCMD> ls
thread_1_seq_248.569.1151792587
thread_1_seq_249.570.1151792587
thread_2_seq_85.571.1151792587
发现11日还有未清理成功的归档日志。
在第二套环境把控制文件保留日期改成1在第二天继续测试
SQL> show parameter control
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
control_file_record_keep_time integer 7
control_files string +DATA/ORCL/CONTROLFILE/current
.261.1144618399, +ARCH/ORCL/CO
NTROLFILE/current.256.11446184
01
control_management_pack_access string DIAGNOSTIC+TUNING
SQL> alter system set control_file_record_keep_time = 1;
System altered.
SQL> show parameter control
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
control_file_record_keep_time integer 1
control_files string +DATA/ORCL/CONTROLFILE/current
.261.1144618399, +ARCH/ORCL/CO
NTROLFILE/current.256.11446184
01
control_management_pack_access string DIAGNOSTIC+TUNING
目前归档日志初始总数量为28
SQL> select * from v$controlfile_record_section where type='ARCHIVED LOG';
TYPE RECORD_SIZE RECORDS_TOTAL RECORDS_USED FIRST_INDEX LAST_INDEX LAST_RECID CON_ID
---------------------------- ----------- ------------- ------------ ----------- ---------- ---------- ----------
ARCHIVED LOG 584 28 7 1 7 7 0
##造归档日志数量到252后
SQL> select count(*) from v$archived_log;
COUNT(*)
----------
252
SQL> select * from v$controlfile_record_section where type='ARCHIVED LOG';
TYPE RECORD_SIZE RECORDS_TOTAL RECORDS_USED FIRST_INDEX
---------------------------- ----------- ------------- ------------ -----------
LAST_INDEX LAST_RECID CON_ID
---------- ---------- ----------
ARCHIVED LOG 584 448 252 1
252 252 0
将CONTROL_FILE_RECORD_KEEP_TIME设置的时间>(备份的周期+备份时间)