挽救DG中主库的nologging操作的块

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

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

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

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

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*/插入数据并提交

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

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

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、查询主库

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、查询备库

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#列的值大于备库中的同一列,则需要将这些数据文件在备库恢复。

步骤二

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

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至新的数据文件

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

SQL> select count(1) from demo;
  COUNT(1)
----------
    101000

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

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

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

步骤一

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

SQL> alter database recover managed standby database cancel;
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started

步骤二

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

RMAN> restore database from service 'primary_db'; #这里的primary_db,为备库至主库的tns连接串的别名
Starting restore at 2018-05-03 17:00:35
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=29 device type=DISK
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: using network backup set from service primary_db
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00001 to /data/data1/ORCL2/datafile/o1_mf_system_02t1t9ck_.dbf
channel ORA_DISK_1: restore complete, elapsed time: 00:00:25
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: using network backup set from service primary_db
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00003 to /data/data1/ORCL2/datafile/o1_mf_sysaux_03t1t9d3_.dbf
channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: using network backup set from service primary_db
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00004 to /data/data1/ORCL2/datafile/o1_mf_undotbs1_04t1t9di_.dbf
channel ORA_DISK_1: restore complete, elapsed time: 00:00:02
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: using network backup set from service primary_db
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00006 to /data/data1/ORCL2/datafile/o1_mf_users_05t1t9dm_.dbf
channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
Finished restore at 2018-05-03 17:01:34

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

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

RECOVER DATABASE NONLOGGED BLOCK

步骤一

停止备库实时日志应用

SQL> alter database recover managed standby database cancel;

步骤二

备库登陆RMAN执行

RECOVER DATABASE NONLOGGED BLOCK 

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

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

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

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

|  作者简介

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

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

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏乐沙弥的世界

Oracle 表空间时点恢复(TSPITR)

表空间时点恢复,是Oracle在基于冷备,热备恢复以外的一种以表空间为粒度的,不完全恢复的形式来将表空间恢复到过去某个特定的时间点的一种恢复方式。它整合了RMA...

15020
来自专栏landv

SQLSERVER异机备份 T-SQL

47270
来自专栏乐沙弥的世界

关于undo表空间配置错误的ORA-30012

      undo表空间是Oracle体系结构的重要组成部分,为什么我们可以回滚,就是因为有它。数据库任意数据的修改都会在undo表空间里生成前镜像,一是可以...

7310
来自专栏全栈架构

Elasticsearch Java API 搜索之简介(三)

搜索查询,返回查询匹配的结果,搜索一个index / type 或者多个index / type,可以使用 queryJavaAPI(https://www.e...

9530
来自专栏杨建荣的学习笔记

alert日志中的两种ORA错误分析(r6笔记第21天)

今天在巡检系统的时候,发现alert日志中有两种类型的ora错误。 Errors in file /U01/app/oracle/diag/rdbms/XX/...

30050
来自专栏乐沙弥的世界

Oracle 实例恢复

Oracle实例失败多为实例非一致性关闭所致,通常称为崩溃(crash)。实例失败的结果等同于shutdown abort。

13750
来自专栏c#开发者

DataGrid和CheckBox的混合使用

我们知道DataGrid是非常强大的一个ASP.NET组件,我们可以用它表示非常丰富的信息.在论坛里经常可以看见一些网友问一些关于该控件的问题,我虽不是什么高手...

37090
来自专栏乐沙弥的世界

SYSAUX表空间管理及恢复

SYSAUX表空间是在10g之后引入的一个新的表空间,主要用于减轻对SYSTEM表空间的压力而作为SYSTEM表空间的辅助表空间。

11420
来自专栏乐沙弥的世界

中小型数据库 RMAN CATALOG 备份恢复方案(三)

      在前两篇文章中描述了中小型数据库使用RMAN catalog设计备份与恢复方案,并给出了所有相关的脚本来从某种车程度上模拟Oracle Data G...

8810
来自专栏逸鹏说道

SQL Server 数据库清除日志的方法

SQLSERVER的数据库日志占用很大的空间,下面提供三种方法用于清除无用的数据库日志文件 方法一: 1、打开查询分析器,输入命令 BACKUP LOG d...

44050

扫码关注云+社区

领取腾讯云代金券