暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

通过RMAN DUPLICATE...FROM ACTIVE DATABASE创建物理备库

923

一、Oracle Data Guard相关概念

  DG相关进程:

  • ARCH(Archiver):发送归档日志。
  • LGWR(Log Writer):当事务提交时,将Redo Buffer中的重做记录写入当前重做日志文件中,并将该记录传递给本地进程LNS。
  • LNS(LGWR Net Server):通过网络将重做日志传递给备库。
  • RFS(Remote File Server):接收来自主库的归档日志或重做日志,并将其写入备库的归档日志文件或备库联机重做日志文件中。
  • MRP(Managed Recovery Process):如果备库类型为物理备,则通过MRP进程应用日志来实现数据同步(也称Redo Apply)。
  • LSP:如果备库类型为逻辑备,则LSP进程会将日志转换为SQL语句,通过在备库上执行SQL语句来实现数据同步(也称SQL Apply)。

  从上可知ARCH和LWGR都可以用来发送日志,LGWR发送日志又可分为SYNC和ASYNC,下面给出三种日志发送模式下,Data Guard实现数据同步的原理。

1.ARCH发送日志

  1.Primary Database不断产生Redo Log,这些日志被LGWR进程写到联机日志。
  2.当一组联机日志被写满后,会发生日志切换(Log Switch)并且会触发本地归档。
  3.完成本地归档后,联机日志就可以被覆盖重用。
  4.ARCH 进程通过Net把归档日志发送给Standby Database的RFS(Remote File Server)进程。
  5.Standby Database端的RFS进程把接收的日志写入到归档日志。
  6.Standby Database端的MRP(Managed Recovery Process)进程(Redo Apply)或者LSP 进程(SQL Apply)在Standby Database上应用这些日志,进而同步数据。
image.png

2.LGWR SYNC方式发送日志

  1)Primary Database 产生的Redo 日志要同时写道日志文件和网络。也就是说LGWR进程把日志写到本地日志文件的同时还要发送给本地的LNSn进程(LGWR Network Server Process),再由LNSn(LGWR Network Server process)进程把日志通过网络发送给远程的目的地,每个远程目的地对应一个LNS进程,多个LNS进程能够并行工作。
  2)LGWR 必须等待写入本地日志文件操作和通过LNSn进程的网络传送都成功,Primary Database上的事务才能提交,这也是SYNC的含义所在。
  3)Standby Database的RFS进程把接收到的日志写入到Standby Redo Log日志中。
  4)Primary Database的日志切换也会触发Standby Database上的日志切换,即Standby Database对Standby RedoLog的归档。MRP或者LSP进程根据备库的恢复模式在不同的时机运用日志,若为实时恢复,则在RFS将日志写入备库重做日志之后触发日志应用,若为归档恢复,则在主库发生日志切换后触发日志应用。
  备库有两种恢复模式:

  • 实时恢复(Real-Time Apply):只要RFS把日志写入Standby Redo Log就会立即进行恢复;
# 以实时恢复的方式在后台启动Redo Apply,去掉DISCONNECT,则为前台启动
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;
  • 归档恢复:在完成对Standby RedoLog归档才触发恢复。
# 以归档恢复的方式在后台启动Redo Apply
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING ARCHIVED LOGFILE DISCONNECT;

  停止Redo Apply:

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

  SQL Apply的启停方式:

1.启动SQL Apply
ALTER DATABASE START LOGICAL STANDBY APPLY;
2.以实时应用的方式启动SQL Apply
ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
3.停止方式
ALTER DATABASE STOP LOGICAL STANDBY APPLY;

3.LGWR ASYNC方式发送日志

  1) Primary Database 一段产生Redo 日志后,LGWR 把日志同时提交给日志文件和本地LNS 进程,但是LGWR进程只需成功写入日志文件就可以,不必等待LNSn进程的网络传送成功。
  2) LNSn进程异步地把日志内容发送到Standby Database。多个LNSn进程可以并发发送。
  3) Primary Database的Online Redo Log 写满后发生Log Switch触发归档操作,也触发Standby Database对Standby Redo Log 的归档;然后触发MRP或者LSP 进程恢复归档日志。备库恢复方式同上一小节一致。
  下文将介绍如何通过RMAN DUPLICATE…FROM ACTIVE DATABASE创建物理备。

二、通过RMAN DUPLICATE…FROM ACTIVE DATABASE创建物理备库

1.环境概述

Database Version:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0
Instance Name:cdbtest(主)、cdbtestdg(备)
Database Name : cdb_test
Primary db_unique_name : cdb_test
standby db_unique_name : testdg
Container Database:Yes

2.主库配置

## 确保数据库开启归档
select log_mode from v$database;
## 数据库启用强制日志
alter database force logging;
## 创建备库redo日志,注意主备redo日志大小应该一样
alter database add standby logfile '/u01/app/oracle/oradata/CDB_TEST/onlinelog/standby01.log' size 10M;
## 修改初始化参数
alter system set LOG_ARCHIVE_CONFIG='DG_CONFIG=(cdb_test,testdg)';
alter system set LOG_ARCHIVE_DEST_1='LOCATION=/u01/arch/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=cdb_test';
alter system set LOG_ARCHIVE_DEST_2='SERVICE=testdg LGWR ASYNC VALID_FOR=(ONLINE_LOGFILE,PRIMARY_ROLE) DB_UNIQUE_NAME=testdg';
alter system set LOG_ARCHIVE_DEST_STATE_1=ENABLE;
alter system set FAL_SERVER=testdg;
alter system set FAL_CLIENT=cdb_test;
## 若数据文件存放位置有多个需要指定多个转换关系
alter system set DB_FILE_NAME_CONVERT='/u01/app/oracle/oradata/TESTDG/datafile/','/u01/app/oracle/oradata/CDB_TEST/datafile/','/u01/app/oracle/oradata/TESTDG/F20E4157E91EB61BE0534600000A53DD/datafile' ,'/u01/app/oracle/oradata/CDB_TEST/F20E4157E91EB61BE0534600000A53DD/datafile' scope=spfile;
alter system set LOG_FILE_NAME_CONVERT='/u01/app/oracle/oradata/TESTDG/onlinelog/','/u01/app/oracle/oradata/CDB_TEST/onlinelog/' scope=spfile;

3.网络配置

## 在备库系统中的listener.ora添加如下静态条目
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
     (GLOBAL_DBNAME = testdg)
     (ORACLE_HOME = /u01/app/oracle/product/19.3.0/dbhome_1)
     (SID_NAME = cdbtestdg)
    )
   )

LISTENER =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.100)(PORT = 1521))
  )
## 启动监听
lsnrctl start

## 主库和备库的tnsnames.ora都配置如下条目
cdb_test =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.70)(PORT = 1521))
    )
    (CONNECT_DATA = (SERVICE_NAME = cdb_test))
  )

testdg =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.100)(PORT = 1521))
    )
    (CONNECT_DATA = (SERVICE_NAME = testdg))
  )
  
## 检查网络配置是否正确
tnsping cdb_test
tnsping testdg

4.创建备库

## (1)将主库密码文件拷贝至备库
cd $ORACLE_HOME/dbs
orapwd file="$ORACLE_HOME/dbs/orapwcdbtest"  password=1234567z#  force=y
scp -rp orapwcdbtest oracle@10.0.0.100:/u01/app/oracle/product/19.3.0/dbhome_1/dbs/orapwcdbtestdg

## (2)创建初始化文件,仅包含db_name参数
[oracle@alldb /u01/app/oracle/product/19.3.0/dbhome_1/dbs]$ vim initcdbtestdg.ora
db_name=cdb_test
db_unique_name=testdg

## (3)创建必要的目录来存放数据库文件和追踪文件
[oracle@alldb /u01/app/oracle]$ mkdir oradata/TESTDG/datafile -p
[oracle@alldb /u01/app/oracle]$ mkdir oradata/TESTDG/onlinelog -p
mkdir /u01/app/oracle/fast_recovery_area
mkdir /u01/arch
mkdir /u01/app/oracle/admin/testdg/adump -p 
mkdir /u01/app/oracle/oradata/TESTDG/F20E4157E91EB61BE0534600000A53DD/datafile -p 
## (4)启动备库实例
export ADR_HOME=/u01/app/oracle/admin/testdg/adump
export ORACLE_SID=cdbtestdg
sqlplus / as sysdba
startup nomount pfile=$ORACLE_HOME/dbs/initcdbtestdg.ora;

## (5)验证“as sysdba”是否能够正常工作
sqlplus sys/1234567z#@cdb_test as sysdba
sqlplus sys/1234567z#@testdg as sysdba

## (6)在主库上通过rman连接主库和辅助库(备库)
rman target sys/1234567z#@cdb_test auxiliary sys/1234567z#@testdg
run {
allocate channel prmy1 type disk;
allocate channel prmy2 type disk;
allocate channel prmy3 type disk;
allocate channel prmy4 type disk;
allocate auxiliary channel stby type disk;

duplicate target database for standby from active database nofilenamecheck
spfile
  parameter_value_convert 'cdb_test','testdg'
  set db_unique_name='testdg'
  set LOG_ARCHIVE_DEST_1='LOCATION=/u01/arch/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=testdg'
  set db_file_name_convert='/u01/app/oracle/oradata/CDB_TEST/datafile/','/u01/app/oracle/oradata/TESTDG/datafile/','/u01/app/oracle/oradata/CDB_TEST/F20E4157E91EB61BE0534600000A53DD/datafile','/u01/app/oracle/oradata/TESTDG/F20E4157E91EB61BE0534600000A53DD/datafile'
  set log_file_name_convert='/u01/app/oracle/oradata/CDB_TEST/onlinelog/','/u01/app/oracle/oradata/TESTDG/onlinelog/'
  set control_files='/u01/app/oracle/oradata/TESTDG/controlfile/control01.ctl'
  set log_archive_max_processes='3'
  set fal_client='testdg'
  set fal_server='cdb_test'
  set standby_file_management='MANUAL'
  set log_archive_config='dg_config=(cdb_test,testdg)'
  set log_archive_dest_2='service=cdb_test ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=cdb_test'
;
}

  补充:当密码文件名和位置发生改变之后需执行如下命令,以便使用新的密码文件

ALTER SYSTEM FLUSH PASSWORDFILE_METADATA_CACHE;
# 在安装了GRID的环境中,可以使用如下命令来更改指定数据库的密码文件
srvctl modify database -db cdb_test -pwfile '/u01/app/oracle/product/19.3.0.0/dbhome_1/dbs/orapwcdbtest'

5.启动MRP进程

## 使用SQL*Plus连接到备库,并启动MRP (Managed Recovery Process)。
alter database recover managed standby database disconnect;

## 主备上查看DG相关进程,比较主最新的日志序号和MRP应用的日志序号
select process,pid,status,thread#,sequence#,block#,delay_mins from v$managed_standby;
select process,pid,status,thread#,sequence#,block#,delay_mins from v$managed_standby;

## 查看主备最新归档日志序列号信息
SELECT UNIQUE THREAD#, MAX(SEQUENCE#) OVER(PARTITION BY THREAD#) LAST FROM V$ARCHIVED_LOG; 

6.以只读模式打开备库(active dataguard)

  如果您已获得使用Active Dataguard (ADG)的许可,请以READ ONLY方式打开备库并开始恢复。

alter database recover managed standby database cancel;
alter database open;
alter pluggable database all open;
alter database recover managed standby database disconnect;  --实时恢复数据

## 查看DG状态
select * from v$dataguard_stats;

## 查看归档目标状态
select dest_name,type,database_mode,recovery_mode,protection_mode,standby_logfile_count,archived_seq#,applied_seq#,error,gap_status from v$archive_dest_status where dest_name='LOG_ARCHIVE_DEST_2';

7.查看主备之间相关进程建立的TCP连接信息

  例如查看备库RFS进程与主库相关进程建立的TCP连接信息:

## 1.备库执行:其中oraclecdbtestdg相应的改为oracle$ORACLE_SID
[root@alldb ~]# for pid in `ps -ef | grep "[o]raclecdbtestdg (LOCAL=NO)" |awk '{print $2}'`;do lsof -np $pid | grep -i tcp;done;
oracle_47 47538 oracle   13u     IPv4 879100       0t0       TCP 10.0.0.100:ncube-lm->10.0.0.70:31454 (ESTABLISHED)
oracle_47 47540 oracle   15u     IPv4 878531       0t0       TCP 10.0.0.100:ncube-lm->10.0.0.70:31456 (ESTABLISHED)
oracle_47 47542 oracle   13u     IPv4 878548       0t0       TCP 10.0.0.100:ncube-lm->10.0.0.70:31458 (ESTABLISHED)
oracle_47 47544 oracle   15u     IPv4 878551       0t0       TCP 10.0.0.100:ncube-lm->10.0.0.70:31460 (ESTABLISHED)
oracle_47 47546 oracle   18u     IPv4 878554       0t0       TCP 10.0.0.100:ncube-lm->10.0.0.70:31462 (ESTABLISHED)
## 2.根据上面的命令可以找到主库相关进程用于建立TCP连接的端口信息
[root@alldb ~]# (for pid in `ps -ef | grep "[o]raclecdbtestdg (LOCAL=NO)" |awk '{print $2}'`;do lsof -np $pid | grep -i tcp|awk -F':| +' '{print $11}';done;) |xargs|sed -r 's/ /|/g'
31454|31456|31458|31460|31462


## 3.在主库上查看对应的端口的TCP连接信息
netstat -antup | grep -E '31454|31456|31458|31460|31462'
tcp        0      0 10.0.0.70:31454         10.0.0.100:1521         ESTABLISHED 13114/ora_tt00_cdbt 
tcp        0      0 10.0.0.70:31458         10.0.0.100:1521         ESTABLISHED 13121/ora_arc1_cdbt 
tcp        0      0 10.0.0.70:31462         10.0.0.100:1521         ESTABLISHED 13123/ora_arc2_cdbt 
tcp        0      0 10.0.0.70:31456         10.0.0.100:1521         ESTABLISHED 41481/ora_tt05_cdbt 
tcp        0      0 10.0.0.70:31460         10.0.0.100:1521         ESTABLISHED 13125/ora_arc3_cdbt

## 4.在主库查看这个TCP连接对应进程名信息
[root@oracle4 ~]# netstat -antup | grep -E '31454|31456|31458|31460|31462' | awk -F'/| +' '{print $(NF-2)}'|xargs|sed "s/ /','/g" |sed "s/^/('/g" |sed "s/$/')/g"
('13114','13121','13123','41481','13125')

SYS@cdbtest> select process,pid,status,thread#,sequence#,block#,delay_mins from v$managed_standby where pid in ('13114','13121','13123','41481','13125');

PROCESS   PID			   STATUS	   THREAD#  SEQUENCE#	  BLOCK# DELAY_MINS
--------- ------------------------ ------------ ---------- ---------- ---------- ----------
DGRD	  13114 		   ALLOCATED		 0	    0	       0	  0
ARCH	  13121 		   CLOSING		 1	  139	       1	  0
ARCH	  13123 		   CLOSING		 1	  137	    5607	  0
ARCH	  13125 		   CLOSING		 1	  138	       1	  0
LNS	  41481 		   WRITING		 1	  140	   10840	  0

8.使用RMAN复制遇到的问题

(1)RMAN-05537

  执行RMAN数据复制时,报如下错:

RMAN-05537 DUPLICATE without TARGET connection when auxiliary instance is started with spfile cannot use SPFILE clause

  处理措施: 备库实例启动时需要使用pfile,不要使用spfile,但我的确是通过pfile来启动数据库的,仍旧报错这个错,后面我发现目录$ORACLE_HOME/dbs/下存在该实例的spfile,将之删除,重启备库,问题解决。

startup nomount pfile=$ORACLE_HOME/dbs/initcdbtestdg.ora;
(2)RMAN-05001

  详细报错信息如下所示:

RMAN-05001: auxiliary file name /u01/app/oracle/oradata/CDB_TEST/F20E4157E91EB61BE0534600000A53DD/datafile/o1_mf_system_kvzlo323_.dbf conflicts with a file used by the target database

  处理措施:在duplicate语句中加上nofilenamecheck,告诉RMAN不要检查目标数据文件与正在创建的复制文件是否共享相同的名称。

三、主备密码文件不一致问题(ORA-16191)

  Oracle数据库自12.2之后当数据库密码文件放置于ASM磁盘组中时,会自动同步主库SYS用户密码的变更信息至从库。本次测试所使用的数据库版本,将密码文件放置于文件系统中,当主库使用alter user修改了SYS用户的密码时,备库的密码文件也会自动更新。
  当DG搭建好之后,主备密码文件不一致时,并不影响备库实时恢复主库的变更信息,即使主库进行了日志切换,也是不会出现数据同步中断问题。当出于其它原因导致备库出现日志GAP时,也就是备库最新的日志序列号与主库不一致,然后备库启动FAL进程去主库获取缺失的日志,此时如果密码文件有问题,就会触发ORA-16191报错。恢复备库的密码文件,然后在主库上执行如下操作,即可恢复DG数据实时恢复。

# 主库操作
alter system set log_archive_dest_state_2 = defer;
alter system set log_archive_dest_state_2 = enable;

参考:
1.Step by Step Guide on Creating Physical Standby Using RMAN DUPLICATE…FROM ACTIVE DATABASE (Doc ID 1075908.1)
2.Oracle 11g DG概念与进程详解

最后修改时间:2024-12-03 13:51:36
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论