上周四应用更新后,周五晚上的批量明显变慢,检查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/
,如需转载,请注明出处,否则将追究法律责任。