简体   繁体   English

MySQL行锁定myisam innodb

[英]MySQL row locking myisam innodb

I've got a theoretical question and can't find a good solution for this on the net: 我有一个理论性的问题,在网上找不到好的解决方案:

For a tblA with 100,000 recs. 对于具有100,000个记录的tblA。

I want to have multiple processes/apps running, each of which accesses tblA. 我想运行多个进程/应用程序,每个进程/应用程序都访问tblA。

I don't want the apps to access the same recs. 我不希望这些应用访问相同的记录。 ie, I want appA to access the 1st 50 rows, with appB accessing the next 50, and appC accessing the next 50 after that.. 即,我希望appA访问前50行,而appB访问后50行,而appC之后访问后50行。

So basically I want the apps to do a kind of fetch on the next "N" recs in the table. 因此,基本上,我希望这些应用对表中的下一个“ N”记录进行某种提取。 I'm looking for a way to access/process the row data as fast as possible, essentially running the apps in a simultaneous manner. 我正在寻找一种尽可能快地访问/处理行数据的方法,实质上是同时运行应用程序。 but I don't want the apps to process the same rows. 但我不希望这些应用程序处理相同的行。

So, just how should this kind of process be set up? 那么,应该如何建立这种过程呢?

Is it simply doing a kind of: 它只是在做一种:

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

Pointers/psuedo code would be useful. 指针/伪代码将很有用。

Here is some posts from the DBA StackExchange on this 这是来自DBA StackExchange的一些帖子

It discusses SELECT ... LOCK IN SHARE MODE and potential headcahes that comes with it. 它讨论了SELECT ... LOCK IN SHARE MODE和随之而来的潜在麻烦。

Percona wrote a nice article on this along with SELECT ... FOR UPDATE Percona和SELECT ... FOR UPDATE一起写了一篇不错的文章

The problem with these solutions is lag time. 这些解决方案的问题是滞后时间。 If process A executes at 12:00:00 and proccess B also executes at precisely the same time, and in an application, there are several blocks of distinct code leading up to the locks/DMLs, the process time for each would vary. 如果进程A在12:00:00执行并且进程B也恰好在同一时间执行,并且在应用程序中,有几个不同的代码块导致锁/ DML,则每个代码的处理时间都会有所不同。 So process A may complete first, or it may be process B. If process A is setting the lock, and process B modifies the record first, you're in trouble. 因此,进程A可能首先完成,也可能是进程B。如果进程A正在设置锁定,而进程B首先修改了记录,则您会遇到麻烦。 This is the trouble with forking. 这是分叉的麻烦。

Your application should handle what data it wants to access. 您的应用程序应该处理它想要访问的数据。 Create a pointer in that. 在其中创建一个指针。 If you're using stored procedures, use another table to store the pointers. 如果使用存储过程,请使用另一个表存储指针。 Each process would "reserve" a set of rows before beginning processing. 在开始处理之前,每个进程都会“保留”一组行。 Every process should check for the max of that and also see if it is greater than the length of the table. 每个进程都应检查该最大值,并查看它是否大于表的长度。

If you are specifically looking for processing first set, second set, etc. The you can use LIMIT # (ie 0,50 51,100 101,150) with an ORDER BY. 如果要专门处理第一组,第二组等,则可以将LIMIT#(即0,50 51,100 101,150)与ORDER BY一起使用。 Locking is not necessary since the processes won't even try to access each others record sets. 锁定是不必要的,因为进程甚至不会尝试访问彼此的记录集。 But I can't imagine a scenario where that would be a good implementation. 但是我无法想象一个很好的实现方案。

An alternative is to just to use update with a limit, then select the records that were updated. 一种替代方法是只使用带有限制的更新,然后选择已更新的记录。 You can use the process ID, random number or something else that is almost guaranteed to be unique across processes. 您可以使用进程ID,随机数或几乎可以保证在整个进程中唯一的其他名称。 Add a "status" field to your table indicating if the record is available for processing (ie value is NULL). 在表中添加一个“状态”字段,指示该记录是否可用于处理(即,值为NULL)。 Then each process would update the status field to "own" the record for processing. 然后,每个进程将更新状态字段以“拥有”记录以进行处理。

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

This would work for MyISAM or Innodb. 这将适用于MyISAM或Innodb。 With Innodb you would be able to have multiple updates running at once, improving performance. 使用Innodb,您可以一次运行多个更新,从而提高性能。

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

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