在 MySQL 8.0.33 上,我遇到了一种文档未解释的争用形式(在多个实例上重现)。
例如:
- 我启动一个实例
- 在控制台客户端上,我在一个相对较大的表上调用 a
SELECT COUNT(*)
(几 GB 的总记录+索引) ANALYZE TABLE
在一个单独的客户端上,我在一个单独的、较小的表上调用
结果是第二条语句(ANALYZE TABLE
)挂起一段时间,处于阻塞状态System Lock
;这是一个示例输出:
+----+--------+------+-------+---------+------+-------------+---------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+--------+------+-------+---------+------+-------------+---------------------------------+
| 18 | _user_ | _ip_ | _db_ | Query | 72 | executing | SELECT COUNT(*) FROM _table_1_ |
| 32 | _user_ | _ip_ | _db_ | Query | 45 | System lock | ANALYZE TABLE _table_2_ |
+----+--------+------+-------+---------+------+-------------+---------------------------------+
根据文档(此处和此处),MySQL 似乎在对第一个 ( ) 表的记录进行分页时锁定(至少)两个表SELECT
。
究竟是什么导致 MySQL 在对一个表执行 SELECT 时锁定多个表?
https://dev.mysql.com/doc/refman/8.0/en/analyze-table.html说:
从 5.6.6 开始,innodb_stats_auto_recalc 和持久统计实际上消除了对
ANALYZE TABLE
.我建议你避免这样做
ANALYZE
。如果您仍然觉得需要这样,请提供它有帮助的查询以及SHOW CREATE TABLE
。可能有一个可行的解决方法。