强烈安利8个AI论文平台,自考学生轻松搞定毕业论文!
2026/1/16 18:04:35
enq: CI - contention、enq: TX - allocate ITL entry)SYSDBA或SELECT ANY DICTIONARY权限(需查询v$动态视图)目标:快速找到“等待锁的会话”和“持有锁的会话”,明确阻塞关系。
SELECT -- 等待方信息 w.sid AS 等待会话ID, w.serial# AS 等待会话序列号, w.username AS 等待用户, w.program AS 等待进程, w.machine AS 等待机器, w.event AS 锁等待事件, -- 持有方信息 h.sid AS 持有会话ID, h.serial# AS 持有会话序列号, h.username AS 持有用户, -- 锁详情 l.type AS 锁类型, l.id1 AS 锁资源ID1, l.id2 AS 锁资源ID2, o.object_name AS 涉及对象名, o.object_type AS 对象类型 FROM v$session w JOIN v$lock l ON w.sid = l.sid LEFT JOIN v$session h ON l.block = 1 AND l.id1 = (SELECT id1 FROM v$lock WHERE sid = h.sid AND block = 1) LEFT JOIN dba_objects o ON l.id1 = o.object_id WHERE w.wait_class = 'Concurrency' -- 仅筛选并发类锁等待 AND w.status = 'ACTIVE' -- 排除非活跃会话 ORDER BY w.event, w.sid;持有会话ID不为空:存在明确的阻塞源,优先处理持有会话涉及对象名不为空:锁定对象为表/索引,需关联业务判断影响范围锁等待事件包含enq:前缀:属于Oracle内置锁,需对照“高风险锁速查表”处理目标:排查是否存在“多会话循环等待”(死锁)或“长链阻塞”(A等B、B等C)。
-- 1. 查看最近死锁信息(需数据库开启死锁跟踪) SELECT dt.username, dt.sid, dt.serial#, dt.object_name, dt.mode_held, dt.mode_requested, dt.lock_type, dt.deadlock_time FROM dba_deadlocks dt ORDER BY dt.deadlock_time DESC; -- 2. 查看完整锁等待链 WITH lock_chain AS ( SELECT l.sid AS waiter_sid, l.block AS holder_sid, l.type AS lock_type, l.id1, l.id2, 1 AS level FROM v$lock l WHERE l.request > 0 -- 等待锁的会话 UNION ALL SELECT l.sid AS waiter_sid, l.block AS holder_sid, l.type AS lock_type, l.id1, l.id2, lc.level + 1 AS level FROM v$lock l JOIN lock_chain lc ON l.sid = lc.holder_sid WHERE l.request > 0 ) SELECT lc.level AS 阻塞层级, lc.waiter_sid AS 等待方ID, s1.username AS 等待方用户, lc.holder_sid AS 持有方ID, s2.username AS 持有方用户, lc.lock_type, lc.id1, lc.id2 FROM lock_chain lc LEFT JOIN v$session s1 ON lc.waiter_sid = s1.sid LEFT JOIN v$session s2 ON lc.holder_sid = s2.sid ORDER BY lc.level DESC;阻塞层级超过3:属于长链阻塞,需从顶层持有会话开始处理dba_deadlocks有结果:存在死锁,需优先终止“非核心业务”的持有会话目标:根据锁类型和关联对象,判断是“参数配置问题”“SQL优化问题”还是“业务逻辑问题”。
| 锁类型/事件 | 常见根因 | 验证SQL |
|---|---|---|
enq: TX - allocate ITL | 表/索引的ITL(事务槽)不足 | SELECT ini_trans, max_trans FROM dba_tables WHERE table_name = 'XXX'; |
enq: TX - index contention | 索引频繁拆分(如自增主键索引) | SELECT index_name, leaf_blocks, distinct_keys FROM dba_indexes WHERE table_name = 'XXX'; |
enq: CI - contention | 数据库健康检查异常(如内存泄漏) | SELECT * FROM v$database_block_corruption;(检查数据块损坏) |
enq: DF - contention | RAC环境数据文件 ONLINE/OFFLINE 异常 | SELECT name, status FROM v$datafile;(检查数据文件状态) |
enq: WL - contention | REDO日志归档延迟或日志文件不足 | SELECT group#, status, bytes FROM v$log;(检查REDO日志状态) |
dba_tables/dba_indexes查ITL、分区、碎片化情况gv$session/gv$lock查跨节点阻塞(加INST_ID字段)v$log/v$archive_dest_status查归档是否正常目标:判断锁等待是否影响核心业务,决定处理优先级。
SELECT s.sid, s.serial#, s.username, s.program, s.module, -- 业务模块(如“订单系统”“支付接口”) s.action, -- 具体操作(如“下单”“退款”) s.sql_id, -- 执行的SQL ID s.last_call_et AS 等待时长(秒), l.event AS 锁等待事件 FROM v$session s JOIN v$lock l ON s.sid = l.sid WHERE s.wait_class = 'Concurrency' AND s.module IN ('核心订单模块', '支付接口') -- 替换为实际核心业务模块 ORDER BY s.last_call_et DESC;| 锁类别 | 锁事件(Event) | 核心特征 | 诊断SQL | 临时解决方案 | 长期优化建议 |
|---|---|---|---|---|---|
| 数据库健康类 | enq: CI - contention | 持续出现→系统健康异常 | SELECT * FROM v$instance;(查实例状态)SELECT * FROM v$sgastat WHERE name LIKE '%leak%';(查内存泄漏) | 1. 重启异常实例 2. 联系Oracle Support | 1. 定期巡检实例健康 2. 及时安装PSU补丁 |
| 事务管理类 | enq: TX - allocate ITL entry | 并发更新同一表→ITL不足 | ALTER TABLE 表名 INITRANS 10;(临时调整)SELECT ini_trans FROM dba_tables WHERE table_name = '表名'; | 1. 临时提升表/索引INITRANS 2. 终止长期持有会话 | 1. 按并发量设置INITRANS(建议10-20) 2. 表分区拆分 |
| RAC环境类 | enq: DF - contention | RAC节点间数据文件状态不一致 | SELECT inst_id, name, status FROM gv$datafile;(查多节点数据文件状态) | 1. 在异常节点执行ALTER DATABASE DATAFILE '路径' ONLINE;2. 重启节点 | 1. 规范数据文件操作流程 2. 避免跨节点频繁切换数据文件状态 |
| REDO相关类 | enq: WL - contention | REDO归档慢/日志组不足 | SELECT dest_name, status FROM v$archive_dest_status;(查归档状态)SELECT group#, status FROM v$log; | 1. 临时增加归档进程(ALTER SYSTEM SET log_archive_max_processes=8;)2. 切换REDO日志 | 1. 增大REDO日志文件(建议2-4G) 2. 优化归档存储IO |
| 分布式事务类 | enq: DX - contention | 分布式事务超时→锁未释放 | SELECT * FROM dba_2pc_pending;(查未完成分布式事务)SELECT * FROM v$distributed_lock; | 1. 手动清理 pending 事务(COMMIT FORCE '事务ID';)2. 终止异常分布式会话 | 1. 缩短分布式事务时长 2. 增加分布式锁超时( DISTRIBUTED_LOCK_TIMEOUT=300) |
-- 先验证会话操作(避免误杀) SELECT sql_text FROM v$sql WHERE sql_id = (SELECT sql_id FROM v$session WHERE sid = 持有会话ID); -- 终止会话(sid=持有会话ID,serial#=持有会话序列号) ALTER SYSTEM KILL SESSION '持有会话ID,持有会话序列号' IMMEDIATE;INITRANSdba_deadlocks定位后,优先终止非核心会话@$ORACLE_HOME/rdbms/admin/awrrpt.sql@$ORACLE_HOME/rdbms/admin/ashrpt.sqlKILL SESSION(可能导致事务回滚、数据不一致)INITRANS、重建索引(可能引发新锁等待)v$session.sql_id确认会话执行的SQL是否为“非关键操作”log_archive_max_processes)前,需记录当前值(便于回滚)| 视图名称 | 核心用途 | 关键字段 |
|---|---|---|
v$session | 查看会话状态与等待事件 | sid(会话ID)、event(等待事件)、username(用户)、sql_id(SQL ID) |
v$lock | 查看锁资源持有与等待情况 | sid(会话ID)、type(锁类型)、block(是否阻塞)、id1/id2(锁资源ID) |
dba_objects | 查看锁定对象(表/索引)信息 | object_id(对象ID)、object_name(对象名)、object_type(对象类型) |
dba_deadlocks | 查看历史死锁记录 | deadlock_time(死锁时间)、sid(会话ID)、object_name(涉及对象) |
gv$session | RAC环境查看多节点会话 | 比v$session多INST_ID(节点ID)字段 |