DRM冻结阶段必然导致卡顿,因其五阶段模型中freeze会全局阻塞gc current/cr request,LMS挂起不可响应,数万pkey迁移时冻结持续2–5秒,引发链式阻塞及下游checkpoint incomplete等连锁等待。
drm 不是“可选优化项”,而是高风险的自动重主机制;在生产 rac 中开启它,等于给集群装了一个不带熔断器的定时炸弹——冻结阶段不可中断、网络带宽被吃满、gc current request 瞬间堆积,卡顿不是偶发,而是必然。
DRM 冻结阶段为什么必然导致卡顿
DRM 的五阶段执行(静默 → 冻结 → 清除 → 重建 → 解冻)中,freeze 阶段会全局阻塞所有新发起的 gc current request 和 gc cr request。这不是“慢”,而是硬挂起:
- LMS 进程进入
gcs drm freeze in enter server mode等待,无法响应任何新块请求 - 若一次 DRM 涉及数万 pkey(比如一张高频插入的流水表),冻结可能持续 2–5 秒
- 这期间所有等待这些 block 的会话全部堆在
gc current request上,形成链式阻塞 - 下游连锁反应:redo 写不下去 → checkpoint incomplete → DBWn 刷脏卡住 → buffer busy waits 爆增
_gc_affinity_time=0 是唯一真正禁用 DRM 的方式
别信“调高阈值就能控制 DRM”——_gc_affinity_limit 和 _gc_affinity_minimum 只是提高触发门槛,但只要非零,LMD0 就会定期扫描、排队、触发冻结。真正止血必须设为 0:
-
ALTER SYSTEM SET "_gc_affinity_time"=0 SCOPE=SPFILE;(所有实例统一执行) - 不要只改一个节点,否则残留 affinity 统计会导致 GRD 不一致,引发
ORA-01105或ORA-01606 -
_gc_undo_affinity=FALSE必须同步设置,否则 undo 段仍可能触发 DRM - 该参数生效需重启实例,且不能在线动态关闭已启动的 DRM 流程
DRM 相关视图和 trace 文件怎么验证是否真被抑制
光看参数值没用,得看运行态证据:
- 查 LMD trace:
$ORACLE_HOME/rdbms/log/lmd*.trc,搜索"DRM start"或"remastering",禁用后应完全消失 - 查
x$object_affinity_statistics:若_gc_affinity_time=0生效,OPENS列将长期为 0 或不再增长 - AWR 中
gc current split、gc buffer busy等事件突降,且gcs drm freeze in enter server mode等待归零 - 注意:
DRMDIAG.SQL脚本输出中的drmfree时间戳若不再出现,才是真实抑制
DRM 的设计初衷是“自适应”,但它的冻结模型与 OLTP 场景天然冲突——业务请求不会等你完成五阶段;真正可控的负载均衡靠应用分片、服务名绑定、read-only 实例分流,而不是把命运交给 LMD0 的统计阈值。


















