繁体   English   中英

MySQL行锁定myisam innodb

[英]MySQL row locking myisam innodb

我有一个理论性的问题,在网上找不到好的解决方案:

对于具有100,000个记录的tblA。

我想运行多个进程/应用程序,每个进程/应用程序都访问tblA。

我不希望这些应用访问相同的记录。 即,我希望appA访问前50行,而appB访问后50行,而appC之后访问后50行。

因此,基本上,我希望这些应用对表中的下一个“ N”记录进行某种提取。 我正在寻找一种尽可能快地访问/处理行数据的方法,实质上是同时运行应用程序。 但我不希望这些应用程序处理相同的行。

那么,应该如何建立这种过程呢?

它只是在做一种:

 select from tblA limit 50 
 and doing some kind of row locking for each row (which requires innodb)

指针/伪代码将很有用。

这是来自DBA StackExchange的一些帖子

它讨论了SELECT ... LOCK IN SHARE MODE和随之而来的潜在麻烦。

Percona和SELECT ... FOR UPDATE一起写了一篇不错的文章

这些解决方案的问题是滞后时间。 如果进程A在12:00:00执行并且进程B也恰好在同一时间执行,并且在应用程序中,有几个不同的代码块导致锁/ DML,则每个代码的处理时间都会有所不同。 因此,进程A可能首先完成,也可能是进程B。如果进程A正在设置锁定,而进程B首先修改了记录,则您会遇到麻烦。 这是分叉的麻烦。

您的应用程序应该处理它想要访问的数据。 在其中创建一个指针。 如果使用存储过程,请使用另一个表存储指针。 在开始处理之前,每个进程都会“保留”一组行。 每个进程都应检查该最大值,并查看它是否大于表的长度。

如果要专门处理第一组,第二组等,则可以将LIMIT#(即0,50 51,100 101,150)与ORDER BY一起使用。 锁定是不必要的,因为进程甚至不会尝试访问彼此的记录集。 但是我无法想象一个很好的实现方案。

一种替代方法是只使用带有限制的更新,然后选择已更新的记录。 您可以使用进程ID,随机数或几乎可以保证在整个进程中唯一的其他名称。 在表中添加一个“状态”字段,指示该记录是否可用于处理(即,值为NULL)。 然后,每个进程将更新状态字段以“拥有”记录以进行处理。

UPDATE tblA SET status=1234567890 WHERE status IS NULL LIMIT 50;
SELECT * FROM tblA WHERE status=1234567890;

这将适用于MyISAM或Innodb。 使用Innodb,您可以一次运行多个更新,从而提高性能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM