<span id="be951aa4fc"></span><address id="bf99148926"><style id="bgb02a4fa8"></style></address><button id="bl12bf7221"></button>
                        

          • 博客访问: 558004
          • 博文数量: 105
          • 用 户 组: 普通用户
          • 注册时间: 2016-07-18 13:18
          • 认证徽章:
          文章分类

          全部博文(105)

          文章存档

          2018年(22)

          2017年(56)

          2016年(27)

          分类: Oracle

          2018-05-15 14:06:39


          众所周知我们的Data Guard数据同步是基于日志流的。所以在主库执行nologging操作是不被允许的。这也就是为什么我们需要在配置Data Guard阶段需要使用Force Logging。但是这也会带来很多问题(SQL执行效率),例如:当我们使用数据泵进行迁移时我们希望最少停机时间完成,这时候我们就可能会考虑到以最小日志导入的方式以加快导入速度,然后重新同步备库。

          在一些场景中,我们会去使用nologging操作去节省大量数据插入的时间,而这种操作所带来的问题就是,如果该库在有备库的情况下,因为主库的nologging插入操作不会生成redo,所以不会在备库上传输和应用,这会导致备库的数据出现问题。

          在Oracle 11g,如果遇到这样的问题,可以通过在备库恢复有问题的数据文件来解决问题,示例如下:

          在一个具有主备关系的主库上将force_logging设置为nologging模式,随后创建一张表,设置为nologging模式

          点击(此处)折叠或打开

          1. SQL> alter database no force logging;
          2. SQL> create table DEMO tablespace users pctfree 99 as select rownum n from xmltable('1 to 1000');
          3. SQL> alter table DEMO nologging;

          之后使用/* +append*/插入数据并提交

          点击(此处)折叠或打开

          1. SQL> insert /*+ append */ into DEMO select rownum n from xmltable('1 to 100000');
          2. SQL> commit

          这时候在备库对该表进行查询会看到如下报错信息

          点击(此处)折叠或打开

          1. SQL>select count(1) from demo;
          2. select count(1) from demo
          3.                  *
          4. ERROR at line 1:
          5. ORA-01578: ORACLE data block corrupted (file # 4, block # 819)
          6. ORA-01110: data file 4: '/data/data1/ORCL2/datafile/o1_mf_users_3ft1e9qb_.dbf'
          7. ORA-26040: Data block was loaded using the NOLOGGING option


          而要修复这个问题,需要将包含缺少的数据的数据文件从主库复制到物理备库。

          步骤一

          1、查询主库

          点击(此处)折叠或打开

          1. SQL> SELECT NAME, UNRECOVERABLE_CHANGE# FROM V$DATAFILE;
          2. NAME UNRECOVERABLE_CHANGE#
          3. --------------------------------------------------------------------------- ---------------------
          4. +DATADG/orcl/datafile/system.270.972381717 0
          5. +DATADG/orcl/datafile/sysaux.265.972381717 0
          6. +DATADG/orcl/datafile/undotbs1.261.972381717 0
          7. +DATADG/orcl/datafile/users.259.972381717 6252054
          8. +DATADG/orcl/datafile/example.264.972381807 0
          9. +DATADG/orcl/datafile/undotbs2.258.972381927 0
          10. +DATADG/orcl/datafile/example.266.972400297 0
          11. +DATADG/orcl/datafile/ax.268.973612569 0


          2、查询备库

          点击(此处)折叠或打开

          1. sys@ORCL>SELECT NAME, UNRECOVERABLE_CHANGE# FROM V$DATAFILE;
          2. NAME UNRECOVERABLE_CHANGE#
          3. --------------------------------------------------------------------------- ---------------------
          4. /data/data1/ORCL2/datafile/o1_mf_system_3dt1e9op_.dbf 0
          5. /data/data1/ORCL2/datafile/o1_mf_sysaux_3ct1e9nb_.dbf 0
          6. /data/data1/ORCL2/datafile/o1_mf_undotbs1_3gt1e9qq_.dbf 0
          7. /data/data1/ORCL2/datafile/o1_mf_users_3ft1e9qb_.dbf 5383754
          8. /data/data1/ORCL2/datafile/o1_mf_example_3et1e9ps_.dbf 0
          9. /data/data1/ORCL2/datafile/o1_mf_undotbs2_3ht1e9r1_.dbf 0
          10. /data/data1/ORCL2/datafile/o1_mf_example_3at1e9nb_.dbf 0
          11. /data/data1/ORCL2/datafile/o1_mf_ax_3bt1e9nb_.dbf 0


          3、比较主数据库和备用数据库的查询结果

          在两个查询结果中比较UNRECOVERABLE_CHANGE#列的值。如果主库中UNRECOVERABLE_CHANGE#列的值大于备库中的同一列,则需要将这些数据文件在备库恢复。

          步骤二 

          将主库对应的数据文件拷贝至备库


          点击(此处)折叠或打开

          1. SQL> alter tablespace users begin backup
          2. SQL> exit
          3. ASMCMD>cp +DATADG/orcl/datafile/users.259.972381717 /tmp
          4. $ scp /tmp/users.259.972381717 10.10.60.123:/data/data1/ORCL2/datafile/
          5. SQL> alter tablespace users end backup


          步骤三 

          备库将旧的数据文件rename至新的数据文件

          点击(此处)折叠或打开

          1. SQL> alter database recover managed standby database cancel;
          2. SQL> alter system set standby_file_management=manual; #在备库执行rename操作时,需要此参数为manual
          3. SQL> alter database rename file '/data/data1/ORCL2/datafile/o1_mf_users_3ft1e9qb_.dbf' to '/data/data1/ORCL2/datafile/users.259.972381717';
          4. SQL> alter system set standby_file_management=auto;
          5. SQL> alter database recover managed standby database using current logfile disconnect from session;


          之后就可以在备库查询到实例表DEMO

          点击(此处)折叠或打开

          1. SQL> select count(1) from demo;
          2.   COUNT(1)
          3. ----------
          4.     101000


          对于这种情况,在12.1版本中,RMAN提供了一种便捷的方式让我们不需要在主库上进行数据文件的备份传输而可以在备库使用 restore database (or datafile ) from service去从主库进行恢复。

          当然,Oracle的RMAN是足够聪明的:如果数据文件是正常的状态,RMAN可以根据它们的数据文件头进行跳跃恢复。如果,由于nologging操作导致某些块被标记为损坏的,那么这部分数据文件就是需要恢复的,然后怎么办?在恢复命令中有FORCE选项。但我们可能并不需要它。因为有些时候数据文件是同步的,实时日志应用进程还是在运行的。这个时候,为了恢复,我们需要停止应用。 

          一旦我们停止了应用,那么我们就不需要执行RESOTORE DATABASE FORCE操作,因为现在数据文件的状态是过旧的,就算你不加FORCE选项RMAN也是不会跳过这些数据文件的。

          步骤一 

          备库关掉实时日志应用,并开启至mount状态。

          点击(此处)折叠或打开

          1. SQL> alter database recover managed standby database cancel;
          2. SQL> shutdown immediate
          3. Database closed.
          4. Database dismounted.
          5. ORACLE instance shut down.
          6. SQL> startup mount
          7. ORACLE instance started


          步骤二 

          备库登陆RMAN,使用restore database (or datafile ) from service进行恢复

          点击(此处)折叠或打开

          1. RMAN> restore database from service 'primary_db'; #这里的primary_db,为备库至主库的tns连接串的别名
          2. Starting restore at 2018-05-03 17:00:35
          3. using target database control file instead of recovery catalog
          4. allocated channel: ORA_DISK_1
          5. channel ORA_DISK_1: SID=29 device type=DISK
          6. channel ORA_DISK_1: starting datafile backup set restore
          7. channel ORA_DISK_1: using network backup set from service primary_db
          8. channel ORA_DISK_1: specifying datafile(s) to restore from backup set
          9. channel ORA_DISK_1: restoring datafile 00001 to /data/data1/ORCL2/datafile/o1_mf_system_02t1t9ck_.dbf
          10. channel ORA_DISK_1: restore complete, elapsed time: 00:00:25
          11. channel ORA_DISK_1: starting datafile backup set restore
          12. channel ORA_DISK_1: using network backup set from service primary_db
          13. channel ORA_DISK_1: specifying datafile(s) to restore from backup set
          14. channel ORA_DISK_1: restoring datafile 00003 to /data/data1/ORCL2/datafile/o1_mf_sysaux_03t1t9d3_.dbf
          15. channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
          16. channel ORA_DISK_1: starting datafile backup set restore
          17. channel ORA_DISK_1: using network backup set from service primary_db
          18. channel ORA_DISK_1: specifying datafile(s) to restore from backup set
          19. channel ORA_DISK_1: restoring datafile 00004 to /data/data1/ORCL2/datafile/o1_mf_undotbs1_04t1t9di_.dbf
          20. channel ORA_DISK_1: restore complete, elapsed time: 00:00:02
          21. channel ORA_DISK_1: starting datafile backup set restore
          22. channel ORA_DISK_1: using network backup set from service primary_db
          23. channel ORA_DISK_1: specifying datafile(s) to restore from backup set
          24. channel ORA_DISK_1: restoring datafile 00006 to /data/data1/ORCL2/datafile/o1_mf_users_05t1t9dm_.dbf
          25. channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
          26. Finished restore at 2018-05-03 17:01:34


          当然要记得去起库并开启实时日志应用进程!

          而在12.2中,Oracle提供了一种更方便的方式去进行恢复主库会将未记录的块的列表发送至备库,并记录在备库控制文件中,我们可以从备库的v$nonlogged_block这个视图查看到相关信息。不需要发送主库的整个数据文件,而是在RMAN执行一个简单的命令来恢复它们:

          RECOVER DATABASE NONLOGGED BLOCK

          步骤一 

          停止备库实时日志应用

          点击(此处)折叠或打开

          1. SQL> alter database recover managed standby database cancel;


          步骤二 

          备库登陆RMAN执行

          RECOVER DATABASE NONLOGGED BLOCK 

          注意:执行此步骤前请确认主备库的log_archive_config参数已经设置

          点击(此处)折叠或打开

          1. RMAN> recover database nonlogged block;
          2. Starting recover at 2018-05-03 14:54:22
          3. using target database control file instead of recovery catalog
          4. allocated channel: ORA_DISK_1
          5. channel ORA_DISK_1: SID=56 device type=DISK
          6. starting recovery of nonlogged blocks
          7. List of Datafiles
          8. =================
          9. File Status Nonlogged Blocks Blocks Examined Blocks Skipped
          10. ---- ------ ---------------- --------------- --------------
          11. 1 OK 0 0 107519
          12. 3 OK 0 0 262399
          13. 4 OK 0 0 149759
          14. 5 OK 0 0 31999
          15. 6 OK 0 0 42239
          16. 7 OK 0 16707 21532
          17. 8 OK 0 0 12799
          18. 9 OK 0 0 76799
          19. 18 OK 0 0 33279
          20. 19 OK 0 0 57599
          21. 20 OK 0 0 24959
          22. 21 OK 0 0 33279
          23. 22 OK 0 0 51199
          24. 23 OK 0 0 12799
          25. 29 OK 0 0 1310719
          26. 30 OK 0 0 12799
          27. 31 OK 0 0 33279
          28. 32 OK 0 0 52479
          29. 33 OK 0 0 923519
          30. 34 OK 0 16822 8777
          31. 35 OK 0 0 12799
          32. 37 OK 0 0 24959
          33. Details of nonlogged blocks can be queried from v$nonlogged_block view
          34. recovery of nonlogged blocks complete, elapsed time: 00:00:08
          35. Finished recover at 2018-05-03 14:54:32

          最后别忘了开启实时日志应用进程。

          综上来看,12.2中这个特性在数据仓库等一些场景是可以尝试的。以往我们开启force logging造成大量的redo日志并且影响一部分dml语句的执行效率。在12.2我们可以尝试使用nonlogging操作去节省大量数据插入的时间,然后在系统空闲时间进行备库恢复操作。但是注意这种操作也存在弊端,这样你的备库的可用性就大大降低了。凡事总有取舍!


          |  作者简介

          陈康,沃趣科技数据库技术专家

          主要参与公司产品实施、测试、维护以及优化。


          阅读(2122) | 评论(0) | 转发(1) |
          给主人留下些什么吧!~~
          评论热议
          请登录后评论。

          登录 注册