Oracle统计信息收集时的锁持有阶段
1 准备阶段(共享模式锁)
锁类型:对象级共享锁(S锁)
持续时间:通常1-5秒
主要操作:
- 验证对象存在性和权限
- 检查统计信息首选项设置
- 确定采样方法和并行度
监控方法:
SELECT * FROM v$session_wait
WHERE sid = [收集会话SID]
AND wait_class != 'Idle';
2 数据采样阶段(行级锁)
锁类型:行级排他锁(TX锁)
特点:
- 仅在被采样的行上短暂持有
- 锁持续时间与采样方法相关:
- 全表扫描:几乎不持有行锁
- 随机采样:每采样行约1-10毫秒
规避策略:
BEGINDBMS_STATS.SET_TABLE_PREFS('SCHEMA', 'TABLE', 'METHOD_OPT', 'FOR ALL COLUMNS SIZE AUTO');
END;
3 统计计算阶段(无持久锁)
特点:
- 纯CPU计算过程
- 仅持有内存中的临时结构
- 可能短暂获取library cache latch
资源消耗:
-- 监控CPU使用
SELECT * FROM v$sysmetric
WHERE metric_name = 'CPU Usage Per Sec'
AND group_id = 2;
4 数据字典更新阶段(排他锁)
锁类型:数据字典排他锁(X锁)
关键操作:
- 更新SYS.TAB_STATS$等基表
- 修改USER_TAB_STATISTICS等视图数据
- 持续时间通常<100ms
优化建议:
-- 使用NO_INVALIDATE减少锁影响范围
BEGINDBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCHEMA',tabname => 'TABLE',no_invalidate => FALSE);
END;
5 游标失效阶段(库缓存锁)
锁类型:library cache lock/pin
行为特点:
- 使依赖该表统计信息的游标失效
- 可能引发硬解析风暴
- 持续时间与依赖游标数量成正比
监控方法:
SELECT * FROM v$librarycache
WHERE namespace = 'SQL AREA';
各版本差异对比
版本 | 锁优化改进 | 影响阶段 |
---|---|---|
11gR2 | 引入增量统计收集 | 减少数据字典更新锁时间 |
12c | 默认并发收集 | 缩短整体锁持有时间 |
19c | 持久化统计信息设置 | 减少重复收集锁争用 |
21c | 自动异步统计收集 | 完全避免业务时段锁争用 |