问题描述
MySQL 偶尔会遇到执行计划不准,导致查询变慢,这时候一般会怀疑是索引信息不准,去 analyze 一下,然后再 select 试一下,这时候可能会发现,select 会进入无响应的状态,并且 analyze 的这个表上其他正常的查询都会进入无响应的状态。
解决方案
如果这种现象已经发生了,可以尝试 kill 掉“最早的”那些慢查询。
即如果 tb1 上有慢查询,且进行了 analyze 后遇到了问题,找一下 tb1 上在 analyze 之前已经开始执行,但是没结束的慢查询,然后全部 kill 掉。
问题还原
先来构造一下场景:
CREATE TABLE `stu` (
`id` int(11) NOT NULL,
`name` varchar(16) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_name` (`name`),
KEY `idx_age` (`age`),
KEY `idx_n_a` (`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
INSERT INTO `stu` VALUES (9,'adam',25),(7,'carlos',25),(1,'dave',19),(5,'sam',22),(3,'tom',22),(11,'zoe',29);
这时候来伪造一个长时间执行的慢查询:
mysql> select sleep(3600) from stu;
然后在其他的 session 模拟 analyze 和 select 的操作:
mysql> analyze table stu;
+----------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------+---------+----------+----------+
| test.stu | analyze | status | OK |
+----------+---------+----------+----------+
1 row in set (0.00 sec)
mysql> select * from stu limit 1;
这时候会发现这个 limit 1 的语句也会被阻塞,而且也不会触发innodb_lock_wait_timeo