物理备库转逻辑备库需严格按序操作:先停mrp、主库建logminer字典并启补充日志;再查清不支持对象及缺失主键表并处理;执行alter database recover to logical standby(用v$database.name值);shutdown/startup mount后open resetlogs;最后必须显式启动sql apply,否则库仅可读不同步。

物理备库转逻辑备库不是“执行一条命令就完事”的操作,核心风险在于:没停 MRP 就构建 LogMiner 字典,会导致后续 SQL Apply 解析失败;没处理不支持对象或缺失主键,SQL Apply 会静默跳过表甚至卡住;RESETLOGS 后忘记启动 APPLY,逻辑备库就只是个普通只读库。
必须先停 MRP,再 build LogMiner 字典
MRP(Managed Recovery Process)在物理备库上持续应用归档日志。如果它还在运行,主库执行 EXEC dbms_logstdby.build 生成的 LogMiner 字典可能被提前应用进备库——但此时备库仍是物理模式,无法识别字典内容,导致后续切换为逻辑备库后,SQL Apply 拿不到字典,解析 redo 失败,同步停滞。
- 在物理备库上先执行:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; - 确认 MRP 已退出:
SELECT PROCESS, STATUS FROM V$MANAGED_STANDBY WHERE PROCESS = 'MRP0';—— 应返回空或 STATUS 为NOT APPLYING - 再去主库执行:
EXEC dbms_logstdby.build; - 主库需确保已开启补充日志:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;(全库级主键/唯一约束日志是 SQL Apply 的基础)
检查并清理不支持的对象和行唯一性缺陷
逻辑备库的 SQL Apply 不是块级复制,它靠解析 SQL 重放变更。一旦遇到不支持的数据类型(如 XMLTYPE、BFILE)、内部 Schema(如 SYS.AUD$),或没有主键/唯一约束的表,它要么跳过,要么报错中断。这些不会在转换时立刻暴露,但会在后续同步中突然失效。
- 查不支持的用户表:
SELECT DISTINCT owner, table_name FROM dba_logstdby_unsupported ORDER BY owner, table_name; - 查不支持的原因(比如某列是
XMLTYPE):SELECT column_name, data_type FROM dba_logstdby_unsupported WHERE owner = 'SCOTT' AND table_name = 'EMP'; - 查缺失主键的表:
SELECT owner, table_name, bad_column FROM dba_logstdby_not_unique;—— 对结果中的每张表,必须加主键或唯一约束,否则 UPDATE/DELETE 无法定位行 - 跳过审计表等系统对象(可选但推荐):
EXEC dbms_logstdby.skip('DML', 'SYS', 'AUD$');和EXEC dbms_logstdby.skip('SCHEMA_DDL', 'SYS', 'AUD$');
ALTER DATABASE RECOVER TO LOGICAL STANDBY 必须用对数据库名
这条命令里的 db_name 不是实例名(ORACLE_SID),也不是 DB_UNIQUE_NAME,而是控制文件里记录的数据库名称(v$database.name)。输错会导致 ORA-16125 或 ORA-16134,转换失败且需从头恢复物理备库。
- 在物理备库上先确认:
SELECT name FROM v$database;—— 记下输出值,比如RHT - 执行转换命令时严格使用该值:
ALTER DATABASE RECOVER TO LOGICAL STANDBY RHT; - 注意:该命令会自动重建控制文件,所以之后必须用
RESETLOGS打开,不能用OPEN - 执行顺序不可乱:
SHUTDOWN IMMEDIATE→STARTUP MOUNT→ALTER DATABASE RECOVER TO LOGICAL STANDBY <name></name>→SHUTDOWN IMMEDIATE→STARTUP MOUNT→ALTER DATABASE OPEN RESETLOGS
OPEN RESETLOGS 后必须显式启动 SQL Apply
逻辑备库打开后默认不自动应用日志。它处于 READ WRITE 模式,但所有主库同步表仍是只读的,除非你主动启用 SQL Apply。不启动,它就只是个“能连上但不同步”的库。
- 启动实时应用:
ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; - 验证是否运行:
SELECT TYPE, STATUS, HIGH_SCN FROM V$LOGSTDBY;——TYPE = 'COORDINATOR'且STATUS = 'APPLYING'表示正常 - 若需调优并发性能(高吞吐场景):
EXEC DBMS_LOGSTDBY.APPLY_SET('APPLY_SERVERS', 12);,但别盲目设太高,需结合 CPU 和 I/O 负载观察 - 首次启动后建议立即查错误:
SELECT * FROM DBA_LOGSTDBY_EVENTS ORDER BY EVENT_TIME DESC FETCH FIRST 5 ROWS ONLY;—— 看是否有跳过的 DDL 或权限问题
整个过程最易被忽略的是两处隐性依赖:一是主库的 log_archive_dest_n 参数必须包含 SYNC 或 ASYNC + VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE),否则逻辑备库收不到新日志;二是逻辑备库自己的归档路径要独立于物理备库配置(比如多配一组 LOG_ARCHIVE_DEST_2 指向本地磁盘),否则归档进程可能因 SRL 和 ORL 归档竞争而挂起。











