一次enq: CF - contention 导致数据库宕机的故障分析

本文分析了一次由于enq: CF - contention 导致的数据库宕机故障,指出Oracle在等待CF锁超时时会自动杀死持有该锁的进程,该行为由参数&_kill_controlfile_enqueue_blocker控制。故障发生前,redo log切换频繁,可能原因包括慢速I/O子系统、频繁的日志切换等。建议调整redo logfile大小和I/O性能,以避免类似问题。

数据库意外宕机,alert日志信息如下:


Sun Jul 27 01:02:48 2014
System State dumped to trace file /oracle/app/oracle/product/1020/admin/jcgl/bdump/jcgl2_diag_569650.trc
Sun Jul 27 01:03:48 2014
Killing enqueue blocker (pid=721256) on resource CF-00000000-00000000
 by killing session 3289.1
Killing enqueue blocker (pid=721256) on resource CF-00000000-00000000
 by terminating the process
LMD0: terminating instance due to error 2103
Sun Jul 27 01:03:48 2014
System state dump is made for local instance
Sun Jul 27 01:03:48 2014
Errors in file /oracle/app/oracle/product/1020/admin/jcgl/bdump/jcgl2_lms5_1048666.trc:
ORA-02103: PCC: inconsistent cursor cache (out-of-range cuc ref)
Sun Jul 27 01:03:48 2014
Trace dumping is performing id=[cdmp_20140727010348]
Sun Jul 27 01:03:49 2014
Shutting down instance (abort)
License high water mark = 1575
Sun Jul 27 01:03:57 2014
Termination issued to instance processes. Wa

### 原因分析 enq: TM - contention 是 Oracle 数据库中常见的等待事件之一,主要与表级锁(TM Lock)的争用有关。这种等待事件通常发生在对具有外键约束的表进行插入、更新或删除操作时,而未在外键列上建立索引的情况下[^4]。当没有合适的索引时,Oracle 会强制获取整个子表的 TM 锁,以确保数据一致性,这会导致并发操作受限并引发性能瓶颈。 此外,其他可能导致 enq: TM - contention 的情况包括显式使用 `LOCK TABLE` 命令锁定表资源,或者在高并发环境中多个会话同时尝试修改相关联的主外键表结构或数据的情况。 从 AWR 报告和 ASH 报告中可以观察到该等待事件的具体发生时间和受影响的对象。例如,在某一时段内,数据库出现严重的 enq: TM - contention 锁等待问题,结合 ASH 性能报告可定位到具体涉及的表(如 AA.BBIATE 表与 tran_jrnl 表),这两张表之间存在主外键关联关系[^2]。 ### 诊断方法 1. **AWR 和 ASH 报告**:通过生成 AWR 报告来识别系统中的性能瓶颈,并利用 ASH 报告进一步细化具体的等待事件及其影响对象。检查 ASH 报告中的 EVENT 列可以帮助找到 enq: TM - contention 相关信息,并根据 BLOCKING_SESSION 定位阻塞源会话[^3]。 2. **SQL 查询分析**:运行以下 SQL 查询以查看当前正在发生的 enq: TM - contention 等待事件及相关的阻塞会话: ```sql SELECT s.sid, s.serial#, s.event, s.wait_class, s.seconds_in_wait, s.blocking_session, s.sql_id, s.prev_sql_id, s.module, s.machine FROM v$session s WHERE s.event = 'enq: TM - contention'; ``` 此查询结果将提供有关被阻塞会话的信息以及可能的阻塞会话 ID。 3. **查找缺失索引**:检查所有涉及主外键关系的表,确认外键字段是否有适当的索引。可以通过以下 SQL 查询查找缺少索引的外键: ```sql SELECT a.table_name, a.constraint_name, b.column_name FROM user_constraints a JOIN user_cons_columns b ON a.constraint_name = b.constraint_name WHERE a.constraint_type = 'R' AND NOT EXISTS ( SELECT 1 FROM user_ind_columns c WHERE c.table_name = a.table_name AND c.column_name = b.column_name ); ``` ### 解决方案 1. **为外键添加索引**:最常见的解决办法是为每个外键字段创建索引,特别是在频繁执行 DML 操作的表上。这样可以避免全表级别的 TM 锁,从而减少锁竞争。例如: ```sql CREATE INDEX idx_child_table_fk ON child_table(fk_column); ``` 2. **优化事务处理**:尽量缩短事务持续时间,确保每次事务仅包含必要的操作,降低并发冲突的可能性。 3. **调整并发控制策略**:对于某些特定场景,考虑是否需要显式地使用 `LOCK TABLE`,如果确实需要,请评估其必要性和潜在的影响,并寻找替代方案。 4. **定期监控和维护**:定期审查数据库性能指标,特别是关注长期存在的锁等待事件。使用自动化的监控工具帮助快速发现和解决问题。 5. **深入排查阻塞源头**:一旦确定了阻塞会话,应立即调查该会话所执行的 SQL 语句,并采取相应措施(如终止不必要的长时间运行的事务)来缓解问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值