亲宝软件园·资讯

展开

MySQL锁情况查看命令

挠背小能手 人气:0

本文介绍如何在MySQL数据库中分析锁的情况及处理思路。

MySQL版本

mysql> select version();
+------------+
| version()  |
+------------+
| 5.7.38-log |
+------------+
1 row in set (0.01 sec)

模拟锁产生

A会话加锁

mysql> show create table t\G;
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `name` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> select * from t;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | s    |
|  3 | c    |
|  4 | d    |
|  5 | e    |
+----+------+
5 rows in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t where id<5 for update;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | s    |
|  3 | c    |
|  4 | d    |
+----+------+
4 rows in set (0.00 sec)

B会话插入数据,造成锁等待现象

mysql> insert into t values(0,'null');

这里介绍MySQL查看锁的3个数据字典表,分别是位于information_schema数据库下的innodb_trx、innodb_lock_waits、innodb_locks三张表,查看步骤如下:

先看innodb_trx表

mysql> use information_schema;
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> select * from innodb_trx\G;
*************************** 1. row ***************************
                    trx_id: 8553
                 trx_state: LOCK WAIT
               trx_started: 2022-12-14 16:52:29
     trx_requested_lock_id: 8553:45:3:2
          trx_wait_started: 2022-12-14 16:52:29
                trx_weight: 2
       trx_mysql_thread_id: 22
                 trx_query: insert into t values(0,'null')
       trx_operation_state: inserting
         trx_tables_in_use: 1
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           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: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
*************************** 2. row ***************************
                    trx_id: 8552
                 trx_state: RUNNING
               trx_started: 2022-12-14 16:51:39
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 2
       trx_mysql_thread_id: 20
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 5
         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: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
2 rows in set (0.00 sec)

ERROR: 
No query specified

mysql> show full processlist;
+----+--------+-----------+--------------------+---------+------+----------+--------------------------------+
| Id | User   | Host      | db                 | Command | Time | State    | Info                           |
+----+--------+-----------+--------------------+---------+------+----------+--------------------------------+
| 20 | root   | localhost | ray                | Sleep   |  132 |          | NULL                           |
| 22 | raybak | localhost | ray                | Query   |   82 | update   | insert into t values(0,'null') |
| 24 | root   | localhost | information_schema | Query   |    0 | starting | show full processlist          |
+----+--------+-----------+--------------------+---------+------+----------+--------------------------------+
3 rows in set (0.00 sec)

trx_id:唯一事务id号,本次测试中是8552和8553
trx_state:当前事务的状态,本次测试中8553是LOCK WAIT 锁等待状态
trx_wait_started:事务开始等待时间,本次测试中为2022-12-14 16:52:29
trx_mysql_thread_id:线程id,与show full processlist中的id对应,本次测试中为22
trx_query:事务运行的SQL语句,本次测试为insert into t values(0,‘null’)
trx_operation_state:事务运行的状态,本次测试为inserting

再看innodb_lock_waits表

mysql> select * from innodb_lock_waits\G;
*************************** 1. row ***************************
requesting_trx_id: 8553
requested_lock_id: 8553:45:3:2
  blocking_trx_id: 8552
 blocking_lock_id: 8552:45:3:2
1 row in set, 1 warning (0.00 sec)

requesting_trx_id:请求锁的事务id,本次测试为8553
blocking_trx_id:持有锁的事务id,也就是造成锁等待的事务id,本次测试为8552

再看innodb_locks表

mysql> select * from innodb_locks\G;
*************************** 1. row ***************************
    lock_id: 8553:45:3:2
lock_trx_id: 8553
  lock_mode: X,GAP
  lock_type: RECORD
 lock_table: `ray`.`t`
 lock_index: PRIMARY
 lock_space: 45
  lock_page: 3
   lock_rec: 2
  lock_data: 1
*************************** 2. row ***************************
    lock_id: 8552:45:3:2
lock_trx_id: 8552
  lock_mode: X
  lock_type: RECORD
 lock_table: `ray`.`t`
 lock_index: PRIMARY
 lock_space: 45
  lock_page: 3
   lock_rec: 2
  lock_data: 1
2 rows in set, 1 warning (0.00 sec)

ERROR: 
No query specified

综合三张表查询和show prcess fulllist得知,会话id 20(事务id 8552),锁住了ray.t表,锁模式是行级锁,会话id 22(事务id 8553)的insert操作需要等待会话20释放锁后才能执行,因此出现了会话id 22(事务id 8553)hang住现象。

解决方法,杀会话

mysql> kill 20;
Query OK, 0 rows affected (0.00 sec)

当然,杀会话也可以通过pt-kill工具更方便,在后续文章会对pt-kill工具做详细介绍

加载全部内容

相关教程
猜你喜欢
用户评论