合 恢复DG环境中由于主库nologging操作导致的坏块
简介
众所周知我们的Data Guard数据同步是基于日志流的。所以在主库执行nologging操作是不被允许的。这也就是为什么我们需要在配置Data Guard阶段需要使用Force Logging。但是这也会带来很多问题(SQL执行效率),例如:当我们使用数据泵进行迁移时我们希望最少停机时间完成,这时候我们就可能会考虑到以最小日志导入的方式以加快导入速度,然后重新同步备库。
在一些场景中,我们会去使用nologging操作去节省大量数据插入的时间,而这种操作所带来的问题就是,如果该库在有备库的情况下,因为主库的nologging插入操作不会生成redo,所以不会在备库上传输和应用,这会导致备库的数据出现问题。
11g恢复
在Oracle 11g,如果遇到这样的问题,可以通过在备库恢复有问题的数据文件来解决问题,示例如下:
在一个具有主备关系的主库上将force_logging设置为nologging模式,随后创建一张表,设置为nologging模式
1 2 3 | SQL> alter database no force logging; SQL> create table DEMO tablespace users pctfree 99 as select rownum n from xmltable('1 to 1000'); SQL> alter table DEMO nologging; |
之后使用/ +append/插入数据并提交
1 2 | SQL> insert /*+ append */ into DEMO select rownum n from xmltable('1 to 100000'); SQL> commit |
这时候在备库对该表进行查询会看到如下报错信息
1 2 3 4 5 6 7 | SQL>select count(1) from demo; select count(1) from demo * ERROR at line 1: ORA-01578: ORACLE data block corrupted (file # 4, block # 819) ORA-01110: data file 4: '/data/data1/ORCL2/datafile/o1_mf_users_3ft1e9qb_.dbf' ORA-26040: Data block was loaded using the NOLOGGING option |
而要修复这个问题,需要将包含缺少的数据的数据文件从主库复制到物理备库。
步骤一
1、查询主库
1 2 3 4 5 6 7 8 9 10 11 | SQL> SELECT NAME, UNRECOVERABLE_CHANGE# FROM V$DATAFILE; NAME UNRECOVERABLE_CHANGE# --------------------------------------------------------------------------- --------------------- +DATADG/orcl/datafile/system.270.972381717 0 +DATADG/orcl/datafile/sysaux.265.972381717 0 +DATADG/orcl/datafile/undotbs1.261.972381717 0 +DATADG/orcl/datafile/users.259.972381717 6252054 +DATADG/orcl/datafile/example.264.972381807 0 +DATADG/orcl/datafile/undotbs2.258.972381927 0 +DATADG/orcl/datafile/example.266.972400297 0 +DATADG/orcl/datafile/ax.268.973612569 0 |
2、查询备库
1 2 3 4 5 6 7 8 9 10 11 | sys@ORCL>SELECT NAME, UNRECOVERABLE_CHANGE# FROM V$DATAFILE; NAME UNRECOVERABLE_CHANGE# --------------------------------------------------------------------------- --------------------- /data/data1/ORCL2/datafile/o1_mf_system_3dt1e9op_.dbf 0 /data/data1/ORCL2/datafile/o1_mf_sysaux_3ct1e9nb_.dbf 0 /data/data1/ORCL2/datafile/o1_mf_undotbs1_3gt1e9qq_.dbf 0 /data/data1/ORCL2/datafile/o1_mf_users_3ft1e9qb_.dbf 5383754 /data/data1/ORCL2/datafile/o1_mf_example_3et1e9ps_.dbf 0 /data/data1/ORCL2/datafile/o1_mf_undotbs2_3ht1e9r1_.dbf 0 /data/data1/ORCL2/datafile/o1_mf_example_3at1e9nb_.dbf 0 /data/data1/ORCL2/datafile/o1_mf_ax_3bt1e9nb_.dbf 0 |
3、比较主数据库和备用数据库的查询结果
在两个查询结果中比较UNRECOVERABLE_CHANGE#列的值。如果主库中UNRECOVERABLE_CHANGE#列的值大于备库中的同一列,则需要将这些数据文件在备库恢复。
步骤二
将主库对应的数据文件拷贝至备库
1 2 3 4 5 | SQL> alter tablespace users begin backup SQL> exit ASMCMD>cp +DATADG/orcl/datafile/users.259.972381717 /tmp $ scp /tmp/users.259.972381717 10.10.60.123:/data/data1/ORCL2/datafile/ SQL> alter tablespace users end backup |
步骤三
备库将旧的数据文件rename至新的数据文件
1 2 3 4 5 | SQL> alter database recover managed standby database cancel; SQL> alter system set standby_file_management=manual; #在备库执行rename操作时,需要此参数为manual SQL> alter database rename file '/data/data1/ORCL2/datafile/o1_mf_users_3ft1e9qb_.dbf' to '/data/data1/ORCL2/datafile/users.259.972381717'; SQL> alter system set standby_file_management=auto; SQL> alter database recover managed standby database using current logfile disconnect from session; |
之后就可以在备库查询到实例表DEMO