ITPub博客

首页 > 数据库 > 数据库开发技术 > 记一次DB2事务长时间未提交引起的批量变慢问题

记一次DB2事务长时间未提交引起的批量变慢问题

原创 数据库开发技术 作者:icycastle 时间:2017-03-08 15:02:22 0 删除 编辑
上周四应用更新后,周五晚上的批量明显变慢,检查DB2数据库发现大量会话都停留在同一个insert ... select ... 语句,抓取了db snap, application snap, dynamic snap 和 db2pd -eve信息
发现效率慢的这条insert语句中,select部分有一张表有大量的锁定,找到持有锁定的AppHandl,发现是周五中午的一个文件导入更新操作一直未提交,将这个连接force后就恢复正常了。

具体分析如下:

先来看当时的latch wait信息:
Latches:
Address Holder Waiter Filename LOC LatchType HoldCount
0x0780000001540478 1029 0 ../include/sqle_workload_disp.h 1391 SQLO_LT_sqeWLDispatcher__m_tunerLatch 1
0x0A00040000061908 200755 214051 sqlpgrlg.C 1553 SQLO_LT_SQLP_DBCB__ReadBufSem 0
0x0A00040000061908 200755 172871 sqlpgrlg.C 1553 SQLO_LT_SQLP_DBCB__ReadBufSem 0
0x0A00040000061908 200755 173128 sqlpgrlg.C 1553 SQLO_LT_SQLP_DBCB__ReadBufSem 0
0x0A00040000061908 200755 195620 sqlpgrlg.C 1553 SQLO_LT_SQLP_DBCB__ReadBufSem 0

holder
都是200755,waiter则有195620,从它们对应的appl的语句来看,都是insert ... select ... 跑批语句,也就是说跑批当时慢是因为latch wait。

从等待的latch名字来看,是SQLO_LT_SQLP_DBCB__ReadBufSem,这个latch的用途是:当从日志磁盘上读一条日志记录时(在log buffer中找不到),要放置一个latch。

为什么select语句要从log disk上去读记录呢?因为这个数据库的隔离级别是current commit:
CUR_COMMIT ON ON

这个功能类似于oracle中的多版本读,也就说,当select的数据当时有别的appl放置lock在上面时,读取方会转向日志读取它的上一个commit版本以避免锁等待。大量并发多版本读就会造成SQLO_LT_SQLP_DBCB__ReadBufSem上的latch wait。

但是如果没有lock,是不需要多版本读的,也就是说,select所在的表的记录当时被lock住了,这是为什么呢?

这个问题和reorg当时处于lock-wait的原因是一样的,这个lock的owner都是appl 30856(注意红色字体):
ID of agent holding lock = 30856
Application ID holding lock = 10.200.178.161.56947.200617013556
Lock name = 0x00050290000000000000000054
Lock attributes = 0x10000001
Release flags = 0x40000000
Lock object type = Table
Lock mode = Intention Exclusive Lock (IX)
Lock mode held = Intention Share Lock (IS)
Lock mode requested = Super Exclusive Lock (Z)
Name of tablespace holding lock = TBS_IO
Schema of table holding lock = ACBSAPP
Name of table holding lock = IO_D_NEW_STK_BOND_ISSU_CODE

Application handle = 30856
Application status = UOW Waiting
Status change time = 2017-03-03 11:36:04.414697
Application code page = 1208
Application country/region code = 0
DUOW correlation token = 10.200.178.161.56947.200617013556
Application name = db2jcc_application
Application ID = 10.200.178.161.56947.200617013556
Sequence number = 05393
TP Monitor client user ID =
TP Monitor client workstation name = 10.200.178.161
TP Monitor client application name =
TP Monitor client accounting string =

Connection request start timestamp = 2017-03-02 19:14:00.169036
Connect request completion timestamp = 2017-03-02 19:14:00.169528
Application idle time = 9 hours 28 minutes 31 seconds
CONNECT Authorization ID = ACBSAPP
Client login ID = ACBSAPP
Configuration NNAME of client = 10.200.178.161
Client database manager product ID = JCC03690
Process ID of client application = 0
Platform of client application = Unknown via DRDA
Communication protocol of client = TCP/IP

Inbound communication address = 10.200.178.161 56947

Lock timeout (seconds) = 60
Locks held by application = 300705

这些表明30856持有了 IO_D_NEW_STK_BOND_ISSU_CODE上将近30万个锁,且idle了9个半小时(既不commit也不rollback),因此这些锁都无法释放,造成了两个后果:

1.reorg
被lock-wait
2.
大量跑批insert ... select ... 不得不转向log disk寻求多版本读,造成log record上的latch争用,进而引起跑批变慢

所以,当force了appl 30856后,所有的现象就消失了,跑批也就不慢了,lock没有了,就不需要多版本读,也就不要SQLO_LT_SQLP_DBCB__ReadBufSem这个latch了,也就不会有争用了

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/802647/viewspace-2134935/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-03-15

  • 博文量
    9
  • 访问量
    19403