我有一个跳过表(我不能将其更改为使用InnoDb,请不要建议这样做),它非常大(~20 it ),我有一个工作人员定期转储这个表(我启动时使用-- MyISAM -lock-tables选项)
在转储期间(大约需要5分钟),可以正确地运行并发select,正如我所期望的那样。当我在转储过程中进行“替换”时,这个替换是“等待metadatalock”,这似乎也很正常。
但是,每次在替换开始后启动的SELECT也将是“等待元数据锁定”。我不明白为什么。你能在这方面帮助我,并告诉我如何才能让所有的选择正确运行(即使在这个替换之后)
谢谢!
发布于 2018-01-19 20:19:56
正在发生的情况是:
SELECT。SELECT正在使用读锁定来锁定表。顺便说一句,skip-lock-tables只是意味着您不会一次锁定所有表,但是SELECT查询仍然会单独锁定每个表。更多信息on this answer.REPLACE正在尝试INSERT,但必须等待第一个SELECT (转储)完成才能获得写锁定。将其放入写锁定队列中。在将SELECT放入读锁定队列之后,SELECT。这是在the doc on table-level locking中描述的行为
表更新比表检索具有更高的优先级。因此,当锁被释放时,该锁对写锁队列中的请求可用,然后对读锁队列中的请求可用。这确保了即使在表有大量SELECT活动时,对表的更新也不会“匮乏”。
如果您希望SELECT不等待REPLACE,您可以(实际上从未测试过)在您的替换项上尝试LOW_PRIORITY修饰符。
如果您使用LOW_PRIORITY修饰符,则INSERT的执行将被延迟,直到没有其他客户端正在从表中读取数据。这包括在现有客户端读取和INSERT LOW_PRIORITY语句等待时开始读取的其他客户端。因此,发出INSERT LOW_PRIORITY语句的客户端可能会在读取繁重的环境中等待很长时间(甚至永远)。(这与INSERT DELAYED形成对比,后者允许客户端立即继续。)
但是要小心,因为如果总是有很多select操作,它可能永远不会运行。
https://stackoverflow.com/questions/48339069
复制相似问题