并行应用不等于自动加速,实际并发受事务依赖、日志挖掘线程和目标库资源限制;Oracle 会串行化有依赖的事务,即使设 MAX_SERVERS=8,活跃 applier 仍可能仅1–2个。
为什么 DBMS_LOGSTDBY.APPLY_SET 设为并行后没提速?
并行应用不等于自动加速,底层依赖日志挖掘线程、事务依赖关系和目标库资源。oracle 会主动串行化有依赖的事务(比如同一主键的连续 update),哪怕开了 8 个 apply 进程,实际可能只有 1–2 个在干活。
-
DBMS_LOGSTDBY.APPLY_SET('MAX_SERVERS', '8')只是上限,真实并发数由V$LOGSTDBY_PROCESS中TYPE = 'APPLIER'的活跃数体现 - 检查是否存在“apply lag spike + applier idle”现象:用
SELECT * FROM V$LOGSTDBY_PROGRESS看APPLIED_SCN和NEWEST_SCN差值是否持续扩大,同时查V$LOGSTDBY_PROCESS确认是否有大量STATUS = 'IDLE' - 常见干扰源:备库上运行了
DBMS_STATS或大查询占满 I/O;归档日志路径在 NFS 上导致读取延迟;LOG_ARCHIVE_DEST_n配置了SYNC但主库未启用COMMIT_WAIT
LOGSTDBY_SKIP 跳过 DDL 后为什么 Apply 还卡住?
跳过 DDL 不代表跳过它引发的后续 DML 依赖。比如跳过了 ALTER TABLE t ADD COLUMN c2,但后续日志里所有对 t(c2) 的 UPDATE 仍会被 apply 进程阻塞——因为目标表结构不匹配,Oracle 无法解析该语句。
- 必须同步跳过「DDL + 后续所有相关 DML」:先执行
DBMS_LOGSTDBY.SKIP('DML', 'SCOTT', 'EMP'),再确认DBA_LOGSTDBY_SKIP视图中STATEMENT_OPT为'DML'且OBJECT_NAME匹配 - 更安全的做法是跳过整个 schema:
DBMS_LOGSTDBY.SKIP('SCHEMA_DDL', 'SCOTT', '%'),但需确保备库 schema 结构已手动对齐 - 跳过后务必重启 apply:
EXEC DBMS_LOGSTDBY.STOP_APPLY;→EXEC DBMS_LOGSTDBY.START_APPLY;,否则跳过规则不生效
DBMS_LOGSTDBY.INSTANTIATE_TABLE 大表初始化太慢怎么破?
该过程默认走 SQL*Loader 直接路径插入,但若备库 SGA_TARGET 小于 2G 或 _smm_max_size 设置过低,会导致频繁写临时段,反而比常规 INSERT 还慢。
- 执行前调大内存参数:
ALTER SYSTEM SET "_smm_max_size"=204800 SCOPE=BOTH(单位 KB),避免排序/哈希溢出到磁盘 - 禁用并行度干扰:
EXEC DBMS_LOGSTDBY.INSTANTIATE_TABLE('SCOTT','EMP', parallel_level => 1),高并行在单块 SSD 上常因锁争用变负优化 - 避开高峰时段,检查
V$SESSION_LONGOPS中OPNAME LIKE '%INSTANT%'的TIME_REMAINING,若 >3600 秒,优先考虑 expdp/impdp 替代
Apply 进程 CPU 占用高但吞吐低,是不是该调 LOGSTDBY_MAX_EVENTS?
这个参数控制每个 apply 批次处理的 LCR(逻辑更改记录)数量,设得过大容易触发 PGA 溢出和 latch 争用,设得太小则上下文切换开销压垮 CPU——不是越大越好,也不是越小越稳。
- 默认值 1000 适合 OLTP 场景;若主库批量 INSERT 高频(如每秒 5k+ 行),可试
DBMS_LOGSTDBY.APPLY_SET('MAX_EVENTS', '5000') - 观察
V$LOGSTDBY_STATS中name = 'events applied'和'apply time (sec)'的比值:若每秒事件数 - 绝对不要设为 0 或 NULL,Oracle 会退化为单事件处理,CPU 利用率飙升但吞吐归零
真正卡点往往不在参数本身,而在主备间时钟漂移超过 3 秒,或备库 undo 表空间自动扩展被禁用导致事务回滚失败——这些不会报错,但会让 apply 进程陷入“假活跃”状态。











