死锁检测不生效,加超时hint对性能是否有影响

【 使用环境 】生产环境
【 OB or 其他组件 】OB
【 使用版本 】4.2.1-8BP
【问题描述】
如图,集群已经默认开启了死锁自动检测
image

今日发生了一个死锁。锁了2.7w秒。 如图所示修改单行数据,最大响应时间2.7w秒。

查找DBA_OB_DEADLOCK_EVENT_HISTORY记录, 也未发现该表的死锁记录

我方批量修改表记录,是采用批量提交单行修改update语句进行的。例如
start;
update table set field = xxx,field2=xxx where id = 1;
update table set field = xxx,field2=xxx where id = 2;
update table set field = xxx,field2=xxx where id = 3;

update table set field = xxx,field2=xxx where id = 1000;
commit;

准备在所有update单句上加 超时hint。

update /*+ QUERY_TIMEOUT (10000000) / table set field = xxx,field2=xxx where id = 1;
update /
+ QUERY_TIMEOUT (10000000) */ table set field = xxx,field2=xxx where id = 2;

这样写对性能会有什么影响吗

你这个叫锁冲突,不是死锁

死锁是一个环,相互之间锁,你这个明显是有些事务提交异常导致行锁,后面的事务一直等待这个事务提交,这个不是死锁的场景

楼上的老师回答的是正确的,这里是锁冲突或者是锁队列,不是死锁,死锁会形成一个环,数据库检测到这个环会报异常出来,不过目前社区版 OCP 暂不支持死锁检测功能

https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002012851

一般什么情况下会导致 事务提交异常呢

一句话就能解释死锁,会话之间相互请求对方持有的资源。OB的死锁检测还是有用的,能解决这个场景。你这2.7W秒明显是超时时间设置的太大,其实可以用hint来实现也不会有啥性能问题

单行update语句, 想不到,除了等待另一方update结束拿锁。 还有啥情况会导致超时2.7w秒。

大概率就是另外个会话修改了数据没有提交啊,可以找下当时的trace日志,里面会打印相关信息

grep “conflict” observer.log|grep “-6005” 可以根据这些关键字查询observer日志,确定当时阻塞的源头在哪里,在根据源头定位事务未提交的原因,过滤的日志中会打印那个会话阻塞了那个会话

2 个赞

:+1:

select
/+QUERY_TIMEOUT(3600000000) read_consistency(weak)/
b.TRANS_ID,
case
WHEN b.TYPE = ‘TM’ THEN ‘表锁’
WHEN b.TYPE = ‘TX’ THEN ‘事务锁’
WHEN b.TYPE = ‘TR’ THEN ‘行锁’
ELSE NULL
END
AS lock_type,
ID1,
LMODE,
CASE
WHEN BLOCK = 0 THEN ‘该事务持有锁’
WHEN BLOCK = 1 THEN ‘该事务被阻塞’
ELSE NULL
END
as BLOCK,
a.SVR_IP,
ID,
user,
command,
time,
total_time,
STATE,
info,
retry_cnt,
retry_info,
thread_id,
trace_id
from
gv$ob_processlist a,
GV$OB_LOCKS b,
CDB_ob_table_locations c
where
a.trans_id = b.trans_id
and c.table_name = ‘表名称’
and (
ID1 like concat(’%’ , c.table_id, ‘%’)
OR ID1 like concat(’%’ , c.tablet_id ,’%’)
); 可以根据这个语句监控一下是否存在锁的问题,在SYS租户下面执行

2 个赞