关于查询MySQL事务阻塞信息,你还可以这样玩?

关注我们获得更多内容

关于查询MySQL事务阻塞信息,你还可以这样玩?_第1张图片


作者 | 陈龙,云和恩墨西区工程师,一线服务过金融等行业,精通 oracle 性能优化,故障诊断,特殊恢复领域 。


前言


众所周知 innodb 是支持事务型的存储引擎,在日常运维中大部分运维人员都会遇到关于 DDL 锁阻塞的情况,对于解决这类问题,有常规快速的解决方式。


那今天主要分享一个,如何去查找有关阻止事务的更多信息。


 

测试过程


测试环境:

mysql> USE test

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

 

新建测试表:

mysql> CREATE TABLE tx_albert (

    ->     id     INT PRIMARY KEY,

    ->     name   VARCHAR(20),

    ->     age    INT,

    ->     sex    CHAR(2),

    ->     city   VARCHAR(20),

    ->     job    VARCHAR(10)

    -> );

Query OK, 0 rows affected (0.24 sec)

关于查询MySQL事务阻塞信息,你还可以这样玩?_第2张图片


插入数据:

mysql> INSERT INTO tx_albert (id,name,age,sex,city,job) VALUES (1,'albert',18,'M','GuiYang','DBA');

Query OK, 1 row affected (0.01 sec)

 

mysql> INSERT INTO tx_albert (id,name,age,sex,city,job) VALUES (2,'john',24,'F','GuiYang','DEV');

Query OK, 1 row affected (0.00 sec)

关于查询MySQL事务阻塞信息,你还可以这样玩?_第3张图片

 

会话1:

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

 

mysql> UPDATE tx_albert SET name = 'Taeyeon' WHERE id = 2;

Query OK, 1 row affected (0.13 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

会话2:

mysql> UPDATE tx_albert SET name = 'Jessica' WHERE id = 2;

会话等待....

 

不同方法解读
  • 对于一般常规的做法,可以直接利用 show processlist

关于查询MySQL事务阻塞信息,你还可以这样玩?_第4张图片


如果发生了 DDL 锁阻塞,特别是表上有事务未提交的会话,利用show processlist,不便于具体定位。


当然,可以看 Command,找出 locked 的 id,然后 kill,但是这样太过于暴力,也容易会 kill 错。


备注:command列:显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)。

 

  • 当然,还有另一种方式,借助于 information_schema

mysql> select * from information_schema.innodb_locks \G

*************************** 1. row ***************************

    lock_id: 7460:26:3:5

lock_trx_id: 7460

  lock_mode: X

  lock_type: RECORD

 lock_table: `test`.`tx_albert`

 lock_index: PRIMARY

 lock_space: 26

  lock_page: 3

   lock_rec: 5

  lock_data: 2

*************************** 2. row ***************************

    lock_id: 7459:26:3:5

lock_trx_id: 7459

  lock_mode: X

  lock_type: RECORD

 lock_table: `test`.`tx_albert`

 lock_index: PRIMARY

 lock_space: 26

  lock_page: 3

   lock_rec: 5

  lock_data: 2

2 rows in set (0.00 sec)

 

mysql> SELECT * FROM information_schema.innodb_lock_waits \G

*************************** 1. row ***************************

requesting_trx_id: 7460

requested_lock_id: 7460:26:3:5

  blocking_trx_id: 7459

 blocking_lock_id: 7459:26:3:5

1 row in set (0.00 sec)

 

mysql> select * from information_schema.innodb_trx \G;

*************************** 1. row ***************************

                    trx_id: 7466

                 trx_state: LOCK WAIT

               trx_started: 2018-08-30 05:18:42

     trx_requested_lock_id: 7466:26:3:5

          trx_wait_started: 2018-08-30 05:18:42

                trx_weight: 2

       trx_mysql_thread_id: 14

                 trx_query: UPDATE tx_albert SET name = 'Jessica' WHERE id = 2

       trx_operation_state: starting index read

         trx_tables_in_use: 1

         trx_tables_locked: 1

          trx_lock_structs: 2

     trx_lock_memory_bytes: 360

           trx_rows_locked: 1

         trx_rows_modified: 0

   trx_concurrency_tickets: 0

       trx_isolation_level: REPEATABLE READ

         trx_unique_checks: 1

    trx_foreign_key_checks: 1

trx_last_foreign_key_error: NULL

 trx_adaptive_hash_latched: 0

 trx_adaptive_hash_timeout: 10000

          trx_is_read_only: 0

trx_autocommit_non_locking: 0

*************************** 2. row ***************************

                    trx_id: 7459

                 trx_state: RUNNING

               trx_started: 2018-08-30 04:45:08

     trx_requested_lock_id: NULL

          trx_wait_started: NULL

                trx_weight: 4

       trx_mysql_thread_id: 13

                 trx_query: NULL

       trx_operation_state: NULL

         trx_tables_in_use: 0

         trx_tables_locked: 0

          trx_lock_structs: 2

     trx_lock_memory_bytes: 360

           trx_rows_locked: 1

         trx_rows_modified: 2

   trx_concurrency_tickets: 0

       trx_isolation_level: REPEATABLE READ

         trx_unique_checks: 1

    trx_foreign_key_checks: 1

trx_last_foreign_key_error: NULL

 trx_adaptive_hash_latched: 0

 trx_adaptive_hash_timeout: 10000

          trx_is_read_only: 0

trx_autocommit_non_locking: 0

2 rows in set (0.10 sec)

 

从这里可以看出 trx_mysql_thread_id 14 被阻塞,以及当前正在执行的语句,而与此相联系的 trx_mysql_thread_id  13 正在运行。


通过 information_schema 关于 innodb lock 的表,可以将 kill 对象的缩减了一部分,减少了错 kill 的范围。

 

备注:

1.对于MySQL的Innodb的默认事务隔离级别是重复读(repeatable read)

2.trx_mysql_thread_id,对应着线程id

 

  • 如果想要更详细的信息,可以借助于 performance_schema

Performance Schema 主要用于监视MySQL服务器,且运行时消耗很少的性能,并进行等待事件统计。它可以把等待事件统计表按照不同的分组列(不同纬度)对等待事件相关的数据进行聚合(聚合统计数据列包括:事件发生次数,总等待时间,最小、最大、平均等待时间)

 

启用等待事件的采集功能

默认情况下等待事件的采集功能有一部分默认是禁用的,需要的时候可以通过setup_instruments和setup_objects 表动态开启:

 

例如:

如果没有开启setup_consumers,那么会出现为空

关于查询MySQL事务阻塞信息,你还可以这样玩?_第5张图片

 

设置开启也比较简单,设置为NO就可以了

mysql> UPDATE setup_consumers SET ENABLED = 'YES';

Query OK, 8 rows affected (0.00 sec)

Rows matched: 12  Changed: 8  Warnings: 0

 

mysql> select * from setup_consumers;

关于查询MySQL事务阻塞信息,你还可以这样玩?_第6张图片

 

 setup_consumers

那 setup_consumers 是什么?

先来了解一下 performance_schema 关于 setup 的表

mysql> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'performance_schema' AND TABLE_NAME LIKE 'setup%';

关于查询MySQL事务阻塞信息,你还可以这样玩?_第7张图片

 

setup表的作用


这里共有5种关于 setup 的表,下面大概简述一下其作用。

 

1)setup_actors,配置用户纬度的监控,默认监控所有用户。

关于查询MySQL事务阻塞信息,你还可以这样玩?_第8张图片

 

2)setup_consumers,配置events的消费者类型,即收集的events写入到哪些统计表中。

关于查询MySQL事务阻塞信息,你还可以这样玩?_第9张图片

 

如果没有开启,则需要进行单独启用

 

3)setup_instruments:配置具体的instrument,主要包含4大类:idle、stage/xxx、statement/xxx、wait/xxx:

关于查询MySQL事务阻塞信息,你还可以这样玩?_第10张图片

 

4)setup_objects:配置监控对象,默认对 mysql,performance_schema和information_schema中的表都不监控,而其它DB的所有表都监控。

关于查询MySQL事务阻塞信息,你还可以这样玩?_第11张图片

 

5)setup_timers:配置每种类型指令的统计时间单位。MICROSECOND表示统计单位是微妙,CYCLE表示统计单位是时钟周期,时间度量与CPU的主频有关,NANOSECOND表示统计单位是纳秒。但无论采用哪种度量单位,最终统计表中统计的时间都会装换到皮秒。(1秒=1000000000000皮秒)

关于查询MySQL事务阻塞信息,你还可以这样玩?_第12张图片


查看更多的innodb锁信息


回到刚才的话题,如何去查看更多的 innodb 锁信息

640?wx_fmt=png

 

查看线程号:

关于查询MySQL事务阻塞信息,你还可以这样玩?_第13张图片


这里,我们可以利用 performance_schema 数据库的 events_statements_history表,这个表是一个等待事件统计表,类似于 Oracle 的 v$system_event 视图。


它记录着该线程所执行过的语句,以及一些等待信息,实际上, performance_schema的events_statements_history 语句事件记录表中针对每一个语句的执行状态都记录了较为详细的信息,甚至能够记录和包含执行错误的 SQL 语句信息。

 

关于查询MySQL事务阻塞信息,你还可以这样玩?_第14张图片

 

可以看出线程33,分别执行了两次 update 语句,平均等待了51秒,而被锁定的时间为1分20秒。


TIMER_WAIT:事件已用时间,它的算法为等待的开始时间减去等待的结束时间,这段时间也即是持续时间。单位是皮秒(万亿分之一秒)


LOCK_TIME:等待表锁的时间。 此值以微秒计算,但标准化为皮秒,以便于与其他性能模式计时器进行比较。


SQL_TEXT:顾名思义就是执行SQL语句的文本。 如果是与SQL语句执行无关的命令,那么该值为NULL。 备注:可用于语句显示的最大空间为1024个字节。

 

同样也可借助于 events_waits_history 表,来查看历史的执行信息,不仅如此还可以辅助一些压测软件例如 TCPCopy,查询历史执行情况的汇总信息。

 

关于查询MySQL事务阻塞信息,你还可以这样玩?_第15张图片

 

当然,根据自己的需求,可以开启更多的记录表进行观察,这样更有助于较为详细的诊断问题。

 

原创:陈龙。

投稿:有投稿意向技术人请在公众号对话框留言。

转载:意向文章下方留言。

更多精彩请关注 “数据和云” 公众号 。


招聘专栏

云和恩墨(北京)信息技术有限公司

Oracle 售前工程师(广州、深圳、上海、武汉、北京、石家庄)

Oracle 高级工程师(上海、深圳、北京、成都、昆明、贵州、西宁)

MySQL 技术经理(上海、南京、成都)

MySQL 工程师(上海、杭州)

超高待遇:丰厚的年终奖,五险一金,高额学习基金,团建旅游,法定节假日,福利假期等。

推荐他人成功入职有好礼(iPhone X)相送 。

投递简历至邮箱:[email protected]

资源下载

关注公众号:数据和云(OraNews)回复关键字获取

2018DTCC , 数据库大会PPT

2017DTC,2017 DTC 大会 PPT

DBALIFE ,“DBA 的一天”海报

DBA04 ,DBA 手记4 电子书

122ARCH ,Oracle 12.2体系结构图

2017OOW ,Oracle OpenWorld 资料

PRELECTION ,大讲堂讲师课程资料

近期文章

仅仅使用AWR做报告? 性能优化还未入门

实战课堂:一则CPU 100%的故障分析

杨廷琨:如何编写高效SQL(含PPT)

一份高达555页的技术PPT会是什么样子?

大象起舞:用PostgreSQL解海盗分金问题

ProxySQL!像C罗一样的强大

高手过招:用SQL解决环环相扣刑侦推理问题

关于查询MySQL事务阻塞信息,你还可以这样玩?_第16张图片

你可能感兴趣的:(关于查询MySQL事务阻塞信息,你还可以这样玩?)