MySql - 死锁「pt-deadlock-logger」

线上遇见死锁可以第一时间使用 show engine innodb status 命令来获取最近一次的死锁信息.

MySQL 提供了一套 InnoDB 的监控机制,用于周期性(每隔 15s)输出 InnoDB 的运行状态到 Mysqld 服务的标准错误输出 (stderr)。默认情况下监控是关闭的,只有当需要分析问题的时候才会开启,并且在分析问题之后,建议将监控关闭,因为他对数据库的性能有一定的影响,另外每 15 s 输出一次日志,会使日志文件变得特别大。

InnoDB 的监控主要分四种:

  • 标准监控(Standard InnoDB Monitor)
  • 锁监控(InnoDB Lock Monitor)
  • 表空间监控(InnoDB Tablespace Monitor)
  • 表监控(InnoDB Table Monitor)

后面两种监控基本上废弃了,关于各种监控的作用可以参考 MySQL 的官方文档 。
要获取死锁日志,我们需要开启 InnoDB 的标准监控,推荐将锁监控也打开,它可以提供一些额外的锁信息,在分析死锁问题时会很有用。



一、如何开启锁监控 🔓

在 MySQL 5.6.16 之后,可以通过设置系统参数来开启锁监控,如下:

-- 开启标准监控
set global innodb_status_output=ON;

-- 关闭标准监控
set global innodb_status_output=OFF;

-- 开启锁监控
set global inndb_status_output_locks=ON;

-- 关闭锁监控
set global inndb_status_output_locks=OFF;

另外, MySQL 还提供了一个系统参数 innodb_print_all_deadlocks专门用于记录死锁日志,当发生死锁时,死锁日志会记录到 MySQL 的错误日志文件中。

set global innodb_print_all_deadlocks=ON;

除了 MySQL 自带的监控机制,还有一些监控工具也很用,例如 Innotop 和 Percona Toolkit 里面的小工具 pt-deadlock-logger


二、利用 pt-deadlock-logger 设置 & 查看死锁

1、下载安装:

$ wget percona.com/get/pt-deadlock-logger

设置软连接

$ ln -s /opt/pt-deadlock-logger /usr/bin

2、基础语法

$ pt-deadlock-logger [OPTIONS] DSN

3、创建选项

在这里插入图片描述

4、日常执行 pt-deadlock-logger
  • 首先需要创建一张 deadlocks 的表来存储死锁信息
CREATE TABLE kvalitadog.deadlocks
(
    server    char(20)          NOT NULL COMMENT '发生死锁的 MySQL 实例,IP:PORT 标识',
    ts        timestamp         NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发生死锁的时间',
    thread    int UNSIGNED      NOT NULL COMMENT '该事务所属的线程ID,及应用端连接的会话ID 信息',
    txn_id    bigint UNSIGNED   NOT NULL COMMENT '事务ID',
    txn_time  smallint UNSIGNED NOT NULL COMMENT '事务执行时间',
    user      char(16)          NOT NULL COMMENT '应用连接的用户',
    hostname  char(20)          NOT NULL COMMENT '应用端 hostname 名',
    ip        char(15)          NOT NULL COMMENT '应用端 ip 地址', -- alternatively, ip int unsigned NOT NULL
    db        char(64)          NOT NULL COMMENT '事务语句所在的 database',
    tbl       char(64)          NOT NULL COMMENT '事务关联的表',
    idx       char(64)          NOT NULL COMMENT '使用的索引信息',
    lock_type char(16)          NOT NULL COMMENT '当前事务语句持有锁的类型',
    lock_mode char(1)           NOT NULL COMMENT '引起死锁的锁模式(S,X 等)',
    wait_hold char(1)           NOT NULL COMMENT '该事务是否在等待锁(w) 还是在持有锁(h)',
    victim    tinyint UNSIGNED  NOT NULL COMMENT '1 表示该事务被回滚',
    query     text              NOT NULL COMMENT '事务的 sql 语句(注:innodb status 只显示该事务中最后更新的一条 sql,如果一个事务有多条更新语句,之前的 sql 不会显示出来)',
    PRIMARY KEY (server, ts, thread)
) ENGINE = InnoDB;
  • 开启死锁进程监控
$ ./pt-deadlock-logger h=172.16.06.05,P=3306,u=root,p=root --dest h=172.16.06.05,P=3306,D=test,t=deadlocks,u=root,p=root
  • deadlock 表记录信息
mysql> select * from deadlocks;

+-----------+---------------------+--------+--------+----------+---------+----------+----------------+------------+---------+---------+-----------+-----------+-----------+--------+----------------------------------------------------------------------------------------+
| server    | ts                  | thread | txn_id | txn_time | user    | hostname | ip             | db         | tbl     | idx     | lock_type | lock_mode | wait_hold | victim | query                                                                                  |
+-----------+---------------------+--------+--------+----------+---------+----------+----------------+------------+---------+---------+-----------+-----------+-----------+--------+----------------------------------------------------------------------------------------+
| 127.0.0.1 | 2021-08-26 21:07:52 |    106 |      0 |      142 | beanbag |          | 115.236.000.00 | dmeo       | demo_tt | PRIMARY | RECORD    | X         | w         |      1 | /* ApplicationName=DataGrip 2020.2.3 */ UPDATE demo_tt SET `desc`='222222' WHERE id =2 |
| 127.0.0.1 | 2021-08-26 21:07:52 |    107 |      0 |      140 | beanbag |          | 115.236.000.00 | dmeo       | demo_tt | PRIMARY | RECORD    | X         | w         |      0 | /* ApplicationName=DataGrip 2020.2.3 */ UPDATE demo_tt SET `desc`='111111' WHERE id =1 |
+-----------+---------------------+--------+--------+----------+---------+----------+----------------+------------+---------+---------+-----------+-----------+-----------+--------+----------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值