mysql5.7查看谁持有表级锁

测试环境

centos7.4+mysql5.7.29

启用 performance_schema

mysql> show variables like ‘%performance%’
±---------------------------------------------------------±------+
| Variable_name | Value |
±---------------------------------------------------------±------+
| performance_schema | ON
说明:默认情况下performance_schema 在5.7下是启用的,这里最好对setup_instruments采集器配置项和setup_consumers表中的配置项进行启用
mysql> update setup_instruments set enabled=‘YES’,TIMED=‘YES’ where name like ‘%wait%’;
Query OK, 316 rows affected (0.01 sec)
Rows matched: 370 Changed: 316 Warnings: 0

mysql> desc setup_consumers;
±--------±-----------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±--------±-----------------±-----±----±--------±------+
| NAME | varchar(64) | NO | | NULL | |
| ENABLED | enum(‘YES’,‘NO’) | NO | | NULL | |
±--------±-----------------±-----±----±--------±------+

mysql> update setup_consumers set enabled=‘YES’ where name like ‘%wait%’;
Query OK, 3 rows affected (0.00 sec)

mysql> select * from setup_consumers where name like ‘%wait%’ ;
±--------------------------±--------+
| NAME | ENABLED |
±--------------------------±--------+
| events_waits_current | YES |
| events_waits_history | YES |
| events_waits_history_long | YES |
±--------------------------±--------+

测试场景

1、通过一个会话对表执行 lock table操作
2、通过另一个会话对该进行更新
3、查看哪个会话持有表级锁

mysql> lock table aa read;
mysql> select connection_id();
±----------------+
| connection_id() |
±----------------+
| 7 |

会话2
mysql> select connection_id();
±----------------+
| connection_id() |
±----------------+
| 5 |
mysql> update aa set col3=4 where col1>800;

解决思路与方法

1、通过show processlist查看表锁信息

mysql> show processlist;
+----+-----------------+-----------+--------------------+---------+------+---------------------------------+-------------------------------------+
| Id | User            | Host      | db                 | Command | Time | State                           | Info                                |
+----+-----------------+-----------+--------------------+---------+------+---------------------------------+-------------------------------------+
|  1 | event_scheduler | localhost | NULL               | Daemon  | 2938 | Waiting on empty queue          | NULL                                |
|  5 | root            | localhost | test               | Query   |  497 | Waiting for table metadata lock | update aa set col3=4 where col1>900 |
|  6 | root            | localhost | performance_schema | Query   |    0 | starting                        | show processlist                    |
|  7 | root            | localhost | test               | Sleep   |  510 |                                 | NULL                                |
+----+-----------------+-----------+--------------------+---------+------+---------------------------------+-------------------------------------+

测试环境只有几条记录,所以很容易就是知道是哪个会话持有了表级锁,这里应该是会话7,但在生产环境中就不一定了,
2、通过查询事务无法获取到server层面相应信息,
mysql> select * from information_schema.innodb_trx;
mysql> select * from information_schema.innodb_locks;
mysql> select * from information_schema.innodb_lock_waits;

mysql> select * from performance_schema.metadata_locks \G;
Empty set (0.00 sec)

ERROR:
No query specified

这里没有信息输出是因为没有开启setup_instruments和setup_consumers相应的参数导致的

3、查询metadata_locks 信息
select * from performance_schema.metadata_locks where owner_thread_id !=sys.ps_thread_id(connection_id()) \G

*************************** 1. row ***************************
          OBJECT_TYPE: TABLE
        OBJECT_SCHEMA: test
          OBJECT_NAME: aa
OBJECT_INSTANCE_BEGIN: 139975879812688
            LOCK_TYPE: SHARED_READ_ONLY
        LOCK_DURATION: TRANSACTION
          LOCK_STATUS: GRANTED
               SOURCE: 
      OWNER_THREAD_ID: 32
       OWNER_EVENT_ID: 418
*************************** 2. row ***************************
          OBJECT_TYPE: GLOBAL
        OBJECT_SCHEMA: NULL
          OBJECT_NAME: NULL
OBJECT_INSTANCE_BEGIN: 139975668677024
            LOCK_TYPE: INTENTION_EXCLUSIVE
        LOCK_DURATION: STATEMENT
          LOCK_STATUS: GRANTED
               SOURCE: 
      OWNER_THREAD_ID: 30
       OWNER_EVENT_ID: 36
*************************** 3. row ***************************
          OBJECT_TYPE: TABLE
        OBJECT_SCHEMA: test
          OBJECT_NAME: aa
OBJECT_INSTANCE_BEGIN: 139975668591216
            LOCK_TYPE: SHARED_WRITE
        LOCK_DURATION: TRANSACTION
          LOCK_STATUS: PENDING
               SOURCE: 
      OWNER_THREAD_ID: 30
       OWNER_EVENT_ID: 36
3 rows in set (0.10 sec)

说明:在metadata_locks中能看到元数据锁类型、表信息,但无法看到相应的SQL语句

4、通过table_handles查看表中的锁

mysql> select * from performance_schema.table_handles;
+-------------+---------------+-------------+-----------------------+-----------------+----------------+---------------+---------------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | OBJECT_INSTANCE_BEGIN | OWNER_THREAD_ID | OWNER_EVENT_ID | INTERNAL_LOCK | EXTERNAL_LOCK |
+-------------+---------------+-------------+-----------------------+-----------------+----------------+---------------+---------------+
| TABLE       | test          | Sheet1      |       139975869924496 |               0 |              0 | NULL          | NULL          |
| TABLE       | test          | aa          |       139975869990688 |               0 |              0 | NULL          | NULL          |
| TABLE       | test          | bb          |       139975870002256 |               0 |              0 | NULL          | NULL          |
*******************************
| TABLE       | test          | yjgk        |       139975668759360 |               0 |              0 | NULL          | NULL          |
| TABLE       | test          | Sheet1      |       139975870007520 |               0 |              0 | NULL          | NULL          |
| TABLE       | test          | aa          |       139975869907936 |              32 |            420 | NULL          | READ EXTERNAL |
| TABLE       | test          | bb          |       139975869914368 |               0 |              0 | NULL          | NULL          |
***************
| TABLE       | test          | user        |       139975879937840 |               0 |              0 | NULL          | NULL          |
| TABLE       | test          | yjgk        |       139975879947648 |               0 |              0 | NULL          | NULL          |
+-------------+---------------+-------------+-----------------------+-----------------+----------------+---------------+--------------

5、查看events_statements_current 执行的SQL语句

mysql> select * from performance_schema.events_statements_current \G;
*************************** 1. row ***************************
THREAD_ID: 30
EVENT_ID: 30
END_EVENT_ID: NULL
EVENT_NAME: statement/sql/update
SOURCE:
TIMER_START: 2451892308210000
TIMER_END: 2856840026831000
TIMER_WAIT: 404947718621000
LOCK_TIME: 0
SQL_TEXT: update aa set col3=4 where col1>900
DIGEST: NULL
DIGEST_TEXT: NULL
CURRENT_SCHEMA: test
OBJECT_TYPE: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL OBJECT_INSTANCE_BEGIN: NULL
MYSQL_ERRNO: 0
RETURNED_SQLSTATE: NULL
MESSAGE_TEXT: NULL
ERRORS: 0
WARNINGS: 0
ROWS_AFFECTED: 0
ROWS_SENT: 0
ROWS_EXAMINED: 0 CREATED_TMP_DISK_TABLES: 0
CREATED_TMP_TABLES: 0
SELECT_FULL_JOIN: 0 SELECT_FULL_RANGE_JOIN: 0
SELECT_RANGE: 0
SELECT_RANGE_CHECK: 0
SELECT_SCAN: 0
SORT_MERGE_PASSES: 0
SORT_RANGE: 0
SORT_ROWS: 0
SORT_SCAN: 0
NO_INDEX_USED: 0
NO_GOOD_INDEX_USED: 0
NESTING_EVENT_ID: NULL
NESTING_EVENT_TYPE: NULL
NESTING_EVENT_LEVEL: 0
*************************** 2. row ***************************
THREAD_ID: 31
EVENT_ID: 457
END_EVENT_ID: NULL
EVENT_NAME: statement/sql/select
SOURCE:
TIMER_START: 2856839656572000
TIMER_END: 2856840058364000
TIMER_WAIT: 401792000
LOCK_TIME: 230000000
SQL_TEXT: select * from performance_schema.events_statements_current
DIGEST: NULL
DIGEST_TEXT: NULL
CURRENT_SCHEMA: performance_schema
OBJECT_TYPE: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL OBJECT_INSTANCE_BEGIN: NULL
MYSQL_ERRNO: 0
RETURNED_SQLSTATE: NULL
MESSAGE_TEXT: NULL
ERRORS: 0 ………………………………………………………………………………
NO_GOOD_INDEX_USED: 0
NESTING_EVENT_ID: NULL
NESTING_EVENT_TYPE: NULL
NESTING_EVENT_LEVEL: 0
*************************** 3. row ***************************
THREAD_ID: 32
EVENT_ID: 412
END_EVENT_ID: 429
EVENT_NAME: statement/sql/lock_tables
SOURCE:
TIMER_START: 2438691100503000
TIMER_END: 2438691297187000
TIMER_WAIT: 196684000
LOCK_TIME: 123000000
SQL_TEXT: lock table aa read
DIGEST: 0c4323e259b6706bec0bcc2870e4c3c8
DIGEST_TEXT: LOCK TABLE aa READ
CURRENT_SCHEMA: test
OBJECT_TYPE: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL OBJECT_INSTANCE_BEGIN: NULL
MYSQL_ERRNO: 0
RETURNED_SQLSTATE: 00000
MESSAGE_TEXT: NULL
ERRORS: 0
WARNINGS: 0
ROWS_AFFECTED: 0
ROWS_SENT: 0
ROWS_EXAMINED: 0 CREATED_TMP_DISK_TABLES: 0
CREATED_TMP_TABLES: 0
SELECT_FULL_JOIN: 0 SELECT_FULL_RANGE_JOIN: 0
SELECT_RANGE: 0
SELECT_RANGE_CHECK: 0
SELECT_SCAN: 0
SORT_MERGE_PASSES: 0
SORT_RANGE: 0
SORT_ROWS: 0
SORT_SCAN: 0
NO_INDEX_USED: 0
NO_GOOD_INDEX_USED: 0
NESTING_EVENT_ID: NULL
NESTING_EVENT_TYPE: NULL
NESTING_EVENT_LEVEL: 0 3 rows in set (0.01 sec)

ERROR: No query specified

说明:这里就能看到那个thread_id执行了什么SQL语句,根据thread_id查看processlist_id
mysql> select processlist_id from performance_schema.threads where thread_id=32;
±---------------+
| processlist_id |
±---------------+
| 7 |
±---------------+
1 row in set (0.00 sec)


mysql> show processlist;
+----+-----------------+-----------+--------------------+---------+------+---------------------------------+-------------------------------------+
| Id | User            | Host      | db                 | Command | Time | State                           | Info                                |
+----+-----------------+-----------+--------------------+---------+------+---------------------------------+-------------------------------------+
|  1 | event_scheduler | localhost | NULL               | Daemon  | 2938 | Waiting on empty queue          | NULL                                |
|  5 | root            | localhost | test               | Query   |  497 | Waiting for table metadata lock | update aa set col3=4 where col1>900 |
|  6 | root            | localhost | performance_schema | Query   |    0 | starting                        | show processlist                    |
|  7 | root            | localhost | test               | Sleep   |  510 |                                 | NULL                                |
+----+-----------------+-----------+--------------------+---------+------+---------------------------------+-------------------------------------+

4 rows in set (0.00 sec)
6、与研发人员确认相应的SQL后,kill掉相应的线程ID即可
mysql> kill 7;
Query OK, 0 rows affected (0.00 sec)

mysql> show processlist;
+----+-----------------+-----------+--------------------+---------+------+------------------------+------------------+
| Id | User            | Host      | db                 | Command | Time | State                  | Info             |
+----+-----------------+-----------+--------------------+---------+------+------------------------+------------------+
|  1 | event_scheduler | localhost | NULL               | Daemon  | 2953 | Waiting on empty queue | NULL             |
|  5 | root            | localhost | test               | Sleep   |  512 |                        | NULL             |
|  6 | root            | localhost | performance_schema | Query   |    0 | starting               | show processlist |
+----+-----------------+-----------+--------------------+---------+------+------------------------+------------------+
3 rows in set (0.00 sec)

总结

1、通过show processlist方式无法直接了解到是那个会话持有表级锁
2、通过metadata_locks 可以了解到元数据锁的相关信息和表信息
3、通过table_handles可以查询到表上具体的信息
4、通过events_statements_current根据时间先后可以知道每 个线程当前执行的SQL语句
5、根据events_statements_current中的thread_id在threads中能查询具体的线程ID,这就与show processlist中process_id相应起来。

猜你喜欢

转载自blog.csdn.net/weixin_41561946/article/details/108565024
今日推荐