直接说结论:在 Oracle AI Database 26ai 上用 RMAN 的 Active Duplicate 方式搭建 Data Guard 物理备库,是目前交付备库最快、最省事的一条路。你不需要先把主库做一次全量备份再传到备库机,也不需要手动在备库上一步步恢复数据文件,只要主备库之间网络通、监听通、口令文件一致,一条 duplicate target database for standby from active database 就能把备库拉起来。这篇文章我就以自己的实操顺序,把从环境规划、主库配置、RMAN 执行到备库状态确认的完整过程拆开讲,顺带把我在 AI 26ai 上踩过的几个坑也记录下来,给正准备做这件事的人一个参考。
我假设你手里的环境是 Oracle AI Database 26ai,主库和备库的 OS 用户都是 oracle,安装路径和 ORACLE_HOME 一致,主备库字符集相同,网络能互通。如果你用的是 19c 或者 21c,步骤基本一样,只是个别新特性不生效,不影响整体流程。
1. 为什么在 AI Database 26ai 上我仍然首选 Active Duplicate 建备库
先说背景。Oracle AI Database 26ai 是 Oracle 把 AI 能力大量内置进数据库内核的一代版本,比如 AI Vector Search、JSON Relational Duality 这些特性,但它的高可用架构依然没有跳出 Data Guard 这套成熟框架。也就是说,你以前在 19c、21c 上掌握的 Data Guard 概念,在这里几乎全部沿用,新版本只是给 SQL 引擎和自治运维层面加了更多能力。
在 26ai 上创建 Data Guard 备库,主流有三种方式:传统备份恢复、RMAN Active Duplicate、以及 DBCA 的 Data Guard 模板建库。我比较推荐 Active Duplicate,核心原因有三个。
第一,省掉备份中转环节。传统方式要求你先在主库做全库备份(通常还要带归档),再把备份集传到备库机上,然后用 restore + recover 恢复。这个过程非常依赖磁盘和网络带宽,备份集动不动几百 GB,传文件本身就是一件烦心事。Active Duplicate 通过 Oracle Net 直接把数据文件内容从主库推到备库,省去中间那份物理备份文件。
第二,目标结构可以由命令自动映射。备库的文件路径只要在主库路径基础上做 convert 映射,RMAN 就能自动把数据文件、控制文件、在线日志放到正确位置。如果主备库目录结构完全一致,甚至连 convert 参数都不需要。
第三,它在底层就是 backup as copy 的增量机制,不是单纯的冷拷贝。RMAN 会打开主库为只读或者保持读写状态,通过复制数据文件加增量备份的方式完成同步,数据库不需要停机。这对生产系统很友好,我在 26ai 上测试时,主库一直有业务写入,Active Duplicate 期间没有出现锁冲突或性能剧烈波动。
当然,Active Duplicate 也有它需要注意的短板。最明显的是对网络要求偏高,主备库之间如果走的是低带宽跨地域链路,整个过程会非常慢。另一个相对隐蔽的问题是,如果主库数据文件数量巨大(比如上万个数据文件),RMAN 的通道调度和文件复制会占用不少主库 I/O,建议在业务低峰期操作,并且显式 allocate channel 控制并行度。
注意:Active Duplicate 本质是“在线复制”,它要求主库的归档模式已经开启,且主库的
FORCE LOGGING建议打开,否则一些NOLOGGING操作可能造成备库数据不一致。这一点在 26ai 同样适用,别以为新版本会自动处理。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动手前必须做好的规划和检查项
做 Data Guard 最忌讳上来就跑命令,结果最后发现主备库的 db_unique_name 一样、监听起不来、目录不存在,白白浪费时间。我把我的习惯整理成一份检查清单,每一条都是在实际环境里验证过的。
2.1 主备库基本信息规划
在规划阶段,你要先确定几个关键参数,我习惯把它们写下来贴在终端旁边。
- 主库
db_unique_name:例如orcl - 备库
db_unique_name:例如orclstd - 主库
db_name:例如orcl - 备库
db_name:必须与主库完全一致 - 主备库 ORACLE_HOME:建议相同路径,例如
/u01/app/oracle/product/26.0.0/dbhome_1 - 主备库 ORACLE_SID:可以相同,也可以不同,但建议与
db_unique_name区分开,避免混淆 - 主库数据文件路径:例如
/u01/app/oracle/oradata/orcl - 备库数据文件路径:例如
/u01/app/oracle/oradata/orclstd
要注意 db_name 必须一致,因为 Data Guard 靠 db_name + db_unique_name 来识别同一套数据库的不同角色。两个库的 db_unique_name 不能相同,否则 Broker 和 Data Guard 进程会晕掉。
AI 26ai 默认安装时,db_unique_name 通常和 db_name 一样,比如 orcl。你要给备库单独设置一个不同的名字,后面我会说具体在哪里配置。
2.2 主库运行状态检查
在主库执行以下 SQL,确认当前状态:
sql复制SELECT name, db_unique_name, database_role, open_mode, log_mode, force_logging, platform_name
FROM v$database;
重点关注:
log_mode必须是ARCHIVELOG,如果不是,先启动物化归档:sql复制SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER DATABASE ARCHIVELOG; ALTER DATABASE OPEN;force_logging建议为YES,启用方式:sql复制开启后,即使某些表空间或表被设置为ALTER DATABASE FORCE LOGGING;NOLOGGING,也会强制记录 redo,避免备库应用日志时因为缺少 change record 而报错。database_role应为PRIMARY,open_mode应为READ WRITE。
2.3 目录规划
主备库的目录规划直接决定 convert 参数怎么写。我建议备库目录结构尽量与主库保持一致,这样最简单。如果做不到,那就必须在 RMAN 命令里写清楚 db_file_name_convert 和 log_file_name_convert。
我实际环境里主库路径是 /u01/app/oracle/oradata/orcl,备库路径打算用 /u01/app/oracle/oradata/orclstd。这种情况的 convert 参数我会在后面详细写。
需要注意的是,备库的目录必须提前建好,包括 oradata/...、fast_recovery_area(如果要用)、admin 目录等。RMAN 不会自动帮你创建目录,目录不存在时会直接报错,报错信息通常是 ORA-19505: failed to identify file,第一次做的人很容易被这个错误卡住。
2.4 主备库网络与监听配置
主备库之间要能通过 SQL*Net 互相访问。你需要:
- 主备库的
listener.ora里配置监听端口(默认 1521),AI 26ai 安装通常会自动配置一个监听器。 - 主备库的
tnsnames.ora里配置两个网络服务名:一个指向主库,一个指向备库。这两个名字在后面 RMAN 命令里会用到。
例如,主库的 tnsnames.ora 里要有类似这样的条目:
code复制ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = primary_host)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)
ORCLSTD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = standby_host)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orclstd)
)
)
备库的 tnsnames.ora 同样要能解析主库和备库的这两个条目。
这里有一个我在实际操作中反复踩的坑:Active Duplicate 连接备库实例时,如果你直接用 service name 去连,可能碰到 ORA-12514: TNS:listener does not currently know of service requested。因为备库此刻还没有 mount,它的 service 可能没有动态注册到监听上。解决办法是在备库的 listener.ora 里为备库实例配置静态监听。
静态监听条目大概长这样:
code复制SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orclstd)
(ORACLE_HOME = /u01/app/oracle/product/26.0.0/dbhome_1)
(SID_NAME = orclstd)
)
)
配置完成后要重载监听:lsnrctl reload。
提示:
SID_NAME要写备库实例的 SID,而不是 service name。GLOBAL_DBNAME是数据库对外注册的服务名,通常等于db_unique_name。在 Active Duplicate 时,RMAN 会先通过静态监听连接到一个空闲的nomount实例,然后再传送控制文件。
3. 主库端配置:为 Data Guard 打开所有前置条件
主库的准备越充分,后面 duplicate 越顺。这部分我会按顺序把参数、口令文件、归档开启、临时表空间检查都过一遍。
3.1 设置主库 Data Guard 相关参数
先查看主库当前 spfile 位置和参数情况:
sql复制SHOW PARAMETER db_unique_name;
SHOW PARAMETER db_name;
SHOW PARAMETER db_recovery_file_dest;
SHOW PARAMETER db_recovery_file_dest_size;
SHOW PARAMETER log_archive_dest_1;
SHOW PARAMETER log_archive_dest_2;
AI 26ai 默认不一定设置了 log_archive_dest_1 和 log_archive_dest_2。在搭建 Data Guard 时,至少在主库配置 log_archive_dest_2 指向备库,我常用 LOG_ARCHIVE_DEST_2='SERVICE=orclstd LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orclstd'。
不过如果你是为了快速先拉起备库,一开始可以不急着配 log_archive_dest_2,等 duplicate 完成后再配置,这样能减少变量。我实际测试中,如果不配 log_archive_dest_2,Active Duplicate 过程中主库不会额外地向备库传输归档;而配了的话,主库会在日志切换后自动把归档推到备库,只要备库 log_archive_dest_1 或者 FRA 里有足够空间接住就可以。
如果主库没有配置 FRA,我建议先设置好:
sql复制ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 100G SCOPE=BOTH;
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST = '/u01/app/oracle/fast_recovery_area' SCOPE=BOTH;
备库在 duplicate 完成后,同样需要 FRA 或者归档目录来接收主库传过来的日志。如果 FRA 空间不足,备库日志应用会暂时卡住,主库会出现 ARCH 进程等待。
再检查一下 compatible 参数。建议主备库设置为一致,且不低于 19.0.0,AI 26ai 的默认值通常会比较高。如果主备库版本不一致,RMAN duplicate 时可能出现兼容性问题。
3.2 生成主库的备用参数文件(pfile)
这一步是很多人会漏掉的。在 duplicate 备库时,RMAN 需要一个参数文件来启动备库实例到 nomount 状态。如果用 SPFILE 方式,RMAN 会自动从主库拉取 spfile,但如果你用 PFILE 方式,就必须提前准备好一份只适用于备库的参数文件。
我的习惯是用 CREATE PFILE 从主库生成:
sql复制CREATE PFILE='/u01/app/oracle/init_orclstd.ora' FROM SPFILE;
然后编辑这份 pfile,把以下参数改为备库的值:
*.db_unique_name='orclstd'*.db_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orclstd'*.log_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orclstd'- 去掉或者注释掉主库专属的
log_archive_dest_2配置,等 duplicate 完成后统一交给 Data Guard Broker 管理。 - 确认
*.control_files指向备库上可用的目录,比如/u01/app/oracle/oradata/orclstd/control01.ctl。
如果你完全不想手动改 pfile,也可以用 SPFILE 方式,让 RMAN 在 duplicate 时自动处理。但我在 AI 26ai 上测试,手动准备 pfile 更容易控制路径和参数,尤其是当你需要把主备库路径做得不一样的时候,提前改好 pfile 能省掉后续一堆 convert 麻烦。
生成 pfile 后,要把这份 pfile 放到备库机器上,目录随意,比如放在 $ORACLE_HOME/dbs/init${ORACLE_SID}.ora。注意文件名要和备库 SID 对应,比如备库 SID 是 orclstd,文件名就应该是 initorclstd.ora。
3.3 确认口令文件一致
Data Guard 主备库之间的 redo 传输和日志应用都需要通过 Oracle Net 连接,认证依赖 sys 用户的口令文件。如果主备库 sys 用户口令不一样,后面可能遇到 ORA-01031: insufficient privileges 或者 ORA-16191。
最简单的办法是先把主库的密码文件拷贝到备库,或者在备库上重建一个相同口令的密码文件。我通常的做法是直接复制:
bash复制scp $ORACLE_HOME/dbs/orapworcl oracle@standby_host:$ORACLE_HOME/dbs/orapworclstd
注意备库密码文件的名字要和备库 SID 对应,比如备库 SID 是 orclstd,密码文件就叫 orapworclstd。如果名字不对,实例启动时不会自动加载密码文件,远程 sysdba 登录就会失败。
如果你不确定主库密码文件位置,可以查:
sql复制SELECT value FROM v$parameter WHERE name = 'password_file';
如果显示为空,说明没有启用密码文件。你需要先创建:
bash复制orapwd file=$ORACLE_HOME/dbs/orapworclstd password=YourStrongPassword force=y
再用这个口令去主库同步 sys 用户口令。
3.4 临时表空间和 undo 表空间检查
Active Duplicate 会从主库复制临时表空间和 undo 表空间文件吗?实际上是会的。RMAN 会重建临时表空间文件,但不会复制其内容,因为临时表空间本来就是临时数据。所以你不必担心临时文件过大导致复制时间很长。
不过在 26ai 里,临时表空间的自动扩展能力比较强,如果你有多个临时表空间,建议确认主库至少有默认临时表空间存在。如果主库默认临时表空间是 TEMP,备库 duplicate 后也会自动创建 TEMP。
undo 表空间在主备库之间是一对一复制的,如果主库 undo 表空间名是 UNDOTBS1,备库也会存在同名文件。不用提前在备库创建 undo 表空间,RMAN 会处理好。
4. 备库端前置准备:目录、监听、参数文件
备库在正式执行 duplicate 前,需要保证实例能被远程启动到 nomount。这部分的准备程度,决定了你执行 RMAN 命令时是顺利跑完还是立刻报错。
4.1 创建备库目录结构
我建议至少创建以下目录(按你的实际路径调整):
bash复制mkdir -p /u01/app/oracle/oradata/orclstd
mkdir -p /u01/app/oracle/fast_recovery_area
mkdir -p /u01/app/oracle/admin/orclstd/adump
mkdir -p /u01/app/oracle/admin/orclstd/dpdump
mkdir -p /u01/app/oracle/admin/orclstd/pfile
其中 adump 是审计文件目录,如果参数 audit_file_dest 指向这里但目录不存在,实例启动可能直接报 ORA-09925。在 26ai 上默认审计是启用数据库审计的,所以这个目录很重要。
4.2 配置监听与 tnsnames
备库的 listener.ora 用静态监听方式配置好,确保远程可以连接到一个未启动的实例。以 SID orclstd 为例:
code复制SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orclstd)
(ORACLE_HOME = /u01/app/oracle/product/26.0.0/dbhome_1)
(SID_NAME = orclstd)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = standby_host)(PORT = 1521))
)
)
配置完后:
bash复制lsnrctl stop
lsnrctl start
lsnrctl status
lsnrctl status 的输出里如果能看到 orclstd 这个静态服务,就说明外部连接可以进来了。这一步非常关键,很多人 duplicate 时报 ORA-12514 就是因为静态监听没配好。
4.3 放置 pfile 和密码文件
把第 3.2 节生成好的 pfile 放到备库 $ORACLE_HOME/dbs 目录下,命名为 init${ORACLE_SID}.ora,其中 ${ORACLE_SID} 是备库 SID,比如 orclstd。
把第 3.3 节复制好的密码文件放到 $ORACLE_HOME/dbs/orapworclstd。确保文件属主是 oracle:
bash复制chown oracle:oinstall /u01/app/oracle/product/26.0.0/dbhome_1/dbs/orapworclstd
4.4 备库环境变量
在备库上确认环境变量正确,尤其是 ORACLE_SID 要设为 orclstd:
bash复制export ORACLE_SID=orclstd
export ORACLE_HOME=/u01/app/oracle/product/26.0.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
如果你用 .bash_profile 管理,建议把这几行加进去。这一步看起来简单,但我在多次操作中发现,备库执行 sqlplus / as sysdba 时如果 ORACLE_SID 没设置,SQL*Plus 会默认去读 $ORACLE_HOME/dbs 下某个默认参数文件,结果就是连到一个不存在的实例或者启动不了正确的实例。
5. RMAN Active Duplicate 完整实操步骤
前置条件都齐了以后,就可以执行最重要的一步了。我会先给你一段完整的命令,然后把每一步的关键点拆开说明。
5.1 duplicate 命令全文
以下是在主库服务器上执行 RMAN 脚本的完整示例:
bash复制rman target sys/your_password@orcl auxiliary sys/your_password@orclstd
进入 RMAN 后执行:
sql复制RUN {
ALLOCATE CHANNEL c1 DEVICE TYPE disk;
ALLOCATE CHANNEL c2 DEVICE TYPE disk;
ALLOCATE AUXILIARY CHANNEL ac1 DEVICE TYPE disk;
ALLOCATE AUXILIARY CHANNEL ac2 DEVICE TYPE disk;
DUPLICATE TARGET DATABASE
FOR STANDBY
FROM ACTIVE DATABASE
DBNEWNAME 'orclstd'
SPFILE
SET db_unique_name='orclstd'
SET db_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orclstd'
SET log_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orclstd'
SET control_files='/u01/app/oracle/oradata/orclstd/control01.ctl','/u01/app/oracle/oradata/orclstd/control02.ctl'
SET db_recovery_file_dest='/u01/app/oracle/fast_recovery_area'
SET db_recovery_file_dest_size=100G
SET log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=orclstd'
SET log_archive_dest_2=''
NOFILENAMECHECK;
}
这个命令里有一些参数很容易写错,我逐个解释一下。
TARGET连接串指向主库,AUXILIARY连接串指向备库。两个连接用户都必须是sysdba。FOR STANDBY表示创建的是物理备库,主角是 Data Guard,不是普通 clone。FROM ACTIVE DATABASE是灵魂关键词,表示不经过备份集,直接从主库实时复制。DBNEWNAME用于给备库设置新的db_unique_name,注意不是db_name。db_name在 spfile 中保持不变。SPFILE子句里SET的参数会在 duplicate 过程中直接更新到备库的 spfile。如果这些参数在你的 pfile 或主库 spfile 里已经正确,也可以不写,但写上的好处是避免备库启动时用到主库的绝对路径。NOFILENAMECHECK是必要的,因为主备库路径不同时,RMAN 默认会检查新文件名是否和主库相同,如果不同会报ORA-19660之类的问题,所以直接写上。
执行后 RMAN 会大致做这些事情:
- 连接主库、备库。
- 通过备库实例启动到
nomount。 - 从主库复制 spfile 并应用
SPFILE子句中的设置。 - 从主库复制控制文件到备库。
- 复制数据文件(online datafile)。
- 创建备用日志文件、控制文件、临时文件。
- 将备库置于 mount 状态。
整个过程日志会刷很多行,看到最后出现类似:
code复制Finished Duplicate Db at ...
才算成功。
5.2 duplicate 过程日志如何解读
在 AI 26ai 上执行 Active Duplicate,日志里会出现一些比较新的输出,比如自动检测存储格式、增量副本的统计信息等。你不必全部看懂,但有几个关键阶段要注意:
RMAN-03090: Starting backup ...:表示开始复制数据文件。input datafile copy ...:正在复制某个数据文件。RMAN-03091: Finished backup ...:某个数据文件复制完成。starting media recovery:duplicate 最后阶段会自动做一次实例恢复,把备库推到与主库一致的时间点。Finished Duplicate Db:大功告成。
注意,如果在 starting media recovery 阶段报错,比如 ORA-00313: open failed for members of log group,通常是因为 log_file_name_convert 没有正确映射在线日志路径。这时候去备库的 v$logfile 查看路径,和实际目录对比一下,往往就是目录写错了或者没建。
5.3 duplicate 完成后备库马上要做的检查
在 RMAN 退出前,备库已经被 mount 了。你可以在备库上执行:
sql复制SELECT name, db_unique_name, database_role, open_mode, protection_mode
FROM v$database;
期望结果类似:
DB_UNIQUE_NAME是orclstdDATABASE_ROLE是PHYSICAL STANDBYOPEN_MODE是MOUNTED
如果 database_role 不是 PHYSICAL STANDBY,说明你创建成了普通 duplicate(没加 FOR STANDBY),这时 Data Guard 架构是不成立的,需要重新执行。
5.4 备库日志应用启动和验证
备库处于 mount 状态后,要手动开启日志应用:
sql复制ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
这条命令会把备库从 mount 状态切到“正在应用日志”的持续状态。在 AI 26ai 里,备库也可以处于只读状态同时应用日志(READ ONLY WITH APPLY),但如果你要参与 Data Guard Broker 管理,建议至少先完成一次完整的 RECOVER MANAGED STANDBY 让备库应用历史归档。
验证方式:
sql复制SELECT sequence#, first_time, next_time, applied, status
FROM v$archived_log
ORDER BY sequence# DESC FETCH FIRST 5 ROWS ONLY;
如果 applied 列显示 YES,说明日志已经被应用。
再查备库的同步状态:
sql复制SELECT name, value
FROM v$dataguard_stats
WHERE name IN ('transport lag', 'apply lag', 'estimated failover time');
正常情况 transport lag 和 apply lag 都应该是 0 或者很小的秒数。如果越来越大,说明日志传输或应用出了问题。
6. Data Guard 集成配置与日常运维要点
备库起来后,还远远没到可以撒手不管的程度。你需要把 Data Guard 纳入统一管理,我推荐直接用 Data Guard Broker,省心很多。
6.1 配置 Data Guard Broker
在 26ai 上,Data Guard Broker 的配置方式和老版本基本一致。先确认主备库都允许 broker:
sql复制ALTER SYSTEM SET dg_broker_start=TRUE;
主库和备库都要执行。
然后通过 dgmgrl 把主备库注册进去:
bash复制dgmgrl sys/your_password@orcl
在 dgmgrl 里执行:
code复制CREATE CONFIGURATION 'DG_CONFIG' AS
PRIMARY DATABASE IS 'orcl'
CONNECT IDENTIFIER IS 'orcl';
ADD DATABASE 'orclstd' AS CONNECT IDENTIFIER IS 'orclstd';
ENABLE CONFIGURATION;
SHOW CONFIGURATION;
配置成功后,你可以在 dgmgrl 里查看健康状态:
code复制SHOW DATABASE 'orcl';
SHOW DATABASE 'orclstd';
6.2 添加 Standby Redo Log
没有 Standby Redo Log(SRL)的备库也能工作,但 Data Guard 的同步性能和容错能力都会打折。建议在备库添加 SRL。SRL 的组数和大小参考主库在线日志,组数至少比主库在线日志组数多一组。
假设主库在线日志组是 4 组,每组 200M,那备库建议添加 5 组 SRL:
sql复制ALTER DATABASE ADD STANDBY LOGFILE GROUP 10 ('/u01/app/oracle/oradata/orclstd/srl10.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 11 ('/u01/app/oracle/oradata/orclstd/srl11.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 12 ('/u01/app/oracle/oradata/orclstd/srl12.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 13 ('/u01/app/oracle/oradata/orclstd/srl13.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 14 ('/u01/app/oracle/oradata/orclstd/srl14.log') SIZE 200M;
SRL 的作用是让主库的 redo 传输可以直接写到备库的 SRL,备库的 MRP 进程再从 SRL 应用。如果备库没有 SRL,主库的 redo 会先被接收为归档日志,再等待应用,延迟会明显变大,而且在 failover 时容易丢日志。
6.3 开启 Active Data Guard(实时查询)
AI 26ai 的 Active Data Guard 默认就包含只读打开能力(需要额外授权),你可以把备库从 mount 状态切到只读同时应用日志:
sql复制ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
ALTER DATABASE OPEN;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
这样备库就处于 READ ONLY WITH APPLY,报表查询可以直接打到备库上,分担主库压力。
6.4 归档删除策略和常见误区
备库配置完以后,很多人会在主库打开 RMAN 删除归档策略,比如:
bash复制CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY;
这样配置后,主库删除归档时会检查备库是否已经应用该归档,避免备库缺日志。但有一个前提:备库必须注册在主库的 Data Guard 环境中,且能被主库 v$archive_dest_status 查询到。如果你没有配置 log_archive_dest_2,主库根本不知道备库状态,这个策略不会生效。
所以,为了让归档删除策略真正起到保护作用,必须在主库配置好向备库传输日志的 log_archive_dest_n 参数,或者启用 Broker 后让 Broker 自动管理传输。我自己更推荐由 Broker 统一管理传输和延迟阈值,因为命令行手工配置 log_archive_dest_n 很容易遗漏 VALID_FOR 和 DB_UNIQUE_NAME。
6.5 切换演练不能省
备库建好之后,我强烈建议做一次 switchover 和 failover 演练。Data Guard 不只是“备库存在”,它的价值在于关键时刻能顶上。AI 26ai 的 broker 支持 switchover 一键切换:
code复制SWITCHOVER TO 'orclstd';
切换完成后,再切回来。整个过程能帮你发现隐藏的路径、权限、监听问题。
注意:切换演练一定要在业务窗口做,并且把应用连接串用 service name 而不是主机 IP。不然切换后应用一时半会儿找不到新主库,演练效果大打折扣。
7. 常见问题与排查技巧实录
这部分我把自己在 AI 26ai Active Duplicate 中实际遇到的报错和排查过程整理成速查表。
| 报错信息 | 常见原因 | 排查思路与解决办法 |
|---|---|---|
ORA-12514: TNS:listener does not currently know of service requested |
备库实例没有 mount,service 未动态注册 | 在备库 listener.ora 配置静态监听,lsnrctl reload 后确认 lsnrctl status 能看到服务。 |
ORA-01031: insufficient privileges |
口令文件缺失或 sys 口令不一致 | 保证主备库密码文件名与 SID 对应,口令一致;必要时用 orapwd 重建。 |
ORA-16191: Primary log shipping client not logged on standby |
Data Guard 认证失败,口令不一致 | 重建备库密码文件后再试。 |
ORA-00313: open failed for members of log group |
在线日志路径映射错误 | 检查 log_file_name_convert 设置,确认备库目录存在。 |
ORA-19505: failed to identify file |
备库数据文件目录不存在 | 提前创建所有数据文件路径,确保 OS 用户有写权限。 |
| duplicate 完成后备库无法只读打开 | 缺少 Standby Redo Log 或日志应用未追上 | 确认 SRL 已建,等待 apply lag 归零后再尝试打开。 |
transport lag 持续增长 |
网络带宽不足、备库磁盘慢、SRL 不足 | 检查备库 v$archive_dest_status,确认 redo 传输模式;扩容 SRL 或检查网络。 |
7.1 执行 duplicate 时报错 RMAN-04006
这个是新手非常容易碰到的:RMAN-04006: error from auxiliary database: ORA-12514。
我当时第一反应是 tnsnames 写错,但实际上是由于备库监听静态配置没生效。解决方式就是回到第 4.2 节,确认 listener.ora 静态注册的 SID_NAME 和备库实例 SID 一致,并重载监听。
7.2 ORA-16009: remote archive log destination ... 的应对
这是日志传输目标配置错误。多半是 LOG_ARCHIVE_DEST_n 里的 SERVICE 写成了主库自己的服务名,或者 DB_UNIQUE_NAME 写错。在 broker 接管前,我建议先清掉所有手动的 LOG_ARCHIVE_DEST_n,交给 broker 统一管理。如果还想手动管理,必须确保:
sql复制ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=orclstd LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orclstd' SCOPE=BOTH;
注意 VALID_FOR 的两组参数分别代表日志类型和数据库角色,不能写反。在 AI 26ai 里写反虽然不一定立刻报错,但切换角色后可能出现日志不归档或者归档目录缺失的问题。
7.3 备库 OPEN_MODE 是 MOUNTED,日志应用一直 WAITING
我遇到过备库处于 mount 状态,MRP 进程显示 WAITING FOR LOG,但主库明明有日志没有传过去。后来发现是备库的 log_archive_dest_1 没有设置 FRA 的时候,归档日志没有地方落。主库把 redo 推过来,备库要先注册成归档日志,如果归档目标不可用,就会一直等待。
解决办法是给备库设置好归档位置:
sql复制ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST' SCOPE=BOTH;
并且确认 FRA 路径存在、空间够。在 broker 管理的环境里,这个参数也可以直接让 broker 管理,不必手动设置。
7.4 备份的时候不删除归档,这个习惯其实很重要
标题相关的热搜里有一条是“备份的时候不删除归档”,虽然和 Data Guard 搭建不是直接关系,但确实和数据保护相关。我在实际维护中见过太多因为 “备份脚本删归档太激进” 导致备库缺日志的案例。
在 Data Guard 环境下,主库的归档删除策略应该是:只有确认备库已经应用完,才允许删除。即使你用 RMAN 备份,也要遵守这个规则。更安全的做法是:保留至少最近两天的归档,而不是备份完立即删。这样可以给备库留足追赶窗口,也给排查问题留了余地。
8. 后续扩展:从“能跑”到“跑得稳”
备库能正常同步之后,我建议再做几件事,让你这套 Data Guard 从“能跑”变成“跑得稳”。
第一,配置 Data Guard 的延迟告警阈值。使用 Broker 的话,可以设置 ApplyLagThreshold 和 TransportLagThreshold,比如超过 30 秒就报警。这样主备库出现延迟时你能第一时间知道,而不是等到真正切换才发现日志差了好几个 G。
code复制EDIT DATABASE 'orclstd' SET PROPERTY 'ApplyLagThreshold'=30;
EDIT DATABASE 'orclstd' SET PROPERTY 'TransportLagThreshold'=30;
第二,部署只读备库的监控脚本。在 AI 26ai 上你可以用 SQL 定期查询 v$dataguard_stats,把延迟数值采集到监控系统。如果日志应用故障,也能通过 v$managed_standby 看到 MRP 进程状态。
第三,定期执行日志切换和归档清理演练。数据保护是“天天练,用时灵”的事。每月做一次日志切换,检查主备库归档目录是否平稳,SRL 是否够用,备库是否可以正常追上主库。特别是 AI 26ai 的自动归档清理策略,如果你没设置好,FRA 可能被填满,Data Guard 也会跟着出问题。
第四,理解 AI Database 26ai 的 Data Guard 新增能力。新版本对 AI 相关的数据文件、向量索引等对象的复制有一套内部处理机制,大多数情况下 RMAN 会自动识别。如果你在库里有大量向量索引,建议在你自己的测试环境先做一次演练,确认复制后的索引数据和主库一致,避免业务上线时才发现索引丢失或失效。
最后再分享一个小技巧
我在搭建过程中最后一步总是习惯做一次全链路验证,而不是只看 v$database 的角色。具体的做法是:在主库创建一个测试表并提交,然后等几秒,在备库上查询这张表是否可见(备库处于只读打开状态时)。如果可见,说明 redo 传输、日志应用都正常。这个技巧看着简单,但它能帮你把 Data Guard 的“最后一公里”走完,很多时候角色显示正常,但实际日志应用已经卡住了。
另外一个小提醒是:在 AI 26ai 上,如果你使用了 OCI 或者云存储,文件路径的映射会更复杂,别只看本地目录。云存储场景下,db_file_name_convert 的优先级和处理方式可能会不同,建议先在虚拟机或者本地磁盘的环境里把整套流程跑通,再上云环境,否则排查问题的成本会高很多。
我个人的体会是,RMAN Active Duplicate 这套流程,只要把前置检查做到位,实际执行时间非常可控,基本就是数据文件复制的时间加一点日志应用的时间。真正耗时间的往往是前面那些不起眼的配置,比如监听、口令文件、目录权限。希望这篇实操记录能让你少踩几个坑,顺利把 26ai 的备库搭起来。
