【问题标题】:Mysql (myisam) : "waiting for lock" REPLACE blocking all selectsMysql (myisam) : "waiting for lock" REPLACE 阻塞所有选择
【发布时间】:2018-01-19 10:34:16
【问题描述】:

我有一个 MyISAM 表(我无法将其更改为使用 InnoDb,请不要建议),它非常大(~20GB) 我有一个定期转储此表的工作人员(我使用 --skip-lock-tables 选项启动)

在转储期间(大约需要 5 分钟),并发选择可以正确运行,正如我所料。当我在转储期间执行“REPLACE”时,此 REPLACE 正在“等待元数据锁”,这似乎也很正常。

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

谢谢!

【问题讨论】:

    标签: mysql myisam


    【解决方案1】:

    正在发生的事情是:

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

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

    表更新的优先级高于表检索。因此,当一个锁被释放时,锁对写锁队列中的请求可用,然后对读锁队列中的请求可用。这确保了即使在表的 SELECT 活动繁重时,对表的更新也不会“饿死”。

    如果您希望 SELECT 不等待 REPLACE可以(从未实际测试过)尝试在您的替换上使用 LOW_PRIORITY 修饰符。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 2015-05-05
      • 2013-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      相关资源
      最近更新 更多