最近压测国产数据库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 互斥
owner
是正持有锁的线程的共享内存地址
sessid
是会话标识符编号
根据sessid获得进程pid
pid
与此会话的前端关联的进程标识
$ onstat -g sql sessid
经过上面命令查看执行的sql语句
对于重要且该进程能够自动重联数据库的进程,能够用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 -u(用户)输出的 wait 字段中。
是正在等待锁的用户线程(若有)列表中的第一项
owner
是正持有锁的线程的共享内存地址
此地址对应于 onstat -u(用户)输出的 address 字段中的地址。
是刚才列出的全部者所持有锁的连接列表中的下一个锁
类型
使用如下代码指示锁的类型:
HDR
头
B
字节
S
共享
X
互斥
I
意向
U
更新
IX
意向-互斥
IS
意向-共享
SIX
共享的意向-互斥
tblsnum
是已锁定资源的表空间编号
rowid
是行标识号
行标识提供如下锁信息:
若是行标识以 2 个 0 结束,则该锁为页锁。
若是行标识为 6 个数字或更少且不以 0 结束,则该锁极可能是行锁。
若是行标识多于 6 个数字,则该锁极可能是索引键值锁。
key#/bsiz
是索引键号或对 VARCHAR 锁的已锁定字节数
若是该字段包含“K-”,后跟值,则是键锁。值标识哪一个索引正在被锁定。例如:K-1 表示对表所定义的第一个索引上的锁。
如 tblsnum等于500e19
还能够这样解决: 若是是日志型数据库,在执行的时候,能够先锁定 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 是动态分配给数据库服务器的事务的当前数量