本文的目的是描述 NOLOGGING 操作引起的ORA-1578 / ORA-26040坏块问题以及如何修复。
重要:
本文适用于用户和 Oracle Support。
如果数据段定义为
NOLOGGING 属性,当 NOLOGGING/UNRECOVERABLE 操作修改该数据段或者使用datapump import 参数
disable_archive_logging:y,联机重做日志只记录很少的日志信息,如果之后执行 RECOVERY
操作的话,会导致这些块无效。
SQL> select * from test_nologging;
DATAPUMP 参数 DISABLE_ARCHIVE_LOGGING
DATAPUMP
impdp 参数 DISABLE_ARCHIVE_LOGGING:Y 在import时禁止 LOGGING
定义,会产生NOLOGGING操作; 如果相应的datafile被restored 和 recovered, 那么接下来的语句会报错
ORA-1578 和 ORA-26040.
"如果database是 FORCE LOGGING 模式, 那么DISABLE_ARCHIVE_LOGGING 选项不会关闭logging.
import时使用这个参数的例子:
impdp scott/tiger directory=DATA_PUMP_DIR dumpfile=dp transform=disable_archive_logging:y
DBV 检测坏块时,如果 RDBMS 版本小于 10.2.0.4,那么 DBV 打印错误 DBV-200,如果 RDBMS 版本大于或等于 10.2.0.4,那么 DBV 打印错误 DBV-201 (
Note 5031712.8
):
DBV-00200: Block, dba 46137428, already marked corrupted
"VALIDATE" RMAN 命令用来检测NOLOGGING数据块,检查结果记录在 view v$database_block_corruption (versions lower than 12c) 和 v$nonlogged_block (12c and greater). 下面的例子中检查出datafile 4 有 933 坏块,查询v$database_block_corruption 或者 v$nonlogged_block。
RMAN> VALIDATE DATABASE;
10.2.0.4 and lower, 11.1.0.6, 11.1.0.7:
如果 RDBMS 版本大于或等于 10.2.0.5 和 11.2.0.1,RMAN 报告:查看视图 v$database_block_corruption 中 CORRUPTION_TYPE=NOLOGGING 的记录。参考
Note 7396077.8
:
10.2.0.5 and 11.2.0.1+:
在12c及以后版本中,RMAN validate的结果不在视图v$database_block_corruption中,而是在视图v$nonlogged_block:
12c:
RMAN validate的结果显示在视图v$nonlogged_block
在12.2 版本, 可以使用新的命令:"validate .. nonlogged block" 去验证nologging的block。 在以下的例子中,数据文件5,6有nologged的block:
RMAN> validate database nonlogged block;
Starting validate at ...
List of Datafiles
Details of nonlogged blocks can be queried from v$nonlogged_block view
Alert log中会更新以下信息:
Started Nonlogged Block Replacement recovery(validate) on file 5 (ospid 26351 rcvid 10616970560844821494)
Started Nonlogged Block Replacement recovery(validate) on file 6 (ospid 26351 rcvid 10616970560844821494)
NOLOGGING
导致的坏块不会导致 RMAN 备份失败,一般来说 soft corrupt block 不会导致 RMAN 备份失败,不需要设置
MAXCORRUPT。数据库备份中就会含有 soft corrupt block,如果使用这些备份恢复数据,那么恢复的数据也含有 soft
corrupt block。
除 ORA-26040 错误之外,当还有一些其他通用信息出现时,block dump 可
能会被产生,如果数据块的 block dump 内有 byte 0xff
信息或者属于某个段,ORA-1578/ORA-26040会因为介质恢复了NOLOGGING的部分导致了corruption而出现。
执行NOLOGGING操作,并且之后没有备份的情况下,RMAN 命令 "REPORT UNRECOVERABLE" 可以查询出被影响的datafile。
RMAN> report unrecoverable;
当初始化参数db_unrecoverable_scn_tracking设置为true (默认值),那么V$DATAFILE 中以下列会被更新;
UNRECOVERABLE_CHANGE#
在11.2.0.4 or 12.1.0.2+版本中,设置event 16490的情况下,物理备库的MRP进程会检查出NOLOGGING变化,并记录在alert log。
ORA-16490 "logging invalidated blocks on standby due to invalidation redo"
识别数据块什么时候被标志为NOLOGGING
使用trace文件中数据块SCN
Start dump data blocks tsn: 60 file#: 4 minblk 84 maxblk 84
提取SCN值 0x0771.4fa24eb5, 删除 '.' ,然后转换 0x07714fa24eb 到十进制 511453045995
使用v$database_block_coruption视图中CORRUPTION_CHANGE#值
获得SCN Timestamp
使用下面的方法获得时间:
select scn_to_timestamp(&&decimal_scn)
In 12c:
select file#, block#, scn_to_timestamp(NONLOGGED_START_CHANGE#)
如果查询gv$archived_log 或 gv$log_history遇到错误ORA-08181:
alter session set nls_date_format = 'DD-MON-YY HH24:MI:SS';
select first_time, next_time
或
select first_time
alter session set nls_date_format = 'DD-MON-YY HH24:MI:SS';
select file#, block#, first_time, next_time
或
select file#,block#,first_time
12c:
alter session set nls_date_format = 'DD-MON-YY HH24:MI:SS';
select file#, block#, first_time, next_time
OR
select file#, block#, first_time
SYSAUX表空间/AWR,EM 等出现NOARCHIVELOG 和 NOLOGGING 问题
如果数据库版本是11.1.0.6 或 11.1.0.7 或 11.2.0.1,
这种问题经常发生在SYSAUX表空间中的AWR或EM对象。
请参考Note 1071869.1。
这个约束在11.2.0.2以上版本中取消,这个问题在10g不会发生。
RDBMS版本变化
NOARCHIVELOG模式数据库,对NOLOGGING对象执行了DIRECT PATH操作,并且以后手动恢复数据库,即使打开了FORCE LOGGING,
以下RMAN命令被引入:
RMAN> validate [database / datafile] nonlogged block;
RMAN> recover [database / datafile] nonlogged block; -> 对于 Standby 数据库
解决方法
问题是在执行RMAN DUPLICATE或RESTORE之后产生?
如果问题是执行RMAN DUPLICATE 或 RESTORE之后 ,那么在源库打开FORCE LOGGING,然后再重新运行RMAN DUPLICATE 或 RESTORE。
alter database force logging;
问题是发生在物理standby库?
如果错误出现在
物理 STANDBY
数据库,
从主库恢复被影响的数据文件 (只有当主库没有这个问题的情况下)。参考文档Doc ID
958181.1。 在12c中可以使用RMAN选项RECOVER NONLOGGED BLOCK with
DATAFILE,TABLESPACE,DATABASE。例如:
RMAN> RECOVER DATABASE NONLOGGED BLOCK;
为了避免这个问题发生,在主库强制生产日志:
alter database force logging;
如果同一个datafile的数据块在主库出现nologging 坏块,但是备库没有,可以通过手动跳过(dbms_repair)坏块 或者设置event 10231.
识别被影响的Segment
参考
Note 819533.1
和
Note 472231.1
找到坏块所在的对象:
如果NOLOGGING数据块位于空闲数据块(dba_free_space视图可以查询到),DBVerify检查会发现这个问题,报错DBV-00201
如果是
索引
,重新创建(drop/create)索引。
如果是
表
,使用 procedure DBMS_REPAIR.SKIP_CORRUPT_BLOCKS 跳过坏块,请参考
Note 556733.1
获取包 DBMS_REPAIR 的使用示例。然后考虑是否重建表:
移动table: alter table &table_name move;
或者
保存数据 (export, Create Table as Select, etc) 然后truncate 或 drop/create
例子:
标记表中需要skip的块:
BEGIN
确认表的skipping corrupt blocks 是ENABLED:
select SKIP_CORRUPT
Move这个表:
alter table &table_name move;
OR if decided to save the data:
export (datapump or conventional export)
如果是LOB 参考Note 293515.1。
如果删除有坏块的段之后,这个坏块就处于空闲状态,后续可以被分配给其他对象/段,当这个坏块被分配给一个其他对象/段时,
适用于:
Oracle Database - Enterprise Edition - 版本 7.1.6.0 到 12.2.0.1 [发行版 7.1.6 到 12.2]本文档所含信息适用于所有平台
用途
如果只是错误ORA-1578,而没有伴随ORA-26040,那么这个坏块是其他的原因,可以通过RMAN Block Media Recovery修复。参考1578.1
适用范围
详细信息
如果这些联机重做日志/归档日志被用来恢复数据文件,那么 Oracle 会将对应的数据块标志为无效,而且下一次访问这些数据块时,会报 ORA-1578 和 ORA-26040错误。
例如:
ORA-01578: ORACLE data block corrupted (file # 11, block # 84)
ORA-01110: data file 4: '/oradata/users.dbf'
ORA-26040: Data block was loaded using the NOLOGGING option
以下数据字典视图中的 LOGGING 列记录了 NOLOGGING 属性:
DBA_TABLES, DBA_INDEXES, DBA_LOBS, DBA_TAB_PARTITIONS, DBA_LOB_PARTITIONS, DBA_TAB_SUBPARTITIONS, 等等。
LOGGING='NO' 表示 NOLOGGING。
接下来,这些数据块会被标志为 Soft Corrupt,当下一次访问该数据块时,会报 ORA-1578 和 ORA-26040错误。
利用 RMAN/DBV 检测 NOLOGGING 导致的坏块
DBV-00201: Block, DBA 46137428, marked corrupt for invalid redo application
...
.....
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
4 OK 933 1 6401 2275124
File Name: /oracle/dbs/users.dbf
RMAN 检测坏块时,如果 RDBMS 版本小于 10.2.0.5 和 11.1.0.7,RMAN 打印如下错误:
RMAN validate
reports it in
v$database_block_corruption
with
CORRUPTION_TYPE=LOGICAL
RMAN validate reports it in v$database_block_corruption with CORRUPTION_TYPE=NOLOGGING
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=133 device type=DISK
channel ORA_DISK_1: starting validation of datafile
channel ORA_DISK_1: validation complete, elapsed time: 00:00:35
=================
File Status Nonlogged Blocks Blocks Examined Blocks Skipped
---- ------ ---------------- --------------- --------------
1 OK 0 106363 0
2 OK 0 78919 0
3 OK 0 96639 0
4 OK 0 4991 0
5 OK 400 2559 0
6 OK 569 2559 0
Finished Nonlogged Block Replacement recovery(validate) on file 5. 400 blocks found
Finished Nonlogged Block Replacement recovery(validate) on file 6. 569 blocks found
监控 NOLOGGING 操作
using target database control file instead of recovery catalog
Report of files that need backup due to unrecoverable operations
File Type of Backup Required Name
---- ----------------------- -----------------------------------
4 full or incremental /oracle/dbs/users.dbf
db_unrecoverable_scn_tracking参数在10g中是不可用的。请参考Oracle Database在线文档中关于V$DATAFILE中以下列信息:
UNRECOVERABLE_TIME
FIRST_NONLOGGED_SCN
FIRST_NONLOGGED_TIME
"INVD_BLKS: Invalidating (file <file number>, bno <block number>)"
"fname: 'Datafile name'. rdba: ..."
识别数据块什么时候被标志为NOLOGGING,可以将trace文件中数据块SCN或者v$database_block_coruption视图中CORRUPTION_CHANGE#值
转换为时间:
例如:
buffer tsn: 3 rdba: 0x02c00054 (11/84)
scn: 0x0771.4fa24eb5 seq: 0xff flg: 0x04 tail: 0x4eb500ff
如果运行RMAN validate命令后,v$database_block_coruption视图中corruption_type='NOLOGGING' (10.2.0.5 和 11.2.0.1+),
那么CORRUPTION_CHANGE#列的值就是十进制的SCN值。
from dual;
如果运行RMAN validate:
select file#, block#, scn_to_timestamp(CORRUPTION_CHANGE#)
from v$database_block_corruption
where CORRUPTION_TYPE='NOLOGGING';
from v$nonlogged_block;
from gv$archived_log
where &decimal_scn between first_change# and next_change#;
from gv$log_history
where &decimal_scn between first_change# and next_change#;
如果运行RMAN validate:
from v$archived_log, v$database_block_corruption
where CORRUPTION_CHANGE# between first_change# and next_change#
and CORRUPTION_TYPE='NOLOGGING';
from v$log_history, v$database_block_corruption
where CORRUPTION_CHANGE# between first_change# and next_change#
and CORRUPTION_TYPE='NOLOGGING';
from v$nonlogged_block, v$archived_log
where NONLOGGED_START_CHANGE# between first_change# and next_change#;
from v$nonlogged_block, v$log_history
where NONLOGGED_START_CHANGE# between first_change# and next_change#;
对NOLOGGING对象执行过DIRECT PATH操作,并且后续执行了RECOVER DATABASE命令,及时数据库FORCE LOGGING是打开的情况下,
会出现ORA-1578 and ORA-26040错误。
注意数据库当前版本可能已经大于11.1 或者 11.2.0.1
但是问题可能是在升级之前产生的。
RDBMS版本
变化
10.2.0.4+
DBverify报告NOLOGGING block错误信息 "DBV-00201: Block, DBA <rdba>, marked corrupt for invalid redo application"
10.2.0.5, 10.2.0.1+
RMAN validate命令检查NOLOGGING block,在v$database_block_coruption视图中记录corruption_type='NOLOGGING'
11g+
引入
db_unrecoverable_scn_tracking
参数
11.1.0.6 or 11.1.0.7 or 11.2.0.1
也会报ORA-1578 和 ORA-26040。这个约束在11.2.0.2以上版本取消,这个问题在10g不会发生。
12c
RMAN validate的结果不在视图v$database_block_corruption中,而是在视图v$nonlogged_block
12.2
NOLOGGING 操作引起的坏块是不能修复的,比如"Media Recovery" 或 "RMAN blockrecover"都无法修复这种坏块。可行的方法是在 NOLOGGING 操作之后立刻备份对应的数据文件。
主库出现nologging 坏块可能是由于主库执行过备份恢复或者之前是备库,执行了switchover
或者在v$database_block_corruption视图中显示.对于这种情况,我们可以等待到这个数据块被重用时,会自动格式化,或者
手动强制格式化,参考Doc ID 336133.1
DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (
SCHEMA_NAME => '&schema_name',
OBJECT_NAME => '&table_name',
OBJECT_TYPE => dbms_repair.table_object,
FLAGS => dbms_repair.SKIP_FLAG);
END;
/
from dba_tables
where owner = '&schema_name'
and table_name = '&table_name';
or
Create Table &newtable as Select * From &nologging_corrupted_table;
这个数据块被重新格式化。 如果v$database_block_corruption或者是v$nonlogged_block (12c+)视图中还是显示为坏块,那么手动运行rman validate来清除视图中的信息。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31438871/viewspace-2158385/ ,如需转载,请注明出处,否则将追究法律责任。