[英]Why MyISAM storage engine does not support row level locking as 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.