首先,从一些细节来描述整体情况:
也就是说,这是非常高度使用的表(每秒大约500个INSERT,许多SELECT,使用行级锁定)我正在运行DELETE查询:
CREATE TABLE `sales` (
`sale_id` int(32) unsigned NOT NULL auto_increment,
`start_time` int(20) unsigned NOT NULL,
`end_time` int(20) unsigned default NULL,
`identifier` char(9) NOT NULL,
`zip_code` char(5) NOT NULL,
`income` mediumint(6) unsigned NOT NULL,
PRIMARY KEY USING BTREE (`sale_id`),
UNIQUE KEY `SALE_DATA` (`ssn`,`zip_code`,`income`),
KEY `SALE_START` USING BTREE (`start_time`)
) ENGINE=InnoDB DEFAULT CHARSET=ascii ROW_FORMAT=FIXED
DELETE
查询看起来像这样,并且每隔五分钟在cron上运行一次(我更喜欢每分钟运行一次):
DELETE FROM `sales` WHERE
`start_time` < UNIX_TIMESTAMP(NOW() - INTERVAL 30 MINUTE);
我已经将INT
用于时间字段,因为很明显MySQL在使用DATETIME
字段的索引时遇到了麻烦。
所以这就是问题:DELETE
查询似乎在大多数情况下运行良好(可能是10次中的7次)。其他时候,查询很快完成,但MySQL似乎在一段时间后被扼杀了。我无法确切地证明它是正在运行的MySQL,但症状发生的时间肯定与运行此查询的时间一致。以下是症状,而一切都被呛到了:
SHOW FULL PROCESSLIST;
,只运行了几个INSERT INTO
个销售...
个查询,通常有一百多个查询。这里的异常实际上是流程列表中缺少任何任务,而不是存在太多任务。似乎MySQL完全停止了连接。top
中,有许多Apache进程使用大量CPU。最终,大约一两分钟后,事情就会自行恢复而不需要任何干预。 CPU使用率恢复正常,Apache和MySQL恢复正常运行。
那么,我该怎么办? :)我怎么能开始调查为什么会这样?我需要 DELETE查询由于各种原因而运行,为什么在运行时(但不是所有时间)事情都会变得疯狂?
答案 0 :(得分:3)
我想说,也许,删除时出现重新索引问题,在文档中我们可以找到“删除快速”,然后是“优化表”以尝试避免多索引合并。 / p>
另一种可能性,也就是说,删除时死锁链至少有一个其他线程,行锁可以暂停删除操作,删除操作可以暂停下一行锁。然后你有一个检测到的死锁或一个未检测到的死锁,因此发生了超时。你如何检测这种并发中止的异常?你重新运行交易吗?如果线程在同一个事务中执行了很多不同的行锁定,那么第一个死锁会影响越来越多的线程(流量堵塞)。
您是否尝试在删除交易中锁定表格?检查手册,在Innodb中锁定事务表的方式或在所有行上获得SHARE LOCK。也许你需要花一些时间才能拿到桌子,但是如果你的删除速度非常快,没有人会注意到你只为你拿了一张桌子。
现在即使您之前没有尝试过,也许删除正在做什么。检查this doc on implicit locks,您的删除查询应该使用start_time索引,所以我很确定您当前的删除不是锁定所有行(不完全确定,它们锁定已分析的行,而不仅仅是与行匹配的行)条件),但删除肯定是阻止插入。解释了具有事务执行删除的死锁的一些示例。祝好运!对我来说,了解所有锁定隔离影响为时已晚。
修改您可以尝试通过更新设置已删除= 1 来更改 DELETE ,然后执行低使用时间的真正删除(如果你有一些)。并更改客户端查询以检查此索引删除状态。