详解通过SQL进行分布式死锁的检测与消除


当前第2页 返回上一页

事务 A 等待事务 B,需要满足 3 个条件:

1. 两个事务加锁的资源相同(同一个表、同一个分区、同一个页面或同一个元组等)。特别注意,如果事务 A 对 DN1 的 t1 表的加锁,事务 B 对 DN2 的 t1 表的加锁,则我们认为它们加锁的资源不同,只有同一节点上的同一资源才被认为是相同的资源。

2. 事务 B 已经持有锁,而事务 A 还未持有锁。

3. 事务 A 和事务 B 申请的锁的级别互斥。

通过对上一步收集到的锁信息进行处理,就可以构建出事务的等待关系。

执行附件中的示例代码 pgxc_locks_wait.sql,就可以获得等待关系:

locktype | nodename | datname  | acquire_lock_pid |  hold_lock_pid  |                           acquire_lock_event                            |                    hold_lock_event
----------+----------+----------+------------------+-----------------+-------------------------------------------------------------------------+--------------------------------------------------------
 relation | cn_5001  | postgres |  140508814374656 | 140508792350464 | usename           : tyx_1                                              +| usename           : tyx_1                             +
          |          |          |                  |                 | nspname           : public                                             +| nspname           : public                            +
          |          |          |                  |                 | relname           : t2                                                 +| relname           : t2                                +
          |          |          |                  |                 | partname          :                                                    +| partname          :                                   +
          |          |          |                  |                 | page              :                                                    +| page              :                                   +
          |          |          |                  |                 | tuple             :                                                    +| tuple             :                                   +
          |          |          |                  |                 | virtualxid        :                                                    +| virtualxid        :                                   +
          |          |          |                  |                 | transactionid     :                                                    +| transactionid     :                                   +
          |          |          |                  |                 | virtualtransaction: 11/13                                              +| virtualtransaction: 12/1323                           +
          |          |          |                  |                 | mode              : AccessShareLock                                    +| mode              : AccessExclusiveLock               +
          |          |          |                  |                 | client_addr       :                                                    +| client_addr       : ::1/128                           +
          |          |          |                  |                 | application_name  : gsql                                               +| application_name  : cn_5002                           +
          |          |          |                  |                 | xact_start        : 2020-12-25 17:18:40.478704                         +| xact_start        : 2020-12-25 17:18:54.238933        +
          |          |          |                  |                 | query_start       : 2020-12-25 17:19:23.0923                           +| query_start       : 2020-12-25 17:18:54.239319        +
          |          |          |                  |                 | state             : active                                             +| state             : idle in transaction               +
          |          |          |                  |                 | query_id          : 0                                                  +| query_id          : 0                                 +
          |          |          |                  |                 | query             : EXECUTE DIRECT ON(dn_6001_6002) 'SELECT * FROM t2';+| query             : TRUNCATE t2;                      +
          |          |          |                  |                 | ------------------------------------------------------                  | ------------------------------------------------------
 relation | cn_5002  | postgres |  140110481323776 | 140110672164608 | usename           : tyx_1                                              +| usename           : tyx_1                             +
          |          |          |                  |                 | nspname           : public                                             +| nspname           : public                            +
          |          |          |                  |                 | relname           : t1                                                 +| relname           : t1                                +
          |          |          |                  |                 | partname          :                                                    +| partname          :                                   +
          |          |          |                  |                 | page              :                                                    +| page              :                                   +
          |          |          |                  |                 | tuple             :                                                    +| tuple             :                                   +
          |          |          |                  |                 | virtualxid        :                                                    +| virtualxid        :                                   +
          |          |          |                  |                 | transactionid     :                                                    +| transactionid     :                                   +
          |          |          |                  |                 | virtualtransaction: 12/94                                              +| virtualtransaction: 9/298                             +
          |          |          |                  |                 | mode              : AccessShareLock                                    +| mode              : AccessExclusiveLock               +
          |          |          |                  |                 | client_addr       :                                                    +| client_addr       : ::1/128                           +
          |          |          |                  |                 | application_name  : gsql                                               +| application_name  : cn_5001                           +
          |          |          |                  |                 | xact_start        : 2020-12-25 17:18:54.238933                         +| xact_start        : 2020-12-25 17:18:40.478704        +
          |          |          |                  |                 | query_start       : 2020-12-25 17:19:37.715447                         +| query_start       : 2020-12-25 17:18:40.479682        +
          |          |          |                  |                 | state             : active                                             +| state             : idle in transaction               +
          |          |          |                  |                 | query_id          : 0                                                  +| query_id          : 0                                 +
          |          |          |                  |                 | query             : EXECUTE DIRECT ON(dn_6003_6004) 'SELECT * FROM t1';+| query             : TRUNCATE t1;                      +
          |          |          |                  |                 | ------------------------------------------------------                  | ------------------------------------------------------
(2 rows)

等待关系判环

构建出事务的等待关系之后,就可以通过检查等待关系是否成环,来判断当前是否有分布式死锁。

一般情况下,等待关系不会太多,通过观察就可以判断出当前有无分布式死锁。通过观察上一节中构建的等待信息,可以很容易地判断出事务 transaction1 和 transaction2 发生了循环等待,即产生了死锁。

消除死锁

上一步最终可能会找到等待关系中的一个或多个环,对于每个环,需要中止环中的一个事务,才能消除死锁。至于应该选择环中的哪个事务进行中止,需要我们从事务的重要性、已执行时间等多方面进行考虑,最终选择一个对业务影响最小的事务进行中止。

总结

通过 SQL 语句,我们可以很方便地处理分布式死锁。当我们在实际业务中遇到数据库系统 hang 住的问题时,可以借助本文提供的方法,检查 hang 问题是否是分布式死锁引起的,如果问题确实是由分布式死锁引起的,还可以通过中止某个陷入死锁的事务,来快速恢复业务。

以上就是详解通过SQL进行分布式死锁的检测与消除的详细内容,更多关于通过SQL进行分布式死锁的检测与消除的资料请关注其它相关文章!

更多SQL内容来自木庄网络博客


标签:SQL

返回前面的内容

相关阅读 >>

鲜为人知的10条sql语句优化

sql存储过程获取汉字拼音头字母函数

mysql 数据恢复的多种方法汇总

表示修改一个数据库对象的sql关键字是什么

sqlsql server的区别是什么

oracle sql性能优化系列学习一

mysql中的sql_mode模式实例详解

sql2000 全文索引完全图解

sql修改语句怎么写

sql语句创建学生表

更多相关阅读请进入《sql》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...