Sqlcode -244 死锁问题解决
一、分析产生死锁的原因
这个问题通常是因为锁表产生的。要么是多个用户同时访问数据库导致该问题,要么是因为某个进程死了以后资源未释放导致的。
如果是前一种情况,可以考虑将数据库表的锁级别改为行锁,来减少撞锁的机会;或在应用程序中,用set lock mode wait 3这样的语句,在撞锁后等待若干秒重试。
如果是后一种情况,可以在数据库端用onstat -g ses/onstat -g sql/onstat -k等命令找出锁表的进程,用onmode -z命令结束进程;如果不行,就需要重新启动数据库来释放资源。
二、方法一
onmode -u 将数据库服务器强行进入单用户模式,来释放被锁的表。注意:生产环境不适合。
三、方法二
1、onstat -k |grep HDR+X
说明:HDR+X为排他锁,HDR 头,X 互斥。返回信息里面的owner项是正持有锁的线程的共享内存地址。
2、onstat -u |grep c60a363c
说明:c60a363c为1中查到的owner内容。sessid是会话标识符编号。
3、onstat -g ses 20287
说明:20287为2中查到的sessid内容。Pid为与此会话的前端关联的进程标识符。
4、onstat -g sql 20287
说明:20287为2中查到的sessid内容。通过上面的命令可以查看执行的sql语句。
5、ps -ef |grep 409918
说明:409918为4中查到的pid内容。由此,我们可以得到锁表的进程。可以根据锁表进程的重要程度采取相应的处理方法。对于重要且该进程可以自动重联数据库的进程,可以用onmode -z sessid的方法杀掉锁表session。否则也可以直接杀掉锁表的进程 kill -9 pid。
四、避免锁表频繁发生的方法 4.1将页锁改为行锁
1、执行下面sql语句可以查询当前库中所有为页锁的表名:
select tabname from systables
where locklevel='P' and tabid > 99
2、执行下面语句将页锁改为行锁
alter table tabname lock mode(row)
4.2统计更新
UPDATE STATISTICS;
4.3修改数据库配置onconfig
OPTCOMPIND参数帮助优化程序为应用选择合适的访问方法。
∙ 如果OPTCOMPIND等于0,优化程序给予现存索引优先权,即使在表扫描比较快时。
∙ 如果OPTCOMPIND设置为1,给定查询的隔离级设置为Repeatable Read时,优化程序才使用索引。
∙ 如果OPTCOMPIND等于2,优化程序选择基于开销选择查询方式。,即使表扫描可以临时锁定整个表。
*建议设置:OPTCOMPIND 0 # To hint the optimizer
五、起停informix数据库
停掉informix数据库
onmode -ky
启动informix数据库
oninit 注意千万别加-i参数,这样会初始化表空间,造成数据完全丢失且无法挽回。
Sqlcode -244 死锁问题解决
一、分析产生死锁的原因
这个问题通常是因为锁表产生的。要么是多个用户同时访问数据库导致该问题,要么是因为某个进程死了以后资源未释放导致的。
如果是前一种情况,可以考虑将数据库表的锁级别改为行锁,来减少撞锁的机会;或在应用程序中,用set lock mode wait 3这样的语句,在撞锁后等待若干秒重试。
如果是后一种情况,可以在数据库端用onstat -g ses/onstat -g sql/onstat -k等命令找出锁表的进程,用onmode -z命令结束进程;如果不行,就需要重新启动数据库来释放资源。
二、方法一
onmode -u 将数据库服务器强行进入单用户模式,来释放被锁的表。注意:生产环境不适合。
三、方法二
1、onstat -k |grep HDR+X
说明:HDR+X为排他锁,HDR 头,X 互斥。返回信息里面的owner项是正持有锁的线程的共享内存地址。
2、onstat -u |grep c60a363c
说明:c60a363c为1中查到的owner内容。sessid是会话标识符编号。
3、onstat -g ses 20287
说明:20287为2中查到的sessid内容。Pid为与此会话的前端关联的进程标识符。
4、onstat -g sql 20287
说明:20287为2中查到的sessid内容。通过上面的命令可以查看执行的sql语句。
5、ps -ef |grep 409918
说明:409918为4中查到的pid内容。由此,我们可以得到锁表的进程。可以根据锁表进程的重要程度采取相应的处理方法。对于重要且该进程可以自动重联数据库的进程,可以用onmode -z sessid的方法杀掉锁表session。否则也可以直接杀掉锁表的进程 kill -9 pid。
四、避免锁表频繁发生的方法 4.1将页锁改为行锁
1、执行下面sql语句可以查询当前库中所有为页锁的表名:
select tabname from systables
where locklevel='P' and tabid > 99
2、执行下面语句将页锁改为行锁
alter table tabname lock mode(row)
4.2统计更新
UPDATE STATISTICS;
4.3修改数据库配置onconfig
OPTCOMPIND参数帮助优化程序为应用选择合适的访问方法。
∙ 如果OPTCOMPIND等于0,优化程序给予现存索引优先权,即使在表扫描比较快时。
∙ 如果OPTCOMPIND设置为1,给定查询的隔离级设置为Repeatable Read时,优化程序才使用索引。
∙ 如果OPTCOMPIND等于2,优化程序选择基于开销选择查询方式。,即使表扫描可以临时锁定整个表。
*建议设置:OPTCOMPIND 0 # To hint the optimizer
五、起停informix数据库
停掉informix数据库
onmode -ky
启动informix数据库
oninit 注意千万别加-i参数,这样会初始化表空间,造成数据完全丢失且无法挽回。