Gbase8t(Informix)死锁问题

最近压测国产数据库Gbase8t,内核是Informix,压测中遇到问题以下:前端

 Could not do a physical-order read to fetch netxt rowsql

解决方式:数据库

一、设置锁的级别从表变成行
  ALTER TABLE <table name> LOCK MODE (ROW) 
   update statistics high 
   SET LOCK MODE TO WAIT 10 (10ms)服务器

二、这个问题一般是由于锁表产生的。要么是多个用户同时访问数据库致使该问题,要么是由于某个进程死了之后资源未释放致使的。若是是前一种状况,能够考虑将数据库表的锁级别改成行锁,来减小撞锁的机会;或在应用程序中,用set lock mode wait 3这样的语句,在撞锁后等待若干秒重试。若是是后一种状况,能够在数据库端用onstat -g ses/onstat   -g   sql/onstat   -k等命令找出锁表的进程,用onmode   -z命令结束进程;若是不行,就须要从新启动数据库来释放资源。session

方法一
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 sessid
根据sessid获得进程pid
pid 
与此会话的前端关联的进程标识 
$ onstat -g sql sessid 
经过上面命令查看执行的sql语句
4:$ ps -ef |grep pid
由此,咱们可获得锁表的进程,可根据实际锁表进程的重要程度的具体状况采起相映处理方法:
对于重要且该进程能够自动重联数据库的进程,能够用onmode  -z sesid 的方法杀掉锁表session,
$ onmode –z sessid
不然也可直接杀掉锁表的进程 kill pid。
$ kill -9 pid
 
将表的页锁改成行锁   
  参考语句为   
  unload   to   optimize.sql   delimiter   ""   select   'alter   table   '||tabname||     
  '   lock   mode(row)'||';'from   systables   where     locklevel="P"   and   tabid   >   99   
  将卸载的optimize.sql稍微删除一下其中出现的字符或乱码,后运行,便可把表的页锁改成行锁
 
onstat -k 输入内容描述:
address 
是锁表中锁的地址 
若是用户线程正在等待该锁,则锁的地址出如今 onstat -u(用户)输出的 wait 字段中。
wtlist 
是正在等待锁的用户线程(若有)列表中的第一项 
owner 
是正持有锁的线程的共享内存地址 
此地址对应于 onstat -u(用户)输出的 address 字段中的地址。
lklist 
是刚才列出的全部者所持有锁的连接列表中的下一个锁 
类型 
使用如下代码指示锁的类型: 
HDR 
头 

字节 

共享 

互斥 

意向 

更新 
IX 
意向-互斥 
IS 
意向-共享 
SIX 
共享的意向-互斥 
tblsnum 
是已锁定资源的表空间编号 
rowid 
是行标识号 
行标识提供如下锁信息:
若是行标识等于 0,则该锁为表锁。 
若是行标识以 2 个 0 结束,则该锁为页锁。 
若是行标识为 6 个数字或更少且不以 0 结束,则该锁极可能是行锁。 
若是行标识多于 6 个数字,则该锁极可能是索引键值锁。
key#/bsiz 
是索引键号或对 VARCHAR 锁的已锁定字节数 
若是该字段包含“K-”,后跟值,则是键锁。值标识哪一个索引正在被锁定。例如:K-1 表示对表所定义的第一个索引上的锁。
可用锁的最大数量以 ONCONFIG 文件中的 LOCKS 进行指定。
 
查找锁定的表名称
经过onstat -k 查找的rowid 等于0的表锁信息的 tblsnum 信息查找表名。 
如 tblsnum等于500e19
执行 select * from systables where hex(partnum)='0x00500e19'
查找到当前锁表的表名。
 
 
Informix -244 错误 :
Could not do a physical-order read to fetch next row.
 
具体错误解释:
   #finderr -244
 
缘由:
a.锁表
b.记录太多
c.页损坏
d.某个进程死了之后资源未释放致使
   在数据库端用  onstat –g ses/onstat –g sql /
Onstat –k 等找出锁表进程,用onmode –z结束该进程,
不行,重启数据库释放。
锁方式:
   行方式(row),页方式(默认page),表方式(table)。
 
解决:
   1.下降锁级别
   2.减小加锁事务的时间跨度
   3.设置等待解琐时间
 
相关命令:
   )检查索引及页损坏状况
#oncheck  –cID  database_name:table_name
   ) 查看锁级别
#oncheck  –pt  database_name:table_name
   )设置锁级别(行方式)
#alter table table_name lock mode(row)
   )设置隔离级别
#set isolation to dirty read
   )设置等待解锁时间(不宜过大)
#set lock mode to wait second(秒)
不等待
#set lock mode to not wait
 
 
还能够这样解决: 若是是日志型数据库,在执行的时候,能够先锁定 begin work; lock table tab_name in exclusive mode; 要执行的sql语句; commit work; 若是是非日志的数据 lock table table_name in exclusive mode; 要执行的sql语句; unlock table tab_name; 
中间件全局事务锁问题 中间件与informix链接时会出现onstat -k 中 owner 内容为0的现象。 这是应该查看全局事务onstat -x 和onstat -G DATABASE sysmaster; select hex(tx_addr) trans_addr,hex(tx_lklist) lock_addr from systrans where hex(tx_addr) like '%c00000006e329778%'; 须要说明的是,c000000007674c58是使用onstat -x 或 onstat -G获得的全局事务的地址。 上面SQL语句提供出该全局事务对应的锁地址,这时若是获得的锁地址与锁表的锁地址相同的话,你就必需从应用端(一般是三层结构的中间件)发命令让该全局事务回滚或提交,不然该锁会被一直持有,直到你执行oninit。
 

onstat -k 的owner 列中的地址与onstat -x 中的userthread 对应。并发

 

以下解释 onstat -x 的输出curl

address
是事务结构的共享内存地址
flags
位置 1 的标志代码(当前事务状态):
A
用户线程已链接到事务
S
TP/XA 暂挂的事务
C
TP/XA 正在等待回滚
位置 2 的标志代码(事务方式):
分布式

T
紧耦合方式(MTS)
L
松耦合方式(缺省方式)
位置 3 的标志代码(事务阶段):
fetch

B
开始工做
P
准备好用于提交的分布式查询
X
准备好用于提交的 TP/XA
C
正在提交或已提交
R
正在回滚或已回滚
H
正在尝试回滚或已回滚
位置 5 的标志代码(事务类型):
url

G
全局事务
C
分布式查询协调者
S
分布式查询从属者
B
分布式查询协调者和从属者
userthread
是拥有事务的线程(rstcb 地址)
locks
是事务持有的锁数
beginlg
是 BEGIN WORK 记录已记录到其中的日志
curlog
是事务正在写入的当前日志
logposit
是日志位置
4 字节日志位置的格式是 0xPPPPPBBB,其中 PPPPP 是日志中的页偏移量,BBB 是页中的字节偏移量。logposit 能够是日志文件中的 0x100000(或 1048576)页的最大数。

isol
是隔离级别。
retrys
是启动分布式查询的恢复线程的尝试次数
coord
是从属者正在执行事务时事务协调者的名称
该字段告诉您哪一个数据库服务器正在协调两阶段提交。

onstat -x 输出的最后一行指示 maximum concurrent 是自初始化数据库服务器以来并发事务的最大数。

 

以下解释 onstat -G 的输出

address 是事务控制块的内存中地址 flags 是全局事务的当前状态(使用如下十六进制值组合): x00000001 用户已链接到事务上 x00000002 打开事务 x00000004 xa_start() 和 xa_end() 之间的事务 x00000008 全局事务 x00000010 标记为仅异常终止的事务 x00000020 TP/XA 准备的事务 x00000040 分布式事务 x00000080 异常终止的事务 x00000100 已提交的事务 x00000200 已尝试完成的事务 x00000400 已写入 BEGIN WORK 日志记录 x00000800 回滚已完成 x00001000 已开始提交已删除表和索引 x00002000 已开始异常终止事务 x00004000 未执行撤销操做 x00008000 全局保存点处于活动状态 x00010000 保存点回滚 x00020000 清除死事务 x00040000 事务用于远程数据库服务器 x00080000 事务条目在使用中 x00100000 事务已执行远程工做 x00200000 保存点已开始 x00400000 分布式事务中的协调者 x00800000 分布式事务中的从属者 x01000000 长事务或暂挂事务没有全部者 x02000000 事务正在恢复中 x04000000 对该事务的重作失败 x08000000 对该事务进行的撤销失败 x10000000 当发生 I/O 故障时事务是活动的 x20000000 事务在恢复过程当中执行了某些工做 x40000000 事务包含锁 x80000000 事务执行了 DDR 工做 fID 是事务数据的格式标识 gtl 是全局事务的长度 bql 是事务的字节流长度 data 是事务标识和数据的十六进制转储 摘要定义 active 是活动全局事务的数量 total 是动态分配给数据库服务器的事务的当前数量

相关文章
相关标签/搜索