文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

通过查询日志定位持有锁的SQL语句

2024-04-02 19:55

关注
MYSQL 版本:
mysql> select version();
+------------+
| version()  |
+------------+
| 5.6.27-log |
+------------+
1 row in set (0.00 sec)



1. 启用查询日志
mysql> SET GLOBAL general_log=1;
Query OK, 0 rows affected (0.02 sec)


mysql> show variables like 'general_log%';
+------------------+--------------------------------------------------+
| Variable_name    | Value                                            |
+------------------+--------------------------------------------------+
| general_log      | ON                                               |
| general_log_file | /app/oracle/oradata2/mysql-5.5.37/data/oradb.log |
+------------------+--------------------------------------------------+
2 rows in set (0.00 sec)


2. 查看MYSQL 线程信息
--MYSQL 线程1
mysql> show full processlist;
+----+------+-----------+------+---------+------+-------+-----------------------+
| Id | User | Host      | db   | Command | Time | State | Info                  |
+----+------+-----------+------+---------+------+-------+-----------------------+
|  1 | root | localhost | NULL | Query   |    0 | init  | show full processlist |
+----+------+-----------+------+---------+------+-------+-----------------------+
1 row in set (0.00 sec)


--MYSQL 线程2
mysql> show full processlist;
+----+------+-----------+------+---------+------+-------+-----------------------+
| Id | User | Host      | db   | Command | Time | State | Info                  |
+----+------+-----------+------+---------+------+-------+-----------------------+
|  1 | root | localhost | NULL | Sleep   |  145 |       | NULL                  |
|  2 | root | localhost | NULL | Query   |    0 | init  | show full processlist |
+----+------+-----------+------+---------+------+-------+-----------------------+
2 rows in set (0.00 sec)


--MYSQL 线程3

mysql> show full processlist;
+----+------+-----------+------+---------+------+-------+-----------------------+
| Id | User | Host      | db   | Command | Time | State | Info                  |
+----+------+-----------+------+---------+------+-------+-----------------------+
|  1 | root | localhost | NULL | Sleep   |  189 |       | NULL                  |
|  2 | root | localhost | NULL | Sleep   |   44 |       | NULL                  |
|  3 | root | localhost | NULL | Query   |    0 | init  | show full processlist |
+----+------+-----------+------+---------+------+-------+-----------------------+
3 rows in set (0.00 sec)


--MSYQL 线程4
mysql> show full processlist;
+----+------+-----------+------+---------+------+-------+-----------------------+
| Id | User | Host      | db   | Command | Time | State | Info                  |
+----+------+-----------+------+---------+------+-------+-----------------------+
|  1 | root | localhost | NULL | Sleep   |  238 |       | NULL                  |
|  2 | root | localhost | NULL | Sleep   |   93 |       | NULL                  |
|  3 | root | localhost | NULL | Sleep   |   49 |       | NULL                  |
|  4 | root | localhost | NULL | Query   |    0 | init  | show full processlist |
+----+------+-----------+------+---------+------+-------+-----------------------+
4 rows in set (0.00 sec)


--MYSQL 查询日志
[root@oradb data]# tail -f oradb.log
/app/oracle/oradata2/mysql-5.6.27/bin/mysqld, Version: 5.6.27-log (MySQL Community Server (GPL)). started with:
Tcp port: 3306  Unix socket: /tmp/mysql.sock
Time                 Id Command    Argument
161116 10:48:57     1 Query     show variables like 'general_log%'
161116 10:50:07     1 Query     show full processlist
161116 10:52:24     2 Connect   root@localhost on
                    2 Query     select @@version_comment limit 1
161116 10:52:32     2 Query     show full processlist
161116 10:53:09     3 Connect   root@localhost on
                    3 Query     select @@version_comment limit 1
161116 10:53:16     3 Query     show full processlist
161116 10:53:57     4 Connect   root@localhost on
                    4 Query     select @@version_comment limit 1
161116 10:54:05     4 Query     show full processlist


ID:表示MYSQL 线程ID


3. 使用查询日志找出持有锁造成阻塞的SQL
--MYSQL 线程1 执行更新,并且不提交事务持续持有锁
use test;
START TRANSACTION;
UPDATE t1 SET NAME='test11' WHERE id<11;

--MYSQL 线程2,被阻塞
use test;
START TRANSACTION;
UPDATE t1 SET NAME='test11' WHERE id<10;

--MYSQL 线程3,被阻塞
use test;
START TRANSACTION;
UPDATE t1 SET NAME='test11' WHERE id<9;



--查看锁阻塞信息
SELECT CONCAT('thread ',b.trx_mysql_thread_id,' from ',p.host) AS who_blocks,
       IF(p.command="Sleep",p.time,0) AS idle_in_trx,
       MAX(TIMESTAMPDIFF(SECOND,r.trx_wait_started,NOW())) AS max_wait_time,
       COUNT(*) AS num_waiters
FROM information_schema.`INNODB_LOCK_WAITS` AS w
INNER JOIN information_schema.`INNODB_TRX` AS b ON b.trx_id=w.`blocking_trx_id`
INNER JOIN information_schema.`INNODB_TRX` AS r ON r.`trx_id`= w.`requesting_trx_id`
LEFT JOIN   information_schema.`PROCESSLIST` AS p ON p.id= b.`trx_mysql_thread_id`
GROUP BY who_blocks ORDER BY num_waiters DESC\G

*************************** 1. row ***************************
   who_blocks: thread 1 from localhost
  idle_in_trx: 7
max_wait_time: 4
  num_waiters: 2
*************************** 2. row ***************************
   who_blocks: thread 2 from localhost
  idle_in_trx: 0
max_wait_time: 2
  num_waiters: 1
2 rows in set (0.11 sec)

我们看到 MSYQL 线程1 阻塞了 2 个 线程。


SELECT r.trx_id AS waiting_trx_id,r.`trx_mysql_thread_id` AS waiting_thread,
       TIMESTAMPDIFF(SECOND,r.trx_wait_started,CURRENT_TIMESTAMP) AS wait_time,
       r.`trx_query` AS waiting_query,l.`lock_table` AS waiting_table_lock,
       b.trx_id AS blocking_trx_id,b.`trx_mysql_thread_id` AS blocking_thread,
       SUBSTRING(p.host,1,INSTR(p.host,':')-1) AS blocking_host,
       SUBSTRING(p.host,INSTR(p.host,':')+1) AS blocking_port,
       IF(p.command="Sleep",p.time,0) AS idle_in_trx,
       b.`trx_query` AS blocking_query
FROM information_schema.`INNODB_LOCK_WAITS` AS w
INNER JOIN information_schema.`INNODB_TRX` AS b  ON b.trx_id=w.blocking_trx_id
INNER JOIN information_schema.`INNODB_TRX` AS r ON  r.trx_id = w.requesting_trx_id
INNER JOIN information_schema.`INNODB_LOCKS` AS l ON w.requested_lock_id=l.lock_id
LEFT JOIN information_schema.`PROCESSLIST` AS p ON p.id=b.trx_mysql_thread_id
ORDER BY wait_time DESC


*************************** 1. row ***************************
    waiting_trx_id: 17159
    waiting_thread: 2
         wait_time: 3
     waiting_query: UPDATE t1 SET NAME='test11' WHERE id<10
waiting_table_lock: `test`.`t1`
   blocking_trx_id: 17158
   blocking_thread: 1
     blocking_host:
     blocking_port: localhost
       idle_in_trx: 456
    blocking_query: NULL
*************************** 2. row ***************************
    waiting_trx_id: 17160
    waiting_thread: 3
         wait_time: 2
     waiting_query: UPDATE t1 SET NAME='test11' WHERE id<9
waiting_table_lock: `test`.`t1`
   blocking_trx_id: 17158
   blocking_thread: 1
     blocking_host:
     blocking_port: localhost
       idle_in_trx: 456
    blocking_query: NULL
*************************** 3. row ***************************
    waiting_trx_id: 17160
    waiting_thread: 3
         wait_time: 2
     waiting_query: UPDATE t1 SET NAME='test11' WHERE id<9
waiting_table_lock: `test`.`t1`
   blocking_trx_id: 17159
   blocking_thread: 2
     blocking_host:
     blocking_port: localhost
       idle_in_trx: 0
    blocking_query: UPDATE t1 SET NAME='test11' WHERE id<10
3 rows in set (0.01 sec)

等待 T1 表上的锁

--查询日志
161116 11:00:30     1 Query     SELECT DATABASE()
                    1 Init DB   test
                    1 Query     show databases
                    1 Query     show tables
                    1 Field List        t1
                    1 Query     START TRANSACTION
161116 11:00:45     2 Query     SELECT DATABASE()
                    2 Init DB   test
                    2 Query     show databases
                    2 Query     show tables
                    2 Field List        t1
                    2 Query     START TRANSACTION
161116 11:00:51     3 Query     SELECT DATABASE()
                    3 Init DB   test
                    3 Query     show databases
                    3 Query     show tables
                    3 Field List        t1
                    3 Query     START TRANSACTION
161116 11:00:54     4 Query     SELECT DATABASE()
                    4 Init DB   test
                    4 Query     show databases
                    4 Query     show tables
                    4 Field List        t1
                    4 Query     START TRANSACTION
161116 11:01:53     1 Query     UPDATE t1 SET NAME='test11' WHERE id<11
161116 11:01:56     2 Query     UPDATE t1 SET NAME='test11' WHERE id<10
161116 11:01:58     3 Query     UPDATE t1 SET NAME='test11' WHERE id<9
161116 11:02:00     4 Query     SELECT CONCAT('thread ',b.trx_mysql_thread_id,' from ',p.host) AS who_blocks,
       IF(p.command="Sleep",p.time,0) AS idle_in_trx,
       MAX(TIMESTAMPDIFF(SECOND,r.trx_wait_started,NOW())) AS max_wait_time,
       COUNT(*) AS num_waiters
FROM information_schema.`INNODB_LOCK_WAITS` AS w
INNER JOIN information_schema.`INNODB_TRX` AS b ON b.trx_id=w.`blocking_trx_id`
INNER JOIN information_schema.`INNODB_TRX` AS r ON r.`trx_id`= w.`requesting_trx_id`
LEFT JOIN   information_schema.`PROCESSLIST` AS p ON p.id= b.`trx_mysql_thread_id`
GROUP BY who_blocks ORDER BY num_waiters DESC


通过查询日志结合上面查到的锁阻塞信息可以判断是 MSYQL 线程1 执行的UPDATE t1 SET NAME='test11' WHERE id<11
语句持有锁没提交事务,阻塞了线程2、3。
从查询日志的时间上可以看出来,线程1的SQL比线程2和3的SQL先执行。
阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯