mysql - 如何使用 PHP 执行 MySQL 行锁定和删除行?

标签 mysql locking innodb

LAMP 堆栈 - 所以代码是 PHP

我有一个 innodb 表 - 称为queueTable

有一个每 15 分钟运行一次的 cron 作业,它查询数据库以确定是否需要将任何记录放入队列表中。有时没有记录添加到queueTable,有时可能有超过1000条记录添加到queueTable。

需要发生的是需要读取queueTable中的每一行,需要执行一个过程,然后需要删除该行。

目前,我有两个守护进程作业,除了每 5 秒查询一次队列表之外什么也不做。

一个作业读取所有奇数行记录,另一个作业读取所有偶数行记录。为了快速完成所有处理,有两个作业(两个作业比一个好)。

我想创建大约 20 个守护进程来全部进入队列表 - 从而将行在队列表中的生存时间降至最低。

将其视为一个邮件队列(它不是一个有效的示例)。

我需要尽快清空队列。

我可以执行事务并锁定该行,但这并不能阻止另一个守护程序尝试锁定同一行。如果守护程序尝试读取锁定的行,将会发生什么 - 它会等待它。但是锁定该行的守护进程将删除它。不确定第二个守护进程此时会做什么?

完成我想做的事情的最佳方法是什么?

我希望这是有道理的。

谢谢!

顺便说一句 - 我尝试过 pthreads - 发现它在吞吐量方面确实没有多大帮助。 IE。读取一条记录并在获取下一条记录之前对其进行处理的进程 - 如果我在多线程模式下执行此操作(即每个进程都是一个新线程),则清空队列的时间与执行每一行的时间相同一次。至少在我的测试中是这样。

最佳答案

我在 MySQL 中实现队列的口头禅:“不要排队,直接去做!”

使用 PHP 进行多重处理并不是那么容易实现的。 Perl(也是 Lamp 的一部分)要好得多。此外,由于这是一项后台任务,因此请将 Web 服务器和浏览器 (Apache + IE) 排除在外;它们的开销很大。

处理一件“元素”需要多长时间?如果只需要几秒钟,那么BEGIN; SELECT one item FOR UPDATE; process it; COMMIT;

如果需要的时间比这更长,请勿输入 BEGIN...COMMIT围绕一切;相反,做类似的事情:

SET autocommit=1

  1. $id = SELECT id ... WHERE process_id IS NULL ORDER BY ... LIMIT 1; (或者您可以获取 10 个并进行步骤 2..5 的内部循环。)
  2. UPDATE ... SET process_id = $pid WHERE id = $id AND process_id IS NULL;并检查它是否有效。请注意 SELECTUPDATE故意不参与交易;这是为了尽量减少干扰。然而,如果没有事务,另一个线程很有可能会捕获它。如果是这样,rows_affected 将为 0;返回步骤 1。
  3. 处理该项目
  4. UPDATE (or DELETE) ... SET process_id = NULL WHERE id = $item; -- 释放锁
  5. sleep(1) ——延迟一点——以避免人为地淹没系统。这可能需要调整。
  6. 返回第 1 步。

您可以让任意数量的线程执行此操作。

关于mysql - 如何使用 PHP 执行 MySQL 行锁定和删除行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31278918/

相关文章:

C - 多个进程写入同一个日志文件

mysql - Akonadi(KDE)崩溃 : repair InnoDB data when MySQL can't start

mysql - 我无法从数据库中删除记录

java - Springboot 1.5.9版本无法连接mysql RDS

iphone - 为应用程序设置密码锁?

mysql - AI专栏与Percona XtraDB Cluster的数值存在差距

mysql - InnoDB:(PK,col1,col2,col3)形式的覆盖索引是否多余?

mysql - 如何在 mysql 5.0 中查找表的依赖项?

mysql 在准备好的语句结果和调用的存储过程结果之间使用 UNION

multithreading - 在TensorFlow优化器中use_locking = True有什么作用?