这篇文章上次修改于 593 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

在 MySQL 中,可以使用以下命令查看哪些进程被锁住了:

# 查看所有进程
show full processlist;

# 查询是否锁表
show OPEN TABLES where In_use > 0;

# 查看被锁住的
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

查看所有进程

show full processlist; 命令将显示所有当前正在运行的 MySQL 进程。

查询是否锁表

show OPEN TABLES where In_use > 0; 命令将显示所有正在使用的表。如果一个表的 In_use 值大于 0,则表示该表被锁住了。

查看被锁住的

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; 命令将显示所有 MySQL 表上的锁。

示例

假设我们有一个名为 test 的数据库,其中有一个名为 user 的表。如果我们使用 INSERT 语句向 user 表插入一条记录,则会锁住该表。

INSERT INTO user (name, age) VALUES ('John Doe', 30);

使用 show full processlist; 命令查看所有进程,可以看到如下结果:

+----+------+-----------+------------+----------------+----------------+-------------+----------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------------+----------------+----------------+-------------+----------------+
| 1 | root | localhost | test | Query | 00:00:00 | Waiting | INSERT INTO user (name, age) VALUES ('John Doe', 30); |
+----+------+-----------+------------+----------------+----------------+-------------+----------------+

使用 show OPEN TABLES where In_use > 0; 命令查看是否锁表,可以看到如下结果:

+------+------+-------+--------+--------+
| Id | Name | In_use | Type | Tables |
+------+------+-------+--------+--------+
| 1 | user | 1 | TEMPORARY | user |
+------+------+-------+--------+--------+

使用 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; 命令查看被锁住的,可以看到如下结果:

+----------+-----------+-----------+-----------+-----------+-----------+
| lock_id | lock_type | lock_mode | object_id | object_schema | object_name |
+----------+-----------+-----------+-----------+-----------+-----------+
| 228588 | IX | X | 17 | test | user |
+----------+-----------+-----------+-----------+-----------+-----------+

从结果可以看到,进程 ID 为 1 正在对表 user 进行写锁。

解决锁表问题

如果发现数据库出现锁表问题,可以尝试以下方法解决:

  • 查找并解决导致锁表的 SQL 语句。
  • 如果锁表是由于死锁引起的,可以尝试杀掉其中一个导致死锁的进程。
  • 如果锁表是由于数据库资源不足引起的,可以考虑增加数据库的资源。

注意

在杀掉导致锁表的进程之前,请确保该进程不再需要锁定的资源。否则,可能会导致数据丢失或文件损坏。