有一个关于在使用 antdb 时出现“由于锁超时而取消语句”的提示。

huangapple go评论152阅读模式
英文:

There is "canceling statement due to lock timeout" prompt when I use antdb

问题

今天我在使用antdb时发现了"由于锁超时而取消语句"的提示,我该如何处理它?

英文:

I'm a new user of antdb and I always some problems while using it. Today I found there is "canceling statement due to lock timeout" prompt when I use antdb, how can I deal with it?

答案1

得分: 0

被长时间事务占用的锁未被释放,并且新的事务请求在同一对象上的锁。当lock_timeout设置的时间达到时,将报告此错误。客户端需要及时提交或回滚事务,长时间事务对数据库是一种非常耗资源的行为,请尽量避免。

--检查锁表的状态
选择locktype,relation::regclass as relation,virtualxid as vxid,transactionid as xid,virtualtransaction vxid2,pid,mode,granted from adb_locks where granted = 'f';
--查看执行时间超过5分钟的长时间事务
选择datname,pid,usename,client_addr,query,backend_startxact_startnow()-xact_start xact_durationquery_startnow()-query_start query_duration,state from adb_stat_activity where state<>$$idle$$ and now()-xact_start > interval $$5 min$$ order by xact_start;
--终止长时间事务。有两种方法如下(PID是上述SQL语句查询的pid返回值):
方法一:
SELECT adb_cancel_backend(PID);
(此方法只能终止选择查询,对于更新、删除和DML操作无效)

方法二:
SELECT adb_terminate_backend(PID);
这可以终止各种操作(选择、更新、删除、删除等)。

如果在adb_locks中没有与表相关的锁信息,则需要前往每个datanode查看是否有两个阶段的未完成事务挂在那里,查询视图:select * from adb_prepared_xacts
根据prepared字段的时间值来确定是否存在异常事务,所谓异常事务满足以下条件:

prepared字段的值显示的时间长于当前时间,例如,长于单个语句的预期执行时间。
每次查询都会一直存在一些事务。

一般来说,这些事务被视为异常事务。可以在每个节点上查询此事务的状态:select adb_xact_status(50996670);使用adb_prepared_xacts中的gid值去掉T的参数值。

如果在GTMCOORD上已经提交了事务,则需要在此节点上提交事务:commit 'T784168121'。
如果在GTMCOORD上没有提交事务,则需要在此节点上回滚事务:rollback prepared 'T784168121'。

上述操作需要在与事务对应的数据库上执行,由adb_prepared_xacts中的数据库列的值决定。

可以使用以下语句生成批量操作语句:

select 'rollback prepared '||gid||';'
from adb_prepared_xacts
where to_char(prepared,'yyyy-mm-dd hh24:mi') ='2020-01-01 14:30'
and database = 'db1';

英文:

The lock occupied by a long transaction has not been released, and a new transaction requests a lock on the same object.
This error will be reported when the time set by lock_timeout is reached.
The client needs to commit or roll back the transaction in time, and long transactions are a very resource-consuming behavior for the database, so please try to avoid them.

--Check the status of the lock table
select locktype,relation::regclass as relation,virtualxid as vxid,transactionid as xid,virtualtransaction vxid2,pid,mode,granted from adb_locks where granted = 'f';
--view long transactions that take longer than 5 minutes to execute
select datname,pid,usename,client_addr,query,backend_start,xact_start,now()-xact_start xact_duration,query_start,now()-query_start query_duration,state from adb_stat_activity where state<>$$idle$$ and now()-xact_start > interval $$5 min$$ order by xact_start;
--kill long transaction. The 2 ways are as follows (PID is the pid return value from the above sql statement query):
method one:
SELECT adb_cancel_backend(PID);
(This method can only kill select queries, and does not work for update, delete and DML)

method two:
SELECT adb_terminate_backend(PID);
This can kill off various operations (select, update, delete, drop, etc.)

If there is no lock information related to the table in adb_locks, then you need to go to each datanode to see if there are two phases of outstanding transactions hanging there, query view: select * from adb_prepared_xacts.
Based on the time value of the prepared field to determine whether there is an abnormal transaction, the so-called abnormal, meet the following conditions:

The prepared field value shows a time that is longer than the current time, for example, more than the expected execution time of a single statement.
On every query, there are always some transactions existing all the time.

In general, these transactions are considered abnormal transactions. The status of this transaction can be queried on each node: select adb_xact_status(50996670) ;, with the parameter value of T removed from the gid value in adb_prepared_xacts.

If the transaction has been committed on GTMCOORD, the transaction needs to be committed on this node: commit 'T784168121'.
If the transaction is not committed on GTMCOORD, you need to roll back the transaction on this node: rollback prepared 'T784168121'.

The above operation needs to be executed on the database corresponding to the transaction, as determined by the value of the database column in adb_prepared_xacts.

A batch operation statement can be generated with the following statement:

select 'rollback prepared '''||gid||''';' 
from adb_prepared_xacts 
where  to_char(prepared,'yyyy-mm-dd hh24:mi') ='2020-01-01 14:30'
and database = 'db1'; 

Hope it helps you.

huangapple
  • 本文由 发表于 2023年7月6日 10:36:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76625156.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定