原文链接:https://www.gbase.cn/community/post/3915
数据库锁表问题一直是数据库管理中的一个难题。在GBase 8s数据库中,锁表可能导致表头、数据行等被锁定,进而引发各种错误信息。本文将带您深入了解GBase 8s的锁表情况,并提供一系列有效的解决策略。
1、锁表情况
8s 锁表问题可能锁住如 表头、具体数据行等位置,不同位置的锁冲突会抛出不同错误信息,如 244: Could not do a physical-order read to fetch next row。同理都是锁冲突问题。
2、DML语句(INSERT|UPDATE|DELETE)
以 INSERT 语句举例,在开启事务情况下,执行单条插入语句。
begin work;
insert into tab1 values(1,'test');
查看当前锁状态,可以观察到存在 HDR+IX 与 HDR+X 。当该表存在 X 锁情况,在默认CR隔离级别下, 其他会话执行如 select * from tab1 就会抛出 244:Could not do a physical-order read to fetch next row。
Locks
address wtlist owner lklist type
tblsnum rowid key#/bsiz
49ca7798 0 d864d868 49ca96f0 HDR+IX
100266 0 0
49ca7820 0 d864d868 49ca7798 HDR+X
100266 103 0 I
3、查看锁表会话 SID
onstat -k 可以组合 onstat -u 定位到具体会话,不太直观,更适合技术支持同事使用。
SQL语句排查方法:
注:请使用小写表名
---设置脏读隔离界别,方便快速查看系统信息
SET ISOLATION TO DIRTY READ;
---查看 具体表 的锁情况
select username ,sid,waiter,dbsname,tabname,rowidlk,keynum,type from
sysmaster:syslocks a,sysmaster:syssessions b
where b.sid=a.owner and a.tabname ='tab1';
返回信息如下:
username gbasedbt
sid 39
waiter
dbsname mydb
tabname tab1
rowidlk 0
keynum 0
type IX
username gbasedbt
sid 39
waiter
dbsname mydb
tabname tab1
rowidlk 259
keynum 0
type X
onmode -z 39 杀掉未释放锁的会话即可;
或测试环境,如仅自己使用,检查打开的窗口,全部 commit 后再尝试。
4、锁冲突可能性
正常场景,有事务未提交状态一定会导致保持锁不释放,简单列举常见:
1. 增删改DML(INSERT | UPDATE | DELETE)
2. 创改数据库对象DDL(CREATE TABLE | ALTER TABLE)
3. TRUNCATE
4. 统计更新 UPDATE STATISTICS
5. 建索引 CREATE INDEX
简言之,大部分涉及数据库对象创建、修改与数据增删操作的语句,都会上写锁,在默认CR隔离界别 下,就可能遇到锁冲突。
5、一般推荐参数
实例级调整
数据库默认参数隔离级别为 COMMIT READ ,推荐使用 COMMITTED READ LAST COMMITTED(最后 提交读)。
查看实例参数
onstat -c|grep USELASTCOMMITTED
Your evaluation license will expire on 2024-08-13 00:00:00
# USELASTCOMMITTED - Controls the committed read isolation level.
USELASTCOMMITTED "NONE"
动态调整实例参数,设置 CR 隔离级别自动切换至 LC
onmode -wf USELASTCOMMITTED="COMMITTED READ"
Your evaluation license will expire on 2024-08-13 00:00:00
Value of USELASTCOMMITTED has been changed to COMMITTED READ.
会话级调整
如不确定 LC 隔离级别是否符合业务需求,可以单独设置会话参数,进行调试。
SET ISOLATION TO COMMITTED READ LAST COMMITTED;
例如,select语句遇到 244 报错,可以手动设置 LC 隔离界别再次尝试查询语句,查看是否继续报错。
6、存储过程 DEBUG TRACE
在想要DEBUG的部分,头尾开关trace,语句如下:
SET DEBUG FILE TO '/data/lilin/test0817/foo.trace';
trace on;
...
trace off;
可以添加类似如下文本信息方便标记跟踪位置
trace "trace LC 'insert into tab1 select * from tab1;'"
举例演示:
create procedure p1 ()
SET DEBUG FILE TO '/data/lilin/test0813/foo.trace';
trace on;
trace "trace LC 'insert into tab1 select * from tab1;'";
SET ISOLATION TO COMMITTED READ LAST COMMITTED;
--可执行
insert into tab1 select * from tab1;
trace "trace CR 'insert into tab1 select * from tab1;'";
SET ISOLATION TO COMMITTED READ;
--抛出错误
insert into tab1 select * from tab1;
trace off;
end procedure;
返回文本如下,按需直接跳到 标记文本位置即可:
trace on
trace expression :trace LC 'insert into tab1 select * from tab1;'
set isolation to ;
insert into tab1
select *
from tab1;
trace expression :trace CR 'insert into tab1 select * from tab1;'
set isolation to committed read;
insert into tab1
select *
from tab1;
exception : looking for handler
SQL error = -244 ISAM error = -107 error string = = "tab1"
exception : no appropriate handler
如果不需要跟踪子程序调用,可以使用 trace procedure ,仅跟踪调用和返回值。
锁表问题虽然棘手,但通过正确的诊断和处理方法,可以有效避免和解决。GBase 8s数据库提供了丰富的工具和参数调整选项,帮助我们更好地管理数据库锁。希望本文能为您提供实用的指导和帮助。
原文链接:https://www.gbase.cn/community/post/3915