背景
生产环境中,我几乎没有遇到过锁表。多是在开发过程中遇到的,比如团队开发中经常会遇到多个功能访问同一张表的情况。如果有开发人员在这张表加了排它锁,然后又忘记提交事务,那么其他开发人员就要一直等待了。如开发人员在断点调试(Debug)忘记点通过、数据库客户端中修改数据忘记Commit……
当我们在办公室或公司IM上喊了几次后没人反应后,就需要强制解锁了。
DB2解锁实战
打开DB2命令行,开始战斗。
1.查找NODE节点
键入命令“LIST NODE DIRECTORY”,我们会发现当前局域网的所有数据库节点。
db2 => LIST NODE DIRECTORY 节点目录 目录中的条目数 = 3 节点 1 条目: 节点名 = NDE5DC7D 注释 = 目录条目类型 = LOCAL 协议 = TCPIP 主机名 = 192.168.1.11 服务名称 = 50000 节点 2 条目: 节点名 = NDE5F473 注释 = 目录条目类型 = LOCAL 协议 = TCPIP 主机名 = 192.168.1.12 服务名称 = 50001 节点 3 条目: 节点名 = NDE9BBAE 注释 = 目录条目类型 = LOCAL 协议 = TCPIP 主机名 = 192.168.1.13 服务名称 = 50001
我要找的表在192.168.1.12节点,那么根据节点名连接。
db2 => attach to NDE5F473 user [username] using [password] 实例连接信息 实例服务器 = DB2/LINUX 9.5.0 授权标识 = DB2INST1 本地实例别名 = NDE5F473
2.获取数据库锁定快照
连上实例服务器之后,我们要获取目标数据库锁定快照,然后找出是那个应用链接锁定了目标表。
为了方便导出快照文件,我们先退出db2命令行。
db2 => quit DB20000I QUIT 命令成功完成。
然后,我们获取目标数据库快照文件。
C:Documents and SettingsAdministrator>db2 GET SNAPSHOT FOR locks on [dbname] > lock.txt
开始分析快照文件,找到锁定表的应用。
db2 => GET SNAPSHOT FOR locks on XXXX 数据库锁定快照 数据库名称 = XXXX 数据库路径 = /home/db2inst2/db2inst2/NODE0000/SQL00 输入数据库别名 = XXXX 挂起的锁定 = 4 当前已连接的应用程序 = 13 当前正等待锁定的代理程序数 = 0 快照时间戳记 = 2011-03-31 13:21:53.285610 ...... 应用程序句柄 = 26773 应用程序标识 = C0A8013D.J805.110331005614 序号 = 00003 应用程序名 = db2jcc_application CONNECT 授权标识 = DB2INST1 应用程序状态 = UOW 正在等待 状态更改时间 = 未收集 应用程序代码页 = 1208 挂起的锁定 = 0 总计等待时间(毫秒) = 未收集 应用程序句柄 = 28266 应用程序标识 = 192.168.1.56.39691.110331051526 序号 = 00001 应用程序名 = db2bp.exe CONNECT 授权标识 = DB2INST1 应用程序状态 = 连接已完成 状态更改时间 = 未收集 应用程序代码页 = 1386 挂起的锁定 = 0 总计等待时间(毫秒) = 未收集 应用程序句柄 = 28292 应用程序标识 = 192.168.1.56.64523.110331052144 序号 = 00001 应用程序名 = db2jcc_application CONNECT 授权标识 = DB2INST1 应用程序状态 = UOW 正在等待 状态更改时间 = 未收集 应用程序代码页 = 1208 挂起的锁定 = 4 总计等待时间(毫秒) = 未收集 锁定列表 锁定名称 = 0x0600030A1100A0FF0400000052 锁定属性 = 0x00000008 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 0 锁定对象名 = 21468545041 对象类型 = 行 表空间名 = TABLESPACE_IDX 表模式 = DB2INST1 表名 = TABLENAME 方式 = X 锁定名称 = 0x5359535348323030DDECEF2841 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 0 锁定对象名 = 0 对象类型 = 内部方案锁定 方式 = S 锁定名称 = 0x53514C4445464C5428DD630641 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 0 锁定对象名 = 0 对象类型 = 内部方案锁定 方式 = S 锁定名称 = 0x0600030A000000000000000054 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 0 锁定对象名 = 2563 对象类型 = 表 表空间名 = TABLESPACE_IDX 表模式 = DB2INST1 表名 = TABLENAME 方式 = IX
经过分析,我们发现应用程序句柄28292,IP192.168.1.56的这台机器上db2jcc_application应用锁定了目标表。这应该是一个jdbc程序,基本断定是有人在Debug断点调试,可以根据IP找到人让他把断点过掉。有时显示的是十六进制的IP(如C0A8013D),那就自己用计算机原理中学到的进制转换算吧。C0 -> 192,A8 ->168,01 -> 1,3D -> 61,就192.168.1.61。
3.强制结束锁表的链接
如果找不到相关人员主动解锁,那就只能强制结束链接了。我们之前已经找到应用程序句柄是28292,那现在就来暴力解除。DB2提醒改命令为异步,一般几秒后就发现目标表可以访问了。
db2 => force application(28292) DB20000I FORCE APPLICATION命令成功完成。 DB21024I 该命令为异步的,可能不会立即生效。