Oracle中TX锁(行锁)监控,抓TX锁的源头

本文介绍了一种在Oracle数据库中排查SQL语句锁冲突的方法,通过运行特定的SQL脚本来捕捉导致行级锁定的会话信息,包括SID、SQL_ID及SQL文本,帮助DBA快速定位并解决因并发更新同一行数据引起的死锁问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

各位DBA,看到这篇文章是不是很开心,解决了你一个大麻烦,赶紧把它部署到实时监控程序吧

(咳咳,转载,抄袭不注明文章出处的人可耻哈)

session 1: update emp_bak set ename='沙雕' where empno=7369;

session 2: update emp_bak set ename='大长腿' where empno=7369;

session 3: update emp_bak set ename='矮丑穷' where empno=7369;

运行下面脚本可以抓到哪个SID,哪个SQL_ID,跑的SQL_TEXT锁住了哪个SID,哪个SQL_ID,哪个SQL语句

需要注意的是:如果V$SQLAREA没有保存SQL,可能抓不到,其次,如果系统并发很高,你可能需要再修改下脚本

select sysdate,
       source_sid,
       source_sql_id,
       source_sql_text,
       blocking_sid,
       blocking_sql_id,
       blocking_sql_text
  from (select b.sid source_sid,
               d.sql_id source_sql_id,
               d.sql_text source_sql_text,
               a.sid blocking_sid,
               a.sql_id blocking_sql_id,
               e.sql_text blocking_sql_text,
               (select object_name
                  from dba_objects
                 where object_id = a.row_wait_obj#) object_name
          from v$session     a,
               v$session     b,
               v$transaction c,
               v$sqlarea     d,
               v$sqlarea     e
         where a.event = 'enq: TX - row lock contention'
           and a.blocking_session = b.sid
           and b.taddr = c.addr
           and to_date(c.start_time, 'mm/dd/yy hh24:mi:ss') =
               d.last_active_time
           ---and d.command_type in (2, 3, 6)
           and b.user# = d.parsing_schema_id
           and a.sql_id = e.sql_id)
 where instr(upper(source_sql_text), object_name) > 0;

脚本运行示例:

SQL> select sysdate,
  2         source_sid,
  3         source_sql_id,
  4         source_sql_text,
  5         blocking_sid,
  6         blocking_sql_id,
  7         blocking_sql_text
  8    from (select b.sid source_sid,
  9                 d.sql_id source_sql_id,
 10                 d.sql_text source_sql_text,
 11                 a.sid blocking_sid,
 12                 a.sql_id blocking_sql_id,
 13                 e.sql_text blocking_sql_text,
 14                 (select object_name
 15                    from dba_objects
 16                   where object_id = a.row_wait_obj#) object_name
 17            from v$session     a,
 18                 v$session     b,
 19                 v$transaction c,
 20                 v$sqlarea     d,
 21                 v$sqlarea     e
 22           where a.event = 'enq: TX - row lock contention'
 23             and a.blocking_session = b.sid
 24             and b.taddr = c.addr
 25             and to_date(c.start_time, 'mm/dd/yy hh24:mi:ss') =
 26                 d.last_active_time
 27             ---and d.command_type in (2, 3, 6)
 28             and b.user# = d.parsing_schema_id
 29             and a.sql_id = e.sql_id)
 30   where instr(upper(source_sql_text), object_name) > 0;
 
SYSDATE     SOURCE_SID SOURCE_SQL_ID SOURCE_SQL_TEXT                                  BLOCKING_SID BLOCKING_SQL_ID BLOCKING_SQL_TEXT
----------- ---------- ------------- ------------------------------------------------ ------------ --------------- ------------------------------------------------
2020/5/19 1        192 201c4xcdsjaj0  update emp_bak set ename='沙雕' where empno=7369            4 2hpm4yjuut7cg    update emp_bak set ename='矮丑穷' where empno=7369
 
2020/5/19 1        192 201c4xcdsjaj0  update emp_bak set ename='沙雕' where empno=7369          221 36xb1pyv12k56    update emp_bak set ename='大长腿' where empno=7369
 

 

<think>嗯,用户这次的问题是关于Oracle数据库活跃会话数过高的排查和优化。这个问题在数据库运维中很常见,但需要系统性地分析。用户可能是个DBA或者系统管理员,正在面临生产环境性能压力。 从引用内容看,用户已经掌握基础查询语句(如v$session、v$process),但需要更深入的排查方法。用户真正的需求应该是快速定位瓶颈并解决,避免业务受影响。考虑到活跃会话数高通常伴随系统卡顿,用户此刻可能比较着急。 需要从五个维度展开:查询定义、实时监控、定位阻塞、分析SQL、优化建议。特别要注意: 1 活跃会话的定义要明确(status=ACTIVE且type=USER) 2 AWR报告分析是关键,但用户可能不熟悉操作步骤,要给出具体命令 3 冲突是常见诱因,要教用户查enqueue和blocking_session 4 SQL优化部分需要给出可立即执的排查语句(如查top SQL) 对于优化建议,不能只给理论,要结合Oracle特性。比如: - 调整连接池参数要说明具体参数名(如WEBLOGIC的maxCapacity) - 索引优化要强调避免全表扫描 - 归档日志处理需提醒空间不足风险 最后生成的三个问题都很有针对性:监控、AWR报告解读、连接池配置,这些都是用户后续可能遇到的衍生问题。特别是中间件配置那块,很多DBA容易忽略应用层的影响。 (检查LaTeX格式)所有数学符号如$>80%$都正确使用了内公式格式,没有独立公式需求。引用标记[^1][^2]也按要求添加在句末。</think>以下是Oracle数据库活跃会话数过高的排查与优化方案,按操作流程逐步说明: --- ### **1. 确认活跃会话状态** ```sql -- 查看当前活跃会话数 SELECT COUNT(*) FROM v$session WHERE status = 'ACTIVE' AND type = 'USER'; -- 详细活跃会话信息(关键) SELECT sid, serial#, username, program, machine, sql_id, event, blocking_session FROM v$session WHERE status = 'ACTIVE' AND type = 'USER'; ``` **分析重点**: - `sql_id`:定位高负载SQL - `event`:等待事件(如`db file sequential read`表示I/O瓶颈) - `blocking_session`:识别阻塞源头 --- ### **2. 定位性能瓶颈** #### **(1) 等待事件分析** ```sql SELECT event, COUNT(*) AS sessions FROM v$session WHERE status = 'ACTIVE' GROUP BY event ORDER BY sessions DESC; ``` **常见事件与解决方案**: - **`enq: TX - row lock contention`**:冲突 → 优化事务提交频率 - **`db file scattered read`**:全表扫描 → 检查缺失索引 - **`log file sync`**:日志写入延迟 → 优化redo日志配置 #### **(2) 阻塞会话溯** ```sql -- 查找阻塞链源头 SELECT s1.sid AS blocked_sid, s2.sid AS blocking_sid, s2.sql_id AS blocking_sql, s2.program AS blocking_program FROM v$session s1 JOIN v$session s2 ON s1.blocking_session = s2.sid WHERE s1.blocking_session IS NOT NULL; ``` --- ### **3. 分析高负载SQL** ```sql -- 根据sql_id获取SQL文本 SELECT sql_text FROM v$sql WHERE sql_id = '&sql_id'; -- 检查执计划 EXPLAIN PLAN FOR SELECT * FROM ...; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); ``` **优化方向**: - 缺失索引 → 为高频条件列创建索引 - 全表扫描 → 优化查询条件或使用分区表 - 低效JOIN → 改写SQL或调整统计信息 --- ### **4. 系统级资检查** ```sql -- CPU/Memory压力 SELECT * FROM v$sysmetric WHERE metric_name IN ('CPU Usage Per Sec','Memory Usage'); -- I/O负载 SELECT file_id, phyrds, phywrts FROM v$filestat; ``` **判断阈值**: - CPU利用率$>80\%$持续5分钟 → 需扩容或优化 - 物理读/写量激增 → 检查慢SQL或存储性能 --- ### **5. 优化措施** #### **紧急处理** ```sql -- 终止阻塞会话(谨慎使用) ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; ``` #### **长期优化** 1. **SQL调优** - 对高频SQL执`SQL Tuning Advisor` ```sql DECLARE task_name VARCHAR2(30); BEGIN task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_id => '&sql_id'); DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name); END; ``` 2. **参数调整** ```sql -- 增大SGA/PGA(需重启) ALTER SYSTEM SET sga_target=8G SCOPE=spfile; ALTER SYSTEM SET pga_aggregate_target=2G SCOPE=spfile; ``` 3. **架构优化** - 读写分离 → 使用Active Data Guard - 连接池控制 → 限制中间件最大连接数 - 分区表 → 对亿级数据表按时间分区 --- ### **6. 预防性监控** ```sql -- 创建活跃会话阈值告警 BEGIN DBMS_SERVER_ALERT.SET_THRESHOLD( metrics_id => DBMS_SERVER_ALERT.ACTIVE_SESSIONS, warning_operator => DBMS_SERVER_ALERT.OPERATOR_GE, warning_value => '100', critical_operator => DBMS_SERVER_ALERT.OPERATOR_GE, critical_value => '200', observation_period => 1, consecutive_occurrences => 3 ); END; ``` > **关键建议**:定期生成AWR报告分析性能趋势 > ```sql > -- 生成最近1小时AWR报告 > @?/rdbms/admin/awrrpt.sql > ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值