Oracle教程(8)Oracle 19C 单实例调整为 ADG 架构

Oracle教程(8)Oracle 19C 单实例调整为 ADG 架构

一、ADG架构介绍

Active Data Guard 简称ADG,是 Oracle Data Guard 架构下给物理备库(Physical Standby)追加的一个功能,非ADG模式下的物理备库只能保持数据同步,但不能对外提供查询,如果要提供只读查询需要暂停同步。开启 ADG 后,备库可以实现保持数据同步的同时提供只读服务,数据延迟通常在秒级,这样可以把报表、统计等只读查询从主库分流到备库,实现读写分离,同时不影响它随时切换接管为主库的容灾能力

二、Oracle 19C 单机改 ADG 步骤

1、主库部分

1.1 确认主库归档模式

ADG的底层原理是备库靠重放主库的归档日志来保持数据同步,如果主库不开归档就会存在主库已经将之前的redo日志覆盖了,但是备库还没有收到的情况(比如备库停机维护期间),此时就没有办法保证数据的同步了

-- 下面两条命令都可以查询是否开启归档模式
sqlplus / as sysdba

SQL> ARCHIVE LOG LIST;
Database log mode	       Archive Mode
Automatic archival	       Enabled
Archive destination	       /oraarch/DBXSPROD/archivelog
Oldest online log sequence     137242
Next log sequence to archive   137247
Current log sequence	       137247


SQL> SELECT log_mode FROM v$database;
LOG_MODE
------------
ARCHIVELOG


1.2 开启归档模式(如未开启)

如果是 ARCHIVELOG 代表已经开启归档模式,后续操作不用重启主库;如果是 NOARCHIVELOG 则必须先切换到归档模式,该操作只能在数据库 MOUNT 状态下进行,需要短暂停止数据库服务

SQL>SHUTDOWN IMMEDIATE;
SQL>STARTUP MOUNT;
SQL>ALTER DATABASE ARCHIVELOG;
SQL>ALTER DATABASE OPEN;
SQL>SELECT log_mode FROM v$database;
SQL>ALTER SYSTEM SWITCH LOGFILE;    #主动触发一次日志切换,验证归档进程确实能正常把日志写出去

1.3 主库信息核查

记录主库 db_unique_name 和 db_name,必须保持主备节点 db_name 相同,db_unique_name 则必须不同。db_unique_name 作为节点的身份标识,该参数是静态参数,如果改动必须重启数据库才会生效。db_name 参数不需要手工修改,备库在后续通过 RMAN 复制数据时会继承主库的值

# 这里主库 db_unique_name 为 dbxsprod,后续会给备库起一个名字 dbxsprod_standby

SQL> SHOW PARAMETER db_unique_name;
NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_unique_name	                        string	 dbxsprod
		     
		     
SQL> SHOW PARAMETER db_name;
NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_name 			     string	 dbxsprod

1.4 开启 FORCE LOGGING

Oracle 允许某些批量操作通过 NOLOGGING 的方式提升性能,但是由于这类操作不写完整的 redo,会导致备库数据不完整。通过 FORCE LOGGING 可以强制记录完整 redo,保证备库数据完整性。该操作可以在线修改,执行时只需要等待当前正在进行的 NOLOGGING 操作结束,不会锁库或中断连接

SQL> ALTER DATABASE FORCE LOGGING;



SQL> SELECT force_logging FROM v$database;
FORCE_LOGGING
---------------------------------------
YES

1.5 添加 Standby Redo Log

Standby Redo Log 虽然是在主库上创建,但是作用于备库。它用来接收主库实时发过来且还没归档完的 redo 数据。如果没有 standby redo log,主库必须等一个联机日志组写满、触发日志切换、生成了一份完整的归档文件之后才会把归档文件传给备库,这样备库和主库之间就存在数据延迟。通过 standby redo log,主库的 LGWR(日志写入进程)在把 redo 写入自己本地联机日志的同一时刻就会把这部分内容发给备库的 standby redo log,不需要等主库那边写满整个日志文件、切换、归档完成才进行传送。

· 查看主库联机日志的组数和大小

在创建 standby redo log 时,标准做法是单个文件的大小和主库联机日志一致,而组数需要在主库redolog基础上+1,多出来的这一组是为了避免日志切换时因为找不到空闲的 standby 组而发生短暂阻塞

# 可以看到6组日志,每个日志大小200M,编号为1-6

SQL> SQL> SELECT group#, bytes/1024/1024 AS size_mb, members FROM v$log;

    GROUP#    SIZE_MB	 MEMBERS
---------- ---------- ----------
	 1	  200	       1
	 2	  200	       1
	 3	  200	       1
	 4	  200	       1
	 5	  200	       1
	 6	  200	       1

· 添加standby log

standby redo log 的组号不能与现有组号冲突,一般顺着往后编写,比如主库是1/2/3,那么备库就可以使用4/5/6/7。这一步是纯新增文件,不影响任何现有日志组,可以放心在线操作,对业务无影响

-- 查看主库联机日志路径

SQL> SELECT member FROM v$logfile;

MEMBER
--------------------------------------------------------------------------------
/oradata/DBXSPROD/redo03.log
/oradata/DBXSPROD/redo02.log
/oradata/DBXSPROD/redo01.log
/oradata/DBXSPROD/redo04.log
/oradata/DBXSPROD/redo05.log
/oradata/DBXSPROD/redo06.log



-- 添加standby redo log,在redolog基础上增加一组
ALTER DATABASE ADD STANDBY LOGFILE GROUP 7 ('/oradata/DBXSPROD/stdredo07.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 8 ('/oradata/DBXSPROD/stdredo08.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 9 ('/oradata/DBXSPROD/stdredo09.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 10 ('/oradata/DBXSPROD/stdredo10.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 11 ('/oradata/DBXSPROD/stdredo11.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 12 ('/oradata/DBXSPROD/stdredo12.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 13 ('/oradata/DBXSPROD/stdredo13.log') SIZE 200M;

1.6 ADG 相关初始化参数

· 声明集群成员

各成员名字取参数 db_unique_name 的值 

ALTER SYSTEM SET log_archive_config='DG_CONFIG=(dbxsprod,dbxsprod_standby)';


· 主库 redo log 路径配置

主库产生的所有 redo 日志理论上有两个去处:一是本地归档用于数据恢复;二是传给备库,让备库重放这份 redo保持数据同步。Oracle 允许一个库同时配置多个 log_archive_dest_N(N 最多到 31),根据配置的内容决定日志到底是去哪里。随后会在备库也进行同样的配置,只是把远端目标地址互换了一下,这样可以在发生主备切换后保持日志传输的正常。

VALID_FOR参数说明:

ALL_LOGFILES,ALL_ROLES:不管是自己产生还是远端接收的redolog + 不管我现在是主还是备,本条配置都要生效进行本地归档,这样发生角色切换后参数也是生效的

ONLINE_LOGFILES,PRIMARY_ROLE:只有当这份redo是自己产生的,且自己现在是主的时候,才把这份 redo 外传给SERVICE所指定的备库

ASYNC:表示主库提交事务不需要等备库确认写盘成功,而是异步传输,这样可以避免拖累主库性能,只不过有小概率出现数据丢失

#先确认现有 log_archive_dest_1是不是已经有配置
SQL> SHOW PARAMETER log_archive_dest_1;


NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
log_archive_dest_1		     string	 location=/oraarch/DBXSPROD/archivelog

#定义主库本地归档
ALTER SYSTEM SET log_archive_dest_1='LOCATION=/oraarch/DBXSPROD/archivelog VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=dbxsprod';
ALTER SYSTEM SET log_archive_dest_state_1=ENABLE;



#先确认现有 log_archive_dest_2是不是已经有配置,这里为空表示还没有配置
SQL> SHOW PARAMETER log_archive_dest_2;

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
log_archive_dest_2		     string

#定义远端路径
ALTER SYSTEM SET log_archive_dest_2='SERVICE=dbxsprod_standby ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=dbxsprod_standby';
ALTER SYSTEM SET log_archive_dest_state_2=ENABLE;


· FAL配置

FAL(Fetch Archive Log)用于灾难恢复场景,如果备库因网络抖动漏收了某些归档日志,会主动向 fal_server 指定的库去补拉缺失的日志。这个参数主要在备库端起作用,现在属于预防性配置,发生主备切换后不用再去补这个配置

ALTER SYSTEM SET fal_server='dbxsprod_standby';


· 自动生成数据文件

主库新增或删除了数据文件(比如加表空间),设为 AUTO 后备库会自动同步建/删对应物理文件。如果不设置,主库加了数据文件后备库不会跟着建,等 redo 应用到那条 DDL 时 MRP 进程会直接报错并停止应用

ALTER SYSTEM SET standby_file_management=AUTO;

1.7 主库TNS配置

由于在主库 log_archive_dest_N 中配置了 SERVICE=ftxsprdu_standby ,所以需要增加一条TNS解析,不然无法识别这个名称背后的地址和端口。该配置文件是纯文本,客户端每次连接都会重新读取,不需要重启实例

# 主库 tnsnames.ora 添加:
su - oracle
vi $ORACLE_HOME/network/admin/tnsnames.ora
dbxsprod_standby =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.128.32.94)(PORT = 1521))
    (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = dbxsprod_standby))
  )
  
  
#验证
tnsping ftxsprdu_standby


2、备库部分

2.1 安装 Oracle

备库版本一定不能低于主库,只用安装数据库软件,不用运行dbca建库,过程略,环境变量配置如下

su - oracle
vi ~/.bash_profile

if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH

export ORACLE_SID=dbxsprod
export ORACLE_BASE=/oracle/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/19.10/db_1
export PATH=$ORACLE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export NLS_LANG=american_america.ZHS16GBK

umask 022


2.2 创建 listener.ora

因为备库实例此时还没启动,只能通过配置文件静态注册到监听器中。配置文件声明了监听名(服务名)、端口号等,后续 RMAN 连接备库 duplicate 也需要使用配置文件里的信息

vi /oracle/app/oracle/product/19.10/db_1/network/admin/listener.ora
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.128.32.94)(PORT = 1521))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = dbxsprod_standby)
      (ORACLE_HOME = /oracle/app/oracle/product/19.10/db_1)
      (SID_NAME = dbxsprod)
    )
  )

2.3 备库TNS配置

vi /oracle/app/oracle/product/19.10/db_1/network/admin/tnsnames.ora

dbxsprod =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.128.32.140)(PORT = 1521))
    (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = dbxsprod))
  )

2.4 启动监听

启动后确保 dbxsprod_standby 服务已经注册、状态 READY

lsnrctl start
lsnrctl status

2.5 TNS ping测试

主备节点都应该返回 OK

# 主库ping备库
tnsping dbxsprod_standby

# 备库ping主库
tnsping dbxsprod

3、密码文件同步

主备两端必须使用完全相同的密码文件,否则连接会失败,所以需要在主库上将密码文件传输给备库。密码文件固定存放在 $ORACLE_HOME/dbs 目录。密码文件命名规则固定为 orapw + ORACLE_SID 的方式,如orapwdbxsprod。

如果发现没有该文件或者连远程密码文件认证都没有开启的话需要按照后续步骤先行开启

#查看主库密码文件
[oracle@ftxsdb ~]$ ll $ORACLE_HOME/dbs
-rw-rw---- 1 oracle dba     1544 Aug 17  2025 hc_ftxsprdu.dat
-rw-rw---- 1 oracle dba     1544 Nov 10  2022 hc_ftxsprod.dat
-rw-rw---- 1 oracle dba     1544 Nov  7  2022 hc_ftxsprodm.dat
-rw-rw---- 1 oracle dba     1544 Nov  7  2022 hc_ftxsprodum.dat
-rw-r--r-- 1 oracle dba     1419 Nov 28  2022 initftxsprdu.ora
-rw-r--r-- 1 oracle dba     3079 May 14  2015 init.ora
-rw-r----- 1 oracle dba       24 Nov  7  2022 lkFTXSPRDU
-rw-r----- 1 oracle dba       24 Dec  8  2021 lkFTXSPROD
-rw-r----- 1 oracle dba       24 Nov  7  2022 lkFTXSPRODM
-rw-r----- 1 oracle dba       24 Nov  7  2022 lkFTXSPRODUM
-rw-r----- 1 oracle dba     2048 Nov 11  2022 orapwwdbxsprod         #需要确保有类似这样的文件存在
-rw-r----- 1 oracle dba 11288576 Sep 18 02:08 snapcf_ftxsprdu.f
-rw-r----- 1 oracle dba 11845632 Nov 10  2022 snapcf_ftxsprod.f
-rw-r----- 1 oracle dba     4608 Sep 17 14:14 spfileftxsprdu.ora
-rw-r----- 1 oracle dba     3584 Nov 10  2022 spfileftxsprdu.ora.bak
-rw-r----- 1 oracle dba     3584 Mar 31  2022 spfileftxsprod.ora


· 开启远程密码文件认证

确保主库已经开启远程密码认证功能,remote_login_passwordfile的值应该为 EXCLUSIVE。如果是 NONE 就必须开启并重启数据库才会生效。这个密码文件是专门给 SYSDBA、SYSOPER、SYSDG、SYSBACKUP 这类存在管理权限的账号使用的,确保数据库在没打开,甚至没 mount 的时候也能登录。而普通账号权限是存在数据字典里,是登录数据库后通过查字典验证,不需要密码文件

SQL> SHOW PARAMETER remote_login_passwordfile
NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
remote_login_passwordfile	     string	 NONE


#如果是NONE需要修改后重启数据库
SQL> ALTER SYSTEM SET remote_login_passwordfile='EXCLUSIVE' SCOPE=SPFILE;


#重启
SQL>SHUTDOWN IMMEDIATE;
SQL>STARTUP;


· 创建密码文件

需要确保这个文件和备库 listener.ora 里 SID_NAME 所配置的值是一致的

#查看SID
echo $ORACLE_SID

#重启完成后创建密码文件
orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID password=你设置的密码 force=y


· 传输密码文件到备库

scp /oracle/app/oracle/product/19.10/db_1/dbs/orapwftxsprdu oracle@10.128.32.94:/oracle/app/oracle/product/19.10/db_1/dbs/


传完之后在备库确认文件存在,属主正确,权限通常是640

[mb:oracle][/oracle/app/oracle/product/19.10/db_1/dbs]#ls -l /oracle/app/oracle/product/19.10/db_1/dbs/
total 8
-rw-r--r-- 1 oracle dba 3079 May 14  2015 init.ora
-rw-r----- 1 oracle dba 2048 Sep 18 09:27 orapwftxsprdu


4、RMAN 在线复制部分

4.1 主库创建复制用户

RMAN 做 DUPLICATE ... FOR STANDBY 操作时必须拥有 SYSDBA 权限,如果有SYS用户密码的话可以直接略过此步。如果忘了密码可以新建一个用户,新建后需要重新传输一次密码文件

#主库执行
CREATE USER adg_user IDENTIFIED BY ADGuser#202609;
GRANT SYSDBA TO adg_user;

#执行后确认下用户是否进入了密码文件
SELECT * FROM v$pwfile_users WHERE username='ADG_USER';

#重新同步密码文件到备库
scp /oracle/app/oracle/product/19.10/db_1/dbs/orapwftxsprdu oracle@10.128.32.94:/oracle/app/oracle/product/19.10/db_1/dbs/


4.2 备库创建pfile

备库此时还没有控制文件和任何的数据文件,这里需要先创建一个极简的pfile以启动实例,并切换到 nomount 状态,这样后续才能通过 RMAN 把控制文件和数据文件都复制过来

cat /tmp/init_dbxsprod_standby.ora
db_name='dbxsprod'                     #这里的名称需要和主库SHOW PARAMETER db_name一致
db_unique_name='dbxsprod_standby'      #ADG靠它区分主备身份,必须和主库不同
control_files='/oradata/DBXSPROD/control01.ctl','/oradata/DBXSPROD/control02.ctl'  #RMAN复制时会在这里生成控制文件,写两份是为了和主库保持一致,不是硬性要求
audit_file_dest='/oracle/app/oracle/admin/dbxsprod_standby/adump'  #实例启动、登录都会往这个目录写审计文件,必须提前建好


mkdir -p /oradata/DBXSPROD
mkdir -p /oraarch/DBXSPROD/archivelog
mkdir -p /oracle/app/oracle/admin/dbxsprod_standby/adump


4.3 使用pfile启动数据库实例

sqlplus / as sysdba


SQL> STARTUP NOMOUNT PFILE='/tmp/init_dbxsprod_standby.ora';
ORACLE instance started.
Total System Global Area 1182790760 bytes
Fixed Size		    8905832 bytes
Variable Size		  763363328 bytes
Database Buffers	  402653184 bytes
Redo Buffers		    7868416 bytes



SQL> SELECT status FROM v$instance;

STATUS
------------------------
STARTED


4.4 验证主备RMAN通信

在主库上通过rman连接两个节点,备库正常情况下应该是 not mounted ,对应备库的 NOMOUNT,正是复制开始前该有的状态。

[pvvmpgdb01:oraprod][/home/oraprod]#rman target adg_user/ADGuser#202609@dbxsprod auxiliary adg_user/ADGuser#202609@dbxsprod_standby
connected to target database: DBXSPROD (DBID=1201673755)
connected to auxiliary database: DBXSPROD (not mounted)

RMAN>


4.5 创建 RMAN 脚本

在主库上为RMAN建立一个配置文件

· FOR STANDBY FROM ACTIVE DATABASE:核心指令, RMAN 从主库把数据流式复制到备库,同时自动生成备库 standby controlfile。整个过程主库全程保持 open 对外服务,不会锁表,对主库影响小

· SPFILE:把参数文件也复制过去,并按 SET 项修改参数值,避免手工在备库配置

· SET:RMAN 复制 spfile 时会把主库参数全部搬过来,如果没有用 SET 声明的参数,备库都会和主库完全一样。SET 的作用就是把备库端明确需要和主库端不同的参数项进行声明,而这里的关键就是找出这些参数

· NOFILENAMECHECK:如果备库跟主库目录规划完全相同,通过该参数跳过路径校验,否则会因为路径一致而被拒绝;如果两边路径规划不同也不能加这个选项

cat > /tmp/duplicate.rman << 'EOF'
DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE
  SPFILE
    SET db_unique_name='dbxsprod_standby'
    SET control_files='/oradata/DBXSPROD/control01.ctl'
    SET audit_file_dest='/oracle/app/oracle/admin/dbxsprod_standby/adump'
    SET db_recovery_file_dest='/oradata/fra'
    SET local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=10.128.32.94)(PORT=1521))'
    SET log_archive_dest_1='LOCATION=/oradata/DBXSPROD/archivelog VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=dbxsprod_standby'
    SET log_archive_dest_2='SERVICE=dbxsprod ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=dbxsprod'
    SET fal_server='dbxsprod'
    SET standby_file_management='AUTO'
  NOFILENAMECHECK;
EOF


4.6 主库启动 RMAN 脚本

日志最后出现 Finished Duplicate Db 就是成功,备库会停在 MOUNT 状态

nohup rman target adg_user/ADGuser#202609@dbxsprod auxiliary adg_user/ADGuser#202609@dbxsprod_standby \
cmdfile=/tmp/duplicate.rman \
log=/tmp/duplicate.log > /dev/null 2>&1 &


#确保日志最后没有报错
tail -f /tmp/duplicate.log
datafile 62 switched to datafile copy
input datafile copy RECID=64 STAMP=1246296287 file name=/oradata/DBXSPROD/DS_IPLAT17.dbf
datafile 63 switched to datafile copy
input datafile copy RECID=65 STAMP=1246296287 file name=/oradata/DBXSPROD/DS_IPLAT18.dbf
datafile 64 switched to datafile copy
input datafile copy RECID=66 STAMP=1246296287 file name=/oradata/DBXSPROD/DS_IPLAT19.dbf
datafile 65 switched to datafile copy
input datafile copy RECID=67 STAMP=1246296287 file name=/oradata/DBXSPROD/DS_IPLAT20.dbf
datafile 66 switched to datafile copy
input datafile copy RECID=68 STAMP=1246296287 file name=/oradata/DBXSPROD/DS_SM08.dbf
datafile 67 switched to datafile copy
input datafile copy RECID=69 STAMP=1246296288 file name=/oradata/DBXSPROD/DS_SA02.dbf
Finished Duplicate Db at 2026/10/10 17:24:56

Recovery Manager complete.


5、备库应用日志部分

5.1 检查备库状态

预期spfile有值,不是临时pfile;db_unique_name 是 dbxsprod_standby;角色为 PHYSICAL STANDBY、STANDBY;状态为 MOUNTED;备库要用 standby redo log 接收主库实时传来的日志,必须存在

SQL>SHOW PARAMETER spfile;

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
spfile				     string	 /oracle/app/oracle/product/19.10/db_1/dbs/spfiledbxsprod.ora


SQL>SELECT name, db_unique_name, database_role, open_mode, controlfile_type FROM v$database;
NAME	  DB_UNIQUE_NAME		 DATABASE_ROLE	  OPEN_MODE    CONTROL
--------- ------------------------------ ---------------- ---------------------------
DBXSPROD  dbxsprod_standby		 PHYSICAL STANDBY MOUNTED    STANDBY


SQL>SELECT status FROM v$instance;
STATUS
------------
MOUNTED



SQL> SELECT group#, bytes/1024/1024 AS size_mb, status FROM v$standby_log;
    GROUP#    SIZE_MB STATUS
---------- ---------- ----------
	 7	  200 UNASSIGNED
	 8	  200 ACTIVE
	 9	  200 UNASSIGNED
	10	  200 UNASSIGNED
	11	  200 UNASSIGNED
	12	  200 UNASSIGNED
	13	  200 UNASSIGNED

	
SQL> SSELECT member FROM v$logfile WHERE type='STANDBY';
MEMBER
--------------------------------------------------------------------------------
/oradata/fra/DBXSPROD_STANDBY/onlinelog/o1_mf_7_odn134y8_.log
/oradata/fra/DBXSPROD_STANDBY/onlinelog/o1_mf_8_odn135j2_.log
/oradata/fra/DBXSPROD_STANDBY/onlinelog/o1_mf_9_odn1362q_.log
/oradata/fra/DBXSPROD_STANDBY/onlinelog/o1_mf_10_odn136mw_.log
/oradata/fra/DBXSPROD_STANDBY/onlinelog/o1_mf_11_odn1375v_.log
/oradata/fra/DBXSPROD_STANDBY/onlinelog/o1_mf_12_odn137r6_.log
/oradata/fra/DBXSPROD_STANDBY/onlinelog/o1_mf_13_odn1389k_.log


5.1 启动备库应用

备库启动 MRP(Managed Recovery Process),它负责持续把收到的 redo 应用到备库数据文件上,是备库保持与主库同步的核心机制。USING CURRENT LOGFILE 表示优先用 standby redo log 里正在写入的当前日志内容做实时应用,不用等一整个归档文件传完;DISCONNECT 表示命令下发后立即返回,MRP 在后台持续运行,不占用当前会话

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;


启动MRP后检查状态,MRP0 状态是 APPLYING_LOG 或 WAIT_FOR_LOG 说明在正常工作;v$archive_gap 如果有数据,表示有日志缺口,过一会儿自动补,一直不消失就要排查 fal_server 和网络

SQL> SELECT * FROM v$archive_gap;
no rows selected    #没有数据,说明复制期间主库产生的日志没有缺口,主库的归档没被清掉


SQL> SELECT process, status, thread#, sequence# FROM v$managed_standby;
PROCESS   STATUS	  THREAD#  SEQUENCE#
--------- ------------ ---------- ----------
ARCH	  CLOSING		1     138456
DGRD	  ALLOCATED		0	   0
DGRD	  ALLOCATED		0	   0
ARCH	  CLOSING		1     138457
ARCH	  CLOSING		1     138458
ARCH	  CLOSING		1     138459
RFS	  IDLE			1	   0
RFS	  IDLE			1     138460    #正在接收主库当前正在写的 138460 号日志,说明实时传输已经生效
RFS	  IDLE			0	   0
RFS	  IDLE			0	   0
RFS	  IDLE			0	   0

PROCESS   STATUS	  THREAD#  SEQUENCE#
--------- ------------ ---------- ----------
MRP0	  APPLYING_LOG		1     138384           #正在应用 138384 号日志


从上面的查询中可以看到主库已经写到 138460,备库应用到 138384,落后约 76 个日志,这是复制期间积压的。当前MRP 在追,追赶速度通常比主库产生日志的速度快,所以会逐渐缩小

SQL> SELECT process, status, thread#, sequence# FROM v$managed_standby;

#MRP0应用是138460,和 RFS 正在接收的 138460 相同,说明已经追评,现在是实时应用状态(边接收边应用)

PROCESS   STATUS	  THREAD#  SEQUENCE#
--------- ------------ ---------- ----------
ARCH	  CLOSING		1     138456
DGRD	  ALLOCATED		0	   0
DGRD	  ALLOCATED		0	   0
ARCH	  CLOSING		1     138457
ARCH	  CLOSING		1     138458
ARCH	  CLOSING		1     138459
RFS	  IDLE			1	   0
RFS	  IDLE			1     138460
RFS	  IDLE			0	   0
RFS	  IDLE			0	   0
RFS	  IDLE			0	   0

PROCESS   STATUS	  THREAD#  SEQUENCE#
--------- ------------ ---------- ----------
MRP0	  APPLYING_LOG		1     138460



在主库切一次日志,验证全链路。该操作执行完后后备库的 v$managed_standby 里 MRP0 的序号应该跟着变成 138461

#主库
ALTER SYSTEM SWITCH LOGFILE;


5.2 备库开启只读服务(Active Data Guard)

#备库要从 mount 状态切换到 OPEN READ ONLY 必须先结束当前的恢复会话,所以需要 CANCEL 停掉 MRP
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

#开启OPEN READ ONLY 让数据库可读,此时业务已经能连上去查询
ALTER DATABASE OPEN READ ONLY;

#重新启动 MRP,让它在只读状态下继续应用日志
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;


5.3 检查备库状态和数据

备库最终状态应该是 READ ONLY WITH APPLY

SQL> SELECT open_mode, database_role FROM v$database;

OPEN_MODE	             DATABASE_ROLE
--------------------         ----------------
READ ONLY WITH APPLY         PHYSICAL STANDBY

连接到备库,查询能正常返回说明只读服务可用

[dbxsprod_standby:oracle][/home/oracle]#sqlplus adg_user/ADGuser#202609@10.128.32.94:1521/dbxsprod_standby as sysdba


SQL> SELECT COUNT(*) FROM dba_tables;
  COUNT(*)
----------
      3896


6、主库创建只读账号(非必须)

账号创建以后,需要注意连接备库的服务名是 dbxsprod_standby

CREATE USER dbxs_ro IDENTIFIED BY "ro#202610";
GRANT CREATE SESSION TO dbxs_ro;
GRANT READ ANY TABLE TO dbxs_ro;


7、主库配置归档日志清理策略

rman target /
RMAN> SHOW ARCHIVELOG DELETION POLICY;

#下面查询结构返回的dNONE是默认值,说明没有配置过,RMAN 删归档时不会考虑备库是否已经应用
CONFIGURE ARCHIVELOG DELETION POLICY TO NONE; # default

#配置只允许删除备库已经应用的归档
RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY;


文章评论

猜你喜欢

 Oracle教程(7)RMAN 物理备份教程与实战

MySQL | Oracle Oracle教程(7)RMAN 物理备份教程与实战

一、RMAN 介绍RMAN 是 Oracle 自带的物理备份工具,它的核心作用是保护数据库的物理完整性,确保在发生磁盘损坏、误删数据文件、服务器整体故障等灾难场景下能够将数据库恢复到某个可用的状态。R...

Oracle运维管理——修改用户密码过期时间

MySQL | Oracle Oracle运维管理——修改用户密码过期时间

在 Oracle 数据库中,用户的密码有效期通过PROFILE(资源限制配置文件)中的 PASSWORD_LIFE_TIME 参数控制。如果没有为用户单独创建 PROFILE,默认使用一个...

Oracle教程(6)SGA\PGA\REDO核心参数调优

MySQL | Oracle Oracle教程(6)SGA\PGA\REDO核心参数调优

一、Oracle核心参数介绍1、SGASGA(System Global Area)是 Oracle 实例启动时分配的共享内存区域,所有连接到该实例的会话都共用这块内存,是整个数据库实例对外提供服务的...

Oracle教程(5)数据泵逻辑备份教程与实战

MySQL | Oracle Oracle教程(5)数据泵逻辑备份教程与实战

一、数据泵介绍数据泵(Data Pump)是 Oracle 10g 开始引入的命令行逻辑备份与恢复工具。通过 expdp / impdp ,可以对所有数据库对象(模式、表数据、表空间等)进行高效导出和...

MySQL教程(13)基于Position或GTID实现主从复制

MySQL | Oracle MySQL教程(13)基于Position或GTID实现主从复制

一、MySQL主从复制概述主从复制是MySQL高可用与横向扩展的基础方案,其核心依赖于 MySQL 自身的 Binlog 机制。主节点的 Binlog 记录了数据库上所有的 DDL 与 DML 操作(...