当仍然需要实时SELECT查询时,MySQL锁定处理大型LOAD DATA INFILE

时间:2011-02-21 22:58:25

标签: mysql locking load-data-infile

寻求一些帮助和建议,请来自Super Guru MySQL / PHP专业人士,他们可以腾出时间。

我有一个PHP / MySQL的Web应用程序,这些应用程序已经发展多年,并且在其上进行了大量搜索。现在,当使用MySQL LOAD DATA INFILE处理新行的各种每日数据转储时,它遇到了瓶颈。

它是一个大型的MyISAM表,大约有150万行,所有的SELECT查询都出现在它上面。当这些事件发生在大约600k行的LOAD DATA INFILE期间(并且删除了过时的数据)时,他们只需要备份并花费大约30多分钟的时间来释放任何这些搜索无效。

我需要想出一种方法来更新该表,同时保留在合理的时间范围内提供SELECT结果的能力。

我完全没有想法,也没有能够自己提出解决方案,因为这是我第一次遇到这类问题。

任何有用的建议,解决方案或来自过去类似经历的指示都会非常感激,因为我很乐意学会解决这类问题。

非常感谢大家的时间! Ĵ

3 个答案:

答案 0 :(得分:1)

您可以将CONCURRENT关键字用于LOAD DATA INFILE。这样,当您加载数据时,该表仍然可以服务器SELECT。

关于删除,这更复杂。我个人会添加一个名为'status'INT(1)的列,他将定义该行是否处于活动状态(=已删除),然后使用基于此列状态的规则对我的表进行分区。

这样,删除status = 0的所有行都会更容易:P我没有测试过这个最后的解决方案,我可能会在不久的将来这样做。

如果您的表格已优化,则CONCURRENT关键字将起作用。如果有任何FREE_SPACE,则LOAD DATA INFILE将锁定表。

答案 1 :(得分:0)

MyISAM不支持行级锁定,因此像mysqldump这样的操作被强制锁定整个表以保证一致的转储。您唯一可行的选择是切换到支持行级锁定的另一个表(如InnoDB),和/或将转储分成更小的部分。小转储在转储/重装时仍会锁定表,但锁定时间会缩短。

更实用的选择是拥有“实时”和“备份”表。在备份表上执行转储/装入操作。当它们是copmlete时,将它换成实时表(重命名表,或者让你的代码动态地改变他们正在使用的表)。如果你能看到一个潜在陈旧数据的短窗口,这可能会更好选项。

答案 2 :(得分:0)

您应该将表存储引擎从MyISAM切换到InnoDB。 InnoDB提供行锁定(与MyISAM的表锁定相反),这意味着当一个查询忙于更新或插入行时,另一个查询可以同时更新不同的行。