故障现象:
在正常的数据库操作中会经常出现-243、-244 等一类的锁错误码出现
-243 Could not position within a table table-name. -244 Could not do a physical-order read to fetch next row. |
故障分析:
数据库在进行修改操作的时候为了防止其他用户的同时修改,都会在修改所涉及的数据上设置对应的锁,如果其他用户再访问到这些已经被放置上锁的数据,就会出现锁失败。例如如果需要知道在指定的表上是有哪些用户具体占用了锁,可以通过以下的步骤:
- 首先确定表的 partnum,可以通过查询 systables 里面的 partnum,也可以通过执行 oncheck –pt database:tabname 查看 Partition partnum 来获得,该数据为十进制数,需要转换为十六进制;
- 执行 onstat –k | grep partnum 来查找相应的信息,partnum 为上一个步骤获得的结果,需要使用具体的十六进制值来替换,观察其 owner 字段的地址信息;
- 执行 onstat –u | grep address 来获得实际的 session 信息,address 为上一个步骤获得的结果,这是就可以找到具体的锁的拥有者。
1、 oncheck -pt stores:customer … Partition partnum 2097201 2097201=0x200031 或在systables中找出tea对应的partnum。select * from systables where tabname = '',用计算器将此数转换成十六进制; 2、用onstat -k|grep [十六进制] 找到相应的锁,并记录相对应的owner号,此owner号表示进行此操作的用户进程。 onstat -k| grep 200031 5409bed4 0 54d93878 5409be7c HDR+IX 200031 0 0 5409bf2c 0 54d93878 5409bed4 HDR+U 200031 100 0 5、用onstat -u|grep [owner号] 找到相应的用户进程。 onstat -u | grep 54d93878 54d93878 Y--P--- 6 informix 12 5558e720 0 3 113 0 6、如果想看看到底是哪个语句产生的锁,用:onstat -g ses [owner号] 查看语句,或者用onmode -z [owner号]杀之。 onmode -z 54d93878 |
故障处理
调整数据库隔离级别,例如使用 dirty read;将数据库表的缺省页级锁修改为行级锁;设置锁等待时间;调整应用 SQL,提高执行效率,尽量快的完成事务处理,释放资源;如果需要快速处理锁冲突的情况,在确定锁的实际拥有者以后可以确定是否应该终止其操作,执行 onmode –z <sid> Kill specified session id,以达到释放锁资源的目的。