热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

记一则update发生enq:TXrowlockcontention的处理方法

根据事后在虚拟机中复现客户现场发生的情况,做一次记录(简化部分过程,原理不变)客户端1执行update语句SQLselect*fromtest;IDNAME2b10c1bSQL

根据事后在虚拟机中复现客户现场发生的情况,做一次记录(简化部分过程,原理不变)

客户端1执行update语句


SQL> select * from test;

ID NAME
---------- --------------------------------
2 b
10 c
1 b

SQL
> update test set id = 3 where name = c;

1 row updated.

客户端2执行另外一条update语句


SQL> update test set id = 4 where name = c;

这个时候第二条update卡住了,证明发生了hanganalyze,查询当前的等待事件


SQL> select vw.sid,v.serial#, vw.event, vw.p1raw, vw.p2, v.username, sql_id from v$session_wait vw, v$session v where vw.sid = v.sid and vw.event not like %message% order by 3 desc;

SID SERIAL# EVENT P1RAW P2 USERNAME SQL_ID
---------- ---------- -------------------------------------------------- ---------------- ---------- --------------- -------------
13 1 smon timer 000000000000012C 0
2 1 pmon timer 000000000000012C 0
40 7 i/o slave wait 0000000091605340 0
42 23 i/o slave wait 0000000091605340 0
36 23 enq: TX - row lock contention 0000000054580006 196608 ELAN 53msja8m8hbcw
4 1 VKTM Logical Idle Wait 00 0
31 3 Streams AQ: waiting for time management or cleanup 00 0
tasks

18 15 Streams AQ: qmn slave idle wait 0000000000000001 0
25 9 Streams AQ: qmn coordinator idle wait 00 0
33 43 Space Manager: slave idle wait 00 0
8 1 DIAG idle wait 0000000000000005 1
6 1 DIAG idle wait 0000000000000005 1

12 rows selected.

可以看到等待事件中有tx锁

进而查找彼此发生的依赖关系,是谁堵塞了谁


SELECT DECODE(request,0,Holder: ,Waiter: )||sid sess, id1, id2, lmode, request, type FROM V$LOCK WHERE (id1, id2, type) IN(SELECT id1, id2, type FROM V$LOCK WHERE request>0) ORDER BY id1, request;

SESS ID1 ID2 LMODE REQUEST TY
------------------------------------------------ ---------- ---------- ---------- ---------- --
Holder: 46 196608 786 6 0 TX
Waiter:
36 196608 786 0 6 TX

发现,持有者是46号sid,等待着是36号sid,并且lmode模式是6

在oracle官方的支持文档中可以看到对于该模式的描述   exclusive 独占(X):独立访问使用,exclusive,通常发生在Alter table, Drop table, Drop Index, Truncate table, Lock Exclusive

技术分享图片

进而可以根据sid查找是那条语句发生了阻塞


SELECT /*+ ORDERED */ a.SQL_TEXT FROM v$sqltext a WHERE (a.hash_value, a.address) IN ( SELECT DECODE (sql_hash_value, 0, prev_hash_value, sql_hash_value ), DECODE (sql_hash_value, 0, prev_sql_addr, sql_address) FROM v$session b where b.SID = 46) order by a.PIECE

SQL_TEXT
----------------------------------------------------------------
update test set id = 3 where name = c

进而可以根据sid和serial反查是那个机器发出了这条指令


select sid,serial#,machine,CLIENT_INFO from v$session where sid =
2 46;

SID SERIAL# MACHINE CLIENT_INFO
---------- ---------- ---------------------------------------------------------------- ----------------------------------------------------------------
46 67 elan

基本就能够排查所出现情况,进而进行沟通解决,是不是语句未提交导致,或者是其他原因

等待持有锁的会话commit或者rollback。 通常为会话1在某行上执行 update/delete 未提交,会话2对同一行数据进行 update/delete,或其它原因(例如SQL性能差)造成的锁释放速度缓慢或网络问题,都会造成后续的会话进入队列等待

不着急查杀,这个还是要等待确认后,在进行下一步操作

 

接下里我们使用hanganalyze来分析上述问题

执行hanganalyze

 


SQL> ORADEBUG setmypid
Statement processed.
SQL
> oradebug unlimit;
Statement processed.
SQL
> oradebug hanganalyze 3
Hang Analysis
in /u01/app/oracle/diag/rdbms/elan/elan/trace/elan_ora_6322.trc
SQL
>

HANG ANALYSIS基本信息,摘录部分信息如下


-------------------------------------------------------------------------------
Chain 1:
-------------------------------------------------------------------------------
Oracle session identified by: --阻塞会话信息
{
instance:
1 (elan.elan)
os id:
6337
process id:
27, oracle@elan (TNS V1-V3)
session id:
36
session serial #:
23
}
is waiting for enq: TX - row lock contention with wait info:
{
p1:
name|mode=0x54580006
p2:
usn<<16 | slot=0x30000
p3:
sequence=0x312
time
in wait: 19 min 57 sec
timeout after: never
wait id:
24
blocking:
0 sessions --此处显示当前会话没有阻塞的session,说明是被阻塞会话
current sql: update test set id = 4 where name = c
wait history:
* time between current wait and wait #1: 0.000966 sec
1. event: db file sequential read
time waited:
0.000178 sec
wait id:
23 p1: file#=0x5
p2:
block#=0x8a
time waited:
0.000040 sec
wait id:
22 p1: FileOperation=0x2
p2:
fileno=0x5
p3:
filetype=0x2
* time between wait #2 and #3: 0.001004 sec
3. event: SQL*Net message from client
time waited:
17.589536 sec
wait id:
21 p1: driver id=0x62657100
p2:
#bytes=0x1
}
and is blocked by
=> Oracle session identified by:
{
instance:
1 (elan.elan)
os id:
6336
process id:
25, oracle@elan (TNS V1-V3)
session id:
46 --会话session
session serial #: 67
}
which
is waiting for SQL*Net message from client with wait info:
{
p1:
driver id=0x62657100
p2:
#bytes=0x1
time
in wait: 20 min 21 sec
timeout after: never
wait id:
25
blocking:
1 session --此处显示被阻塞的会话数是1,也证明是锁会话持有者
current sql: <none>
short stack: ksedsts()
+465<-ksdxfstk()+32<-ksdxcb()+1927<-sspuser()+112<-__sighandler()<-read()+14<-ntpfprd()+117<-nsbasic_brc()+376<-nsbrecv()+69<-nioqrc()+495<-opikndf2()+978<-opitsk()+831<-opiino()+969<-opiodr()+917<-opidrv()+570<-sou2o()+103<-opimai_real()+133<-ssthrdmain()+265<-main()+201<-__libc_start_main()+253
wait history:
* time between current wait and wait #1: 0.000003 sec
1. event: SQL*Net message to client
time waited:
0.000001 sec
wait id:
24 p1: driver id=0x62657100
p2:
#bytes=0x1
* time between wait #1 and #2: 0.000069 sec
2. event: Disk file operations I/O
time waited:
0.000040 sec
wait id:
23 p1: FileOperation=0x2
p2:
fileno=0x3
p3:
filetype=0x2
* time between wait #2 and #3: 0.000287 sec

  

通过上述分析:大概可以得出sid=36因为请求enq: TX - row lock contention(TX mode=6)被sid=46阻塞

 

分析过程基本如上


推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
author-avatar
书友73428983
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有