SQL Apply 启动失败主因是备库控制文件残留主库“只读”标记或角色未正确设为PHYSICAL STANDBY;需确保V$DATABASE中DATABASE_ROLE=PHYSICAL STANDBY且OPEN_MODE=MOUNTED,并清理V$DATAGUARD_CONFIG中重复DB_UNIQUE_NAME。
SQL Apply 启动失败报 ORA-16000 或 ORA-16025
这是最常见的拦路虎:备库启动 sql apply 时直接报错,根本走不到日志应用阶段。本质不是权限或网络问题,而是备库控制文件里残留了主库的“只读”标记,或者数据库角色没真正切到 physical standby 状态。
实操建议:
- 确认当前状态:
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;—— 必须是PHYSICAL STANDBY+MOUNTED,READ ONLY或READ WRITE都不行 - 如果误开了
ALTER DATABASE OPEN READ ONLY,得先关库再重启到MOUNT,不能靠SHUTDOWN IMMEDIATE+STARTUP MOUNT蒙混过关(某些版本会卡在OPEN MODE = MOUNTED但角色仍是PRIMARY) - 检查
V$DATAGUARD_CONFIG是否有重复或残缺的 DB_UNIQUE_NAME,尤其当用 RMAN duplicate 搭建后未清理旧配置时,ORA-16025往往就出在这儿
遇到 NUMBER(*,n)、XMLType、JSON 字段时 SQL Apply 自动跳过
SQL Apply 不是万能重放器,它依赖逻辑备库的“语义解析”能力,对部分数据类型做硬性限制。一旦碰到不支持的类型,日志应用不会报错中断,而是静默跳过整条 DML —— 表面看着正常,实际数据已不一致。
关键判断点:
-
NUMBER类型只要指定了精度(如NUMBER(10,2))就没问题;但NUMBER(*)(即NUMBER无括号)会被拒绝,因为其内部存储长度动态变化,逻辑备库无法预分配空间 -
XMLType在 12.1+ 默认禁用,需显式设置ENABLE PLUGGABLE DATABASE并启用XML DB组件,否则SQL Apply直接忽略含该字段的事务 -
JSON列(12.2+)必须底层是VARCHAR2或CLOB存储,若建表时用了JSON关键字但未指定STORAGE IN ROW,备库解析失败后同样跳过
如何快速识别哪些表/列会触发 SQL Apply 兼容性告警
别等上线后查 V$LOGSTDBY_EVENTS——那已经是事后补救。搭建期就得主动扫描,重点不是看“支持列表”,而是抓“实际被用到的类型”。
执行这三步:
- 查主库所有用户表中含高风险列的语句:
SELECT OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM DBA_TAB_COLUMNS WHERE DATA_TYPE IN ('XMLTYPE','JSON','BFILE','ANYDATA','ANYTYPE') OR (DATA_TYPE = 'NUMBER' AND DATA_PRECISION IS NULL); - 检查是否启用了
LOGGING和FORCE LOGGING:不满足这两条,哪怕类型全兼容,SQL Apply也收不到完整变更日志 - 用
DBMS_LOGSTDBY.BUILD前先跑一次EXECUTE DBMS_LOGSTDBY.SKIP_TRANSACTION('SCHEMA', 'TABLE_NAME');测试跳过逻辑是否生效,避免后期因某张表阻塞全局同步
使用 DBMS_LOGSTDBY.SKIP 的副作用比想象中大
跳过某个 schema 或 table 看似简单,但会引发两个隐蔽问题:一是后续新建的同名对象不会自动继承 skip 规则(比如你 skip 了 HR.EMPLOYEES,后来又建了 HR.EMPLOYEES_BAK,它仍会被尝试应用);二是 skip 规则本身会写入备库控制文件,重启后不消失,但也不会出现在 DBA_LOGSTDBY_SKIP 视图里,除非你用 DBMS_LOGSTDBY.UNSKIP 显式清除。
更麻烦的是性能影响:
- 每加一条
SKIP规则,SQL Apply进程就要多做一次正则匹配,100 条规则可能让 apply 速度下降 15%~20% - 如果 skip 的是高频更新的大表(比如订单流水),备库的
LOGSTDBY$EVENTS里会出现大量skipped transaction记录,掩盖真正的问题日志 - 最易被忽略的一点:skip 规则对 DDL 无效 —— 即使你 skip 了整个 schema,
DROP TABLE或ALTER TABLE ADD COLUMN依然会执行,可能导致备库结构和主库错位
逻辑备库的数据一致性,从来不在“能不能跑起来”,而在于“哪些地方悄悄没跑”。类型兼容性评估不是一次性 checklist,而是要嵌进每次 DDL 变更的发布流程里。










