必须先创建物理备库,再执行alter database recover to logical standby;否则会因缺少日志应用基础而报ora-16190等错误。关键步骤包括:主库执行dbms_logstdby.build构建logminer字典、配置双归档路径(online和standby日志分别归档)、备库停mrp、转换后以resetlogs打开并启动sql apply。
必须先有物理备库,否则alter database recover to logical standby会报错
逻辑备库不是从零创建的,它依赖物理备库作为起点。直接在空实例或主库备份上执行转换命令会失败,报错类似 ora-16190: invalid operation on standby database 或提示数据库未处于 mount 状态且无应用日志基础。
实操建议:
- 确保物理备库已成功搭建并处于
MANAGED STANDBY DATABASE CANCEL状态(即日志应用已停止) - 确认物理备库能正常接收主库归档(
V$ARCHIVED_LOG中有新归档记录,APPLIED='NO') - 不要跳过
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL—— 这是强制停掉 redo apply 的必要步骤,否则后续DBMS_LOGSTDBY.BUILD会因日志被占用而卡住或失败
DBMS_LOGSTDBY.BUILD 必须在主库执行,且要求归档日志完整
这个过程本质是让 LogMiner 在主库重做日志中提取数据字典变更(DDL),生成可被 SQL Apply 解析的元数据快照。如果主库归档不连续、被删除或 LOG_ARCHIVE_DEST_n 配置未启用,会报 ORA-16224: Database Guard is not enabled 或静默失败。
常见错误现象:
- 执行后无报错但逻辑备库启动时提示
ORA-16111: log mining and preparation of the logical standby database failed -
V$LOGSTDBY_STATE显示BUILDING DICTIONARY卡住超过 5 分钟
关键检查点:
- 主库必须开启强制日志:
ALTER DATABASE FORCE LOGGING - 确保
LOG_ARCHIVE_DEST_1的VALID_FOR包含(ONLINE_LOGFILES,ALL_ROLES),否则字典无法写入归档 - 执行前手动切一次日志:
ALTER SYSTEM SWITCH LOGFILE,保证最新字典变更已落盘
转换前要改主库归档路径,否则逻辑备库切换角色后无法归档
物理备库只归档从主库收到的 standby 日志;逻辑备库则不同——它自己也会产生在线日志(比如执行 SQL Apply 时写入的 DML 日志),这些日志也必须归档。若主库没提前配置好 VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) 的归档路径,将来 switchover 后新主库(原逻辑备库)将因无法归档自身 online log 而挂起。
必须调整的参数(在主库执行):
ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=/arch1 VALID_FOR=(ONLINE_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=chicago'ALTER SYSTEM SET LOG_ARCHIVE_DEST_3='LOCATION=/arch2 VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=chicago'ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_3=ENABLE
注意:LOG_ARCHIVE_DEST_3 的路径需在 OS 层真实存在且 Oracle 用户有写权限,否则后续逻辑备库 open 时会报 ORA-16038: log 1 sequence# 100 cannot be archived。
转换后立即查 DBA_LOGSTDBY_UNSUPPORTED 和 DBA_LOGSTDBY_NOT_UNIQUE
SQL Apply 不支持某些对象类型(如 XMLType、嵌套表、物化视图日志表)和缺少唯一标识的表。这些对象不会报错,但修改不会同步到逻辑备库,且无任何告警。
必须做的验证:
- 查不支持对象:
SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED—— 如果业务表出现在结果里,得重构(比如把XMLType改为CLOB) - 查无唯一标识表:
SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_NOT_UNIQUE WHERE BAD_COLUMN = 'Y'—— 对这类表必须加RELY DISABLE主键或唯一约束,并在对应列建索引,否则 update/delete 会全表扫描甚至数据错乱 - 确认跳过规则:
SELECT * FROM DBA_LOGSTDBY_SKIP WHERE STATEMENT_OPT IN ('DML', 'SCHEMA_DDL'),避免误跳业务 schema
最容易被忽略的是:即使逻辑备库 open 成功,只要有一张表在 DBA_LOGSTDBY_NOT_UNIQUE 里且没加 RELY 约束,它的 DML 就可能丢失或错位 —— 表面看同步正常,实际数据已不一致。











