mysql(myisam):“等待锁”替换阻塞所有选择

tzcvj98z  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(283)

我有一个myisam表(我不能将其更改为使用innodb,请不要建议这样做),它相当大(约20gb),我有一个worker定期转储这个表(我启动时使用--skip lock tables选项)
在转储期间(大约需要5分钟),concurrent select可以正确运行,正如我所期望的那样。当我在转储过程中执行“replace”时,这个替换就是“waitingformetadatalock”,这看起来也很正常。
但是,每次选择启动后,替换也会被“等待元数据锁定”。我不明白为什么。你能帮我一下吗,告诉我怎样才能正确运行所有的选择(即使在这个替换之后)
谢谢!

gajydyqb

gajydyqb1#

正在发生的是:
你的工人赚了一大笔钱 SELECT . 这个 SELECT 正在用读取锁锁定表。顺便说一下 skip-lock-tables 这只意味着您没有同时锁定所有表,而是 SELECT 查询仍在分别锁定每个表。有关此答案的详细信息。
你的 REPLACE 是在试图 INSERT 但必须等待第一次 SELECT (转储)完成以获得写锁。它被放入写锁队列。
SELECT 之后 REPLACE 被放入读锁队列。
这是表级锁定文档中描述的行为:
表更新的优先级高于表检索。因此,当释放锁时,该锁将对写锁队列中的请求可用,然后对读锁队列中的请求可用。这确保了即使在表有大量的select活动时,对表的更新也不会“饥饿”。
如果你想要 SELECT 不等待 REPLACE 你可以(从来没有真正测试过)试试 LOW_PRIORITY 替换上的修饰符。
如果使用低优先级修饰符,插入的执行将延迟,直到没有其他客户机从表中读取为止。这包括在现有客户机正在读取以及insert low\ U priority语句正在等待时开始读取的其他客户机。因此,对于发出insert low\u priority语句的客户机来说,有可能在读量大的环境中等待很长时间(甚至永远)(这与insert delayed相反,后者允许客户机立即继续。)
但是要小心,因为如果总是有很多select,它可能永远不会运行。

相关问题