客户有两个并行删除的线程,使用delete语句删除同一张存储于UTS table里的数据,发现总能出现死锁的问题,但是在没有转UTS的时候,同样的delete语句删除存储于纯segment ts里的tb的时候,这样的死锁却不是经常发生。

一般来说当两个线程按照不同的顺序访问某些资源的时候,在等着某个正在被对方拿着的资源就会发生死锁,比如说:线程甲拿着某个资源A,但是又在等待资源B,才能继续进行,此时线程乙却拿着资源B,又要等资源A,才能继续进行。一般死锁发生后,要么两个线程都不能继续执行,要么其中一个abort掉,使得另外一个进程能够顺利结束。

那为什么同样的语句在TS从纯segment ts转成uts后,会频繁触发死锁呢?这需要提供给客户slip command,然后客户送来deadlock发生时数据库的dump来具体分析。

首先可以看到客户碰到deadlock的message如下:

12.27.12 STC04492 DSNT375I :DB2B PLAN=BATPLASL WITH 390

390 CORRELATION-ID=WKAL1243

390 CONNECTION-ID=BATCH

390 LUW-ID=DKSDCN01.SCPDB2B.DC447A90F2EF=165362

390 THREAD-INFO=OPCP:BATCH:OPCP:WKAL1243:STATIC:582363:*:

390 IS DEADLOCKED WITH PLAN=BATPLASL WITH

390 CORRELATION-ID=KPDL3823

390 CONNECTION-ID=BATCH

390 LUW-ID=DKSDCN01.SCPDB2B.DC4488D542B3=110590

390 THREAD-INFO=OPCP:BATCH:OPCP:KPDL3823:STATIC:582363:*:

390 ON MEMBER DB2B

12.27.12 STC04492 DSNT501I :DB2B DSNILMCL RESOURCE UNAVAILABLE 391 <--所以是DSNILMCL发出deadlock的消息

391 CORRELATION-ID=WKAL1243

391 CONNECTION-ID=BATCH

391 LUW-ID=DKSDCN01.SCPDB2B.DC447A90F2EF=165362

391 REASON 00C90088

391 TYPE 00000304

391 NAME NA04D02L.NA04T01L.X'0004ED93'.X'01'

通过查看DSNILMCL的源码,设计出一个slip trap,客户设置好slip trap后,等待下一次问题重现,Db2就会抓一个SVC dump,需要进一步学习这个slip dump来看看deadlock是怎么发生的。

客户重现了这个问题后,送来了deadlock的slip dump,通过IP VERBX MTRACE可以下面两个线程AF17和16B42发生了死锁,触发的dump来存储deadlock发生时Db2的内存镜像。

IP VERBX MTRACE

M 8000000 SC08 22291 10:21:03.38 STC04953 00000000 DSNT375I :DBB1 PLAN=BATPLASL WITH 501

D 501 00000000 CORRELATION-ID=KPPL2823

D 501 00000000 CONNECTION-ID=BATCH

D 501 00000000 LUW-ID=DKSDCN01.SCPDBB1.DC45B0CF51A3=44823 <--AF17

D 501 00000000 THREAD-INFO=OPCP:BATCH:OPCP:KPPL2823:STATIC:582363:*:*

D 501 00000000 IS DEADLOCKED WITH PLAN=BATPLASL WITH

D 501 00000000 CORRELATION-ID=KPKL2823

D 501 00000000 CONNECTION-ID=BATCH

D 501 00000000 LUW-ID=DKSDCN01.SCPDBB1.DC45A72E0BA0=92994 <--16B42

D 501 00000000 THREAD-INFO=OPCP:BATCH:OPCP:KPKL2823:STATIC:582363:*:*

E 501 00000000 ON MEMBER DBB1

NR0040000 SC08 22291 10:21:03.39 JNAXE$ 00000000 IEA992I SLIP TRAP ID=DEAD MATCHED. JOBNAME=KPPL2823,

通过DS=3.RS=2,DM=2命令,我们可以看到发生死锁时这两个线程都在干嘛

Jobname KPPL2823 ASID(0207)

ACE: 18B41F20 Status: TR* Req: 336E Allied Chain

CT: 0000042A9DD12D08 Lg: 787A8520 56K AGL 64: 0000042981259030 1404K AGL V64: 0000042981274830 1088K

Authid: OPCP Plan: BATPLASL Corrid: KPPL2823 Corrname: BATCH Token: 0000AF17

EB Primary(Asid) Home(Asid) EBSPAWND TCB/SRB -Status-- R14

18B42008 DBB1DBM1(00A7) KPPL2823(0207) 00000000 009F5938 Running 9C0E87EE 10/18/2022 10:21:03.386716

LKTR: 0000005D_5BBB0030 CT: 0000042A_9DD12D08 EB: 18B42008

func type stat dura name rc token r14 time owu lktrent rc-hex

466 lock row x comm 020A.0002.001357B401 00000000 7EEC0580 DSNKNXT2+00E454 DC45B0E92DD8 18B41F20 005D_5BBC56F0 00000000

467 unlk row x comm 00000000 7EEC0580 DSNKNXT2+00B792 DC45B0E92DD9 18B41F20 005D_5BBC57EC 00000000

468 lock row x comm 020A.0002.001357B301 00000000 7EEC0580 DSNKNXT2+00E454 DC45B0E92DDD 18B41F20 005D_5BBC58E8 00000000

469 unlk row x comm 00000000 7EEC0580 DSNKNXT2+00B792 DC45B0E92DDE 18B41F20 005D_5BBC59E4 00000000

470 lock row x comm 020A.0002.001357B001 alrdyhld 7EF93770 DSNKNXT2+00E454 DC45B0E92D31 18B41F20 005D_5BBC5AE0 00041040

471 unlk row x ma+1 00042800 7EF93770 DSNKNXT2+00B386 DC45B0E92DDF 18B41F20 005D_5BBC5BDC 00042800

472 lock row x comm 020A.0002.001357AF01 alrdyhld 7F67C730 DSNKNXT2+00E454 DC45B0E92D46 18B41F20 005D_5BBC5CD8 00041040

473 unlk row x ma+1 00042800 7F67C730 DSNKNXT2+00B386 DC45B0E92DDF 18B41F20 005D_5BBC5DD4 00042800

498 lock row x comm 020A.0002.001357B201 condfail 00000000 DSNKNXT2+00E454 000000000000 18B41F20 005D_5BBC7670 00084040

499 lock row s comm 020A.0002.001357B201 condfail FFFFFFFF DSNKNXT2+01156A DC45B0E92DB6 18B41F20 005D_5BBC776C 00084040

500 lock row x comm 020A.0002.001357B201 deadtime 00000000 DSNKNXT2+012510 000000000000 18B41F20 005D_5BBC7868 00082000

==SQL Statement

-------------

DELETE FROM CHECKPOINT WHERE ( JOBID_TXT = : H ) AND ( PGMID_TXT = : H

)

Jobname KPKL2823 ASID(01C5)

ACE: 187C8920 Status: TR* Req: 63FD Allied Chain

CT: 0000042AFDD14D08 Lg: 787A6E60 56K AGL 64: 0000042980EF41B0 1328K AGL V64: 000004298090BEB0 1420K

Authid: OPCP Plan: BATPLASL Corrid: KPKL2823 Corrname: BATCH Token: 00016B42

EB Primary(Asid) Home(Asid) EBSPAWND TCB/SRB -Status-- R14

187C8A08 DBB1DBM1(00A7) KPKL2823(01C5) 00000000 009EC248 Suspended 1BE3D8A1 DSNTLSUS UI79550 +0007A1 10/18/2022 10:21:02.817026

==SQL Statement

-------------

DELETE FROM CHECKPOINT WHERE ( JOBID_TXT = : H ) AND ( PGMID_TXT = : H

)

LKTR: 0000005D_72150030 CT: 0000042A_FDD14D08 EB: 187C8A08

func type stat dura name rc token r14 time owu lktrent rc-hex

455 lock row x comm 020A.0002.001357D401 00000000 7EEC0580 DSNKNXT2+00E454 DC45B0E92E79 187C8920 005D_7216E0C0 00000000

456 unlk row x comm 00000000 7EEC0580 DSNKNXT2+00B792 DC45B0E92E7A 187C8920 005D_7216E1BC 00000000

457 lock row x comm 020A.0002.001357D301 00000000 7EEC0580 DSNKNXT2+00E454 DC45B0E92E7F 187C8920 005D_7216E2B8 00000000

458 unlk row x comm 00000000 7EEC0580 DSNKNXT2+00B792 DC45B0E92E80 187C8920 005D_7216E3B4 00000000

459 lock row x comm 020A.0002.001357B201 alrdyhld 7F67C4A0 DSNKNXT2+00E454 DC45B0E92DB6 187C8920 005D_7216E4B0 00041040

460 unlk row x ma+1 00042800 7F67C4A0 DSNKNXT2+00B386 DC45B0E92E80 187C8920 005D_7216E5AC 00042800

461 lock row x comm 020A.0002.001357B101 alrdyhld 7EE31D10 DSNKNXT2+00E454 DC45B0E92DC8 187C8920 005D_7216E6A8 00041040

462 unlk row x ma+1 00042800 7EE31D10 DSNKNXT2+00B386 DC45B0E92E80 187C8920 005D_7216E7A4 00042800

499 lock row x comm 020A.0002.001357B001 condfail 00000000 DSNKNXT2+00E454 000000000000 187C8920 005D_72151FE0 00084040

500 lock row s comm 020A.0002.001357B001 condfail FFFFFFFF DSNKNXT2+01156A DC45B0E92D31 187C8920 005D_721520DC 00084040

可以用DB=5,DBID=020A,OBID=0002来看相关数据库对象的DDL

OBDFILE: 0000005D_2A26FBFC (020A.0001)

OBDPSET: 0000005D_2A26FA38 (020A.0002)

CREATE LARGE TABLESPACE NA04T01L IN NA04D02L <---020A。0002是一个PBG UTS

MAXPARTITIONS 6

COMPRESS NO

SEGSIZE 32

LOCKSIZE ROW

MAXROWS 1

DSSIZE 64G

OBDREC: 0000005D_2A26F7C4 (020A.0003)

OBDRX: 0000005D_2A26F8D0

OBDRX2: 0000005D_2A26F920

Current version number: 0000

CREATE TABLE NA04D02L.CHECKPOINT <---TB is NA04D02L.CHECKPOINT,正式delete语句操作的TB

(

C1 CHAR( 8) NOT NULL

C2 CHAR( 8) NOT NULL

C3 TIMESTAMP NOT NULL

C4 CHAR( 8) NOT NULL

C5 INTEGER NOT NULL

C6 INTEGER NOT NULL

C7 VARCHAR( 4004) NOT NULL

)

IN NA04D02L.NA04T01L;

所以到这里我们知道线程AF17和16B42都在执行同样的delete语句删除table NA04D02L.CHECKPOINT 里面满足条件的记录。因为都是DSNK module来lock/unlock data page,因此这delete走的是index access path。

从中可以看到在执行delete语句的时候AF17 先delete 001357B0-01,所以先拿着001357B0-01的x row lock, 然后发现在index上有pseudo delete index entry with rid 001357B2-01,因此index需要 lock/unock一下001357B2-01,来确保record 001357B2-01已经被删除了。但这时另外一个thread 16B42正在删除data record 001357B2-01,所以直到commit,一直拿着x row lock on 001357B2-01,16B42继续删除被的record,发现index上有pseudo delete index entry with rid 001357B0-01,因此需要lock/unlock一下001357B0-01,但此时AF17 正拿着001357B0-01的x row lock,因此产生了死锁。

经过和Db2 developer讨论,这个时因为在转成PBG UTS之后,有了一个pseudo delete的功能,来尽可能在原来删除的位置上利用这些磁盘空间,删除之后相关的index entry/data record 都会变成pseudo delete index entry/data record, 所以delete如果走index path 的话,正在删除的记录会一直被lock到ur结束,而index也会lock/unlock满足条件的pseudo delete data record。如果thread结束之前,别的thread就拿不到lock,这样这两个并行的delete thread就会因为delete的顺序不同,导致deadlock的问题。因此给出的建议时在做并行delete的时候不要走index path,但这样会可能会带来delete操作的时间更长。

 

推荐链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。