m6米乐安卓版下载-米乐app官网下载
暂无图片
7
暂无图片
暂无图片
暂无图片

一条大事务 导致的行锁问题研究 -m6米乐安卓版下载

574

本案例中的问题现象发生于当前主流的oracle 11g环境。不排除随着后续版本的升级可能会有一定细微的差异表现。但问题的原因及m6米乐安卓版下载的解决方案,在所有版本中都是通用的。
数据库版本:oracle 11g

应用人员反馈,当前数据库环境运行批处理作业效率异常。相同作业在dg库上均能较快完成。而当前为生产主库,主机性能远高于dg库。因此不应该出现跑批效率问题。据应用人员分析,怀疑为io问题。
为此。需要排查当前数据库环境以确定问题根本原因。

1.首先查看当前活动会话:

select sid,
       serial#,
       username,
       sql_id,
       program,
       audsid,
       to_char(sql_exec_start, 'yyyymmdd_hh24miss') sql_exec_start,
       event,
       final_blocking_instance block_inst,
       final_blocking_session block_sid
  from v$session
 where username is not null
   and status = 'active'
 order by logon_time;

image.png

当前会话中存在一条低效sql。且该sql导致了其他两个会话行锁。

对应的sql如下:

image.png

相应会话中:
3484为一条慢sql。走直接路径读。
两条更新语句,被3484会话阻塞。导致行锁。

2.分析阻塞事务情况:

select t1.sql_id,
       t1.user_name,
       t2.executions,
       t1.saddr,
       round(t2.buffer_gets / decode(t2.executions, 0, -1, t2.executions),
             2) pcb,
       t2.buffer_gets,
       t2.elapsed_time / power(10, 6),
       round(t2.elapsed_time / decode(t2.executions, 0, -1, t2.executions)/power(10, 6),2) pct,
       substr(t2.sql_text,1,40) sql_text
       --t2.*,
       --t1.*
  from v$open_cursor t1, v$sql t2
 where t1.sql_id = t2.sql_id
   and t1.sid = '&sid'
   and t1.user_name=upper('&uname')
 order by t2.elapsed_time / decode(t2.executions, 0, -1, t2.executions) desc;

image.png

查询对应事务的sid,存在多条sql信息,其中影响最大的为1jcysy3a5zkkr。也就是上面看到的阻塞会话正在执行的sql。除此之外,当前事务中还包含了会话中的行锁sql。也就是(bf4z87a6uf01x)。这里分析正是该事务中的相同sql相同行的更新未提交,导致了其他会话的行锁现象。

进一步对比事务的开始时间。

select distinct t1.sid,
                 t1.serial#,
                 nvl(t2.sql_text, t4.sql_text) sql_text,
                 t3.sql_id,t3.module,t3.machine,
				 round(t2.elapsed_time/1e6,1) as els_s,to_char(t3.sql_exec_start, 'mm-dd hh24:mi') as start_time,t.start_time as start_vess
   from gv$transaction            t,
        gv$session                t1,
        gv$sql                    t2,
        gv$active_session_history t3,
        dba_hist_sqltext         t4
  where t.ses_addr = t1.saddr and t.inst_id=t1.inst_id
    and t1.sid = t3.session_id
    and t1.serial# = t3.session_serial# and t1.inst_id=t3.inst_id
    and t3.sql_id = t2.sql_id( )
    and t3.sql_id = t4.sql_id( )
	and t1.sid='3484'
	order by start_time;

image.png

可以看到对应事务在前一日的0点就已经执行了。但是其中的一条查询1jcysy3a5zkkr执行较慢,且该事物中还包含对目标表的update更新(bf4z87a6uf01x)。整个事务执行不完,也就导致目标表的更新得不到提交。

此时后续会话再次运行目标表的更新时,造成行锁问题。这里分析清了问题根源。就是问题sql导致的事务执行较长,进而导致dml语句无法提交。

如下sql文本:

select count(:"sys_b_0") from (select :"sys_b_1" from t_bny, trc where trc.case_id = t_bny.busi_id and t_bny.type_id = :"sys_b_2" and trc.case_id = :"sys_b_3" union select :"sys_b_4" from t_bn, trc where trc.case_id = t_bn.busi_id and t_bn.type_id = :"sys_b_5" and trc.case_id = :"sys_b_6");

执行计划如下:

image.png

其中执行较慢为t_bn的全表扫描步骤。但经过分析,根本原因是busi_id列的隐式转换导致无法利用上相应索引。才出现的全表扫描问题。

image.png

关联列的类型不一致,就导致出现了隐式转换问题。

image.png

且这里该列上是存在索引的。

image.png

因此这里分析最好的优化方案是修改关联字段为相同类型。

但这里相应表上的数据量巨大,直接修改字段类型可能风险较大。为了尽快降低问题影响。与应用沟通,优先调整sql,在关联列部分通过显示的to_char转换,来避免目标表上的转换发生在索引列上面,出现的索引不可用问题。

select count(:"sys_b_0") from (select :"sys_b_1" from t_bny, trc where to_char(trc.case_id) = t_bny.busi_id and t_bny.type_id = :"sys_b_2" and trc.case_id = :"sys_b_3" union select :"sys_b_4" from t_bn, trc where to_char(trc.case_id) = t_bn.busi_id and t_bn.type_id = :"sys_b_5" and trc.case_id = :"sys_b_6");

调整后,不只避免了全表扫描大表的问题,还应用了更高效的索引。

image.png
避免了性能问题。

本案例正是一条低效sql,导致大事务一直执行较慢,其中的dml语句得不到即使提交,才造成的其余会话行锁问题。如果相应事务一直得不到处理,可能会引发更为严重的问题后果。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【米乐app官网下载的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

网站地图