MySQL 问题汇总
# 锁超时
当出现 Lock wait timeout exceeded; try restarting transaction
,可以通过以下 SQL 来排查:
查看 InnoDB 存储引擎内部状态信息的命令,它可以提供非常详细的关于 InnoDB 存储引擎的运行状态、性能指标以及当前存在的问题等信息
SHOW ENGINE INNODB STATUS;
1内容包括
事物信息
,锁信息
,缓冲池信息
,日志信息
,表空间信息
,当程序发生以上报错信息,使用该语句,可以查看到相关报错信息。查看当前被锁定或正在使用的表的命令。它能帮助你识别哪些表正在被事务或查询占用,从而排查锁等待、死锁等问题
SHOW OPEN TABLES WHERE In_use > 0; # 示例 +----------+-------------+--------+-------------+ | Database | Table | In_use | Name_locked | +----------+-------------+--------+-------------+ | mydb | orders | 2 | 0 | | mydb | customers | 1 | 0 | +----------+-------------+--------+-------------+ * orders 表被锁定 2 次(可能有两个并发事务在操作它)。 * customers 表被锁定 1 次。 * 两个表的名称均未被锁定(Name_locked=0),可正常进行 DML 操作。
1
2
3
4
5
6
7
8
9
10
11- Database 表所在的数据库名称。
- Table 表的名称。
- In_use 表示当前正在使用的连接数。
- Name_locked 表示当前表是否被锁定。
看当前正在执行操作的线程(即非空闲连接)的 SQL 查询。它能帮助你监控数据库中活跃的查询和事务,排查性能问题或长时间运行的任务。
SELECT * FROM information_schema.PROCESSLIST WHERE Command != 'Sleep'; # 示例 +-------+------+-------------------+--------+---------+------+------------------+----------------------------------+ | ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO | +-------+------+-------------------+--------+---------+------+------------------+----------------------------------+ | 12345 | root | localhost | mydb | Query | 120 | Sorting result | SELECT * FROM orders ORDER BY id | | 12346 | app | 192.168.1.1:56789 | mydb | Execute | 5 | Sending data | UPDATE users SET status=1 WHERE id=100 | +-------+------+-----------+--------+---------+------+------------------+----------------------------------+ * 线程 12345:用户 root 在执行 SELECT 查询,已运行 120 秒,正在排序结果(可能需要优化索引)。 * 线程 12346:应用用户 app 在执行 UPDATE,运行 5 秒,正在返回数据。
1
2
3
4
5
6
7
8
9
10- ID 线程 ID(唯一标识),用于 KILL 命令终止线程(如 KILL 12345;)。
- USER 执行该线程的用户(如 root、app_user)。
- HOST 客户端主机名或 IP 地址(如 localhost、192.168.1.1:56789)。
- DB 当前线程操作的数据库名(若未指定则为 NULL)。
- COMMAND 线程当前执行的命令类型:・Query:正在执行 SQL 查询。・Sleep:空闲等待。・Connect:正在连接数据库。・Execute:正在执行预处理语句。
- TIME 线程已持续执行的时间(秒)。若值很大,可能是慢查询或事务未提交。
- STATE 线程当前状态(如 Sorting result、Copying to tmp table),指示查询执行到哪一步。
- INFO 正在执行的 SQL 语句(可能被截断,使用 SHOW FULL PROCESSLIST 可查看完整语句)。
SELECT * FROM information_schema.PROCESSLIST WHERE Command != 'Sleep';
语句能方便的看到当前有哪个 sql 正在占有锁,可以看他的执行时间,如果太长,需要考虑是否优化,也可以立马 kill 这个线程,如果 kill 不起作用,需要重启 mysql。
上次更新: 6/11/2025, 4:10:30 PM