Mysql(myisam):“等待锁定”REPLACE阻止所有选择

时间:2018-01-19 10:34:17

标签: mysql myisam

我有一个MyISAM表(我无法改变它使用InnoDb,请不要暗示)这是相当大的(~20GB) 我有一个定期转储此表的工作者(我使用--skip-lock-tables选项启动)

在转储期间(需要约5分钟),可以正常运行并发选择,正如我所料。当我在转储过程中进行“REPLACE”时,这个REPLACE是“等待metadatalock”,这看起来也很正常。

但是,每个SELECT在启动后启动,REPLACE也将“等待元数据锁定”。我不明白为什么。你能帮我解决这个问题,并告诉我如何正确运行所有选择(即使在此替换之后)

谢谢!

1 个答案:

答案 0 :(得分:0)

发生的事情是:

  • 你的工人正在成长SELECTSELECT使用读锁定锁定表。顺便说一句,skip-lock-tables只表示您没有立即锁定所有表,但SELECT查询仍然单独锁定每个表。更多信息on this answer
  • 您的REPLACE正在尝试INSERT,但必须等待第一个SELECT(转储)完成以获取写锁定。它被放入写锁定队列
  • SELECT之后的每个REPLACE都放入读取锁定队列

这是the doc on table-level locking中描述的行为:

  

表更新的优先级高于表检索。因此,当释放锁定时,锁定对写入锁定队列中的请求可用,然后对读取锁定队列中的请求可用。这确保即使表的SELECT活动很多,对表的更新也不会“缺乏”。

如果您希望SELECT不等待REPLACE (从未实际测试过),请尝试替换LOW_PRIORITY修饰符。< / p>

  

如果使用LOW_PRIORITY修饰符,则INSERT的执行将延迟,直到没有其他客户端从表中读取。这包括在现有客户端正在读取时开始读取的其他客户端,以及INSERT LOW_PRIORITY语句正在等待。因此,发出INSERT LOW_PRIORITY语句的客户端可能会在读取繁重的环境中等待很长时间(甚至永远)。 (这与INSERT DELAYED相反,后者允许客户端立即继续。)

但要小心,因为如果总是有很多选择,它可能永远不会运行。

相关问题