所谓数据写丢失,简单点就是当用户发生修改数据动作,且提交后,在磁盘上再次读取无法读到修改内容。发生写丢失的原因大多是由于IO子系统,固件发生问题导致.
A data block lost write occurs when an I/O subsystem acknowledges the completion of the block write,
while in fact the write did not occur in the persistent storage. The result is that the block
in the database is a stale/old copy which is not logical or physical corrupt;
而写丢失发生后,数据库是不报任何错误的,只有用户在用到数据后,发现异常才会发觉。
当db_lost_write_protect参数打开后,写丢失数据文件在进行问题时间段内的恢复时,会报出write lost错误,比如DATAGUARD环境,因为redo里记录着数据的变化,还有变化对应的时间戳,SCN等增量信息。
a>更新一条记录,记录当前的scn为110到日志文件中;
b>由于写丢失,导致当前数据库中的scn还是100;
c>在进行数据恢复时,先恢复SCN100,但当利用日志时发现100<110;
d>此时就会报出write lost的错误;
使用dd模拟数据写丢失现象:
SQL> alter system set db_lost_write_protect=typical scope=both;
SQL> SELECT a.*,dbms_rowid.rowid_object(rowid) objid,
2 dbms_rowid.rowid_relative_fno(rowid)rel_fno,
3 dbms_rowid.rowid_block_number(rowid) blockno,
4 dbms_rowid.rowid_row_number(rowid) rownumb
5 FROM sun.ddtab a;
ID NAME OBJID REL_FNO BLOCKNO ROWNUMB
---------- ---------- ---------- ---------- ---------- ----------
1 sun 20789 7 174 0
2 cheng 20789 7 174 1
[ora11@prim ~]$ dd if=/u01/app2/ora11/oradata/sunr/rman01.dbf of=ddtab_block.dd bs=8192 count=1 skip=174(第1块是OS使用)
[ora11@prim ~]$ strings ddtab_block.dd
cheng,
SQL> update sun.ddtab set name='qi';
SQL> commit;
SQL> SELECT * FROM sun.ddtab;
ID NAME
---------- -----------
1 qi
2 qi
RMAN> backup as compressed backupset datafile 7 format '/u01/backup/db_%U.db' plus archivelog ;
[ora11@prim ~]$ dd if=ddtab_block.dd of=/u01/app2/ora11/oradata/sunr/rman01.dbf conv=notrunc bs=8192 count=1 seek=174
SQL>aler system flush buffer_cache;
SQL> SELECT * FROM sun.ddtab;
ID NAME
---------- --------------
1 sun
2 cheng
[ora11@prim trace]$ mv /u01/app2/ora11/oradata/sunr/rman01.dbf /u01/app2/ora11/oradata/sunr/rman01.dbf.bak
RMAN> recover datafile 7;
Starting recover at 09-MAY-16
using channel ORA_DISK_1
starting media recovery
archived log for thread 1 with sequence 338 is already on disk as file /u01/app2/arch/1_338_885139531.dbf
archived log file name=/u01/app2/arch/1_336_885139531.dbf thread=1 sequence=336
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of recover command at 05/09/2016 23:24:27
ORA-00283: recovery session canceled due to errors
RMAN-11003: failure during parse/execution of SQL statement: alter database recover logfile '/u01/app2/arch/1_336_885139531.dbf'
ORA-00283: recovery session canceled due to errors
ORA-00752: recovery detected a lost write of a data block
ORA-10567: Redo is inconsistent with data block (file# 7, block# 174, file offset is 1425408 bytes)
ORA-10564: tablespace RMAN
ORA-01110: data file 7: '/u01/app2/ora11/oradata/sunr/rman01.dbf'
ORA-10561: block type 'TRANSACTION MANAGED DATA BLOCK', data object# 20789
解决方法:
1.可以是将参数屏蔽,然后直接恢复过去后再进行修复处理;
2.使用bbed跳过SCN;