【问题标题】:how to synchronize mysql database requests?如何同步mysql数据库请求?
【发布时间】:2011-02-16 16:30:48
【问题描述】:

我在一个表中有很多条目是为执行作业而提取的。这可以扩展到多台服务器。

当服务器获取一堆行以添加到它自己的作业队列中时,它们应该被“锁定”,以便没有其他服务器获取它们。 当执行更新时,时间戳会增加并且它们被“解锁”。

我目前通过更新表中名为“jobserver”的字段来执行此操作,该字段默认为空,并带有作业服务器的 id。

作业服务器只选择字段为空的行。

当所有行都被处理时,它们的时间戳被更新,最后作业字段再次设置为空。

所以我需要同步这个:

$jobs = mysql_query("
SELECT itemId 
FROM items 
WHERE 
jobserver IS NULL 
AND 
DATE_ADD(updated_at, INTERVAL 1 DAY) < NOW()
LIMIT 100
");

mysql_query("UPDATE items SET jobserver = 'current_job_server' WHERE itemId IN (".join(',',mysql_fetch_assoc($jobs)).")");

// do the update process in foreach loop
// update updated_at for each item and set jobserver to null

每台服务器都在无限循环中执行上述操作。如果没有返回任何字段,则所有内容都是最新的 2 日期(最后一次更新不超过 24 小时)并被发送到 10 分钟。

我目前有 MyIsam,我想继续使用它,因为在我的情况下,它的性能比 innodb 好得多,但我听说 innodb 有 ACID 事务。

所以我可以同时执行选择和更新。但它的外观和工作方式如何?

问题是我不能锁定表或其他东西,因为其他进程需要读/写并且无法锁定。

我也对共享信号量等更高级别的解决方案持开放态度。问题是同步需要跨多个服务器。

  • 这种方法总体上是否合理?你会采取不同的做法吗?

  • 如何同步作业 selectino 以确保两台服务器不会更新相同的行?

【问题讨论】:

    标签: php mysql multithreading synchronization acid


    【解决方案1】:

    您可以先运行 UPDATE,但要使用 SELECT 上的 WHERE 和 LIMIT。然后选择将 jobserver 字段设置为您的服务器的行。

    【讨论】:

    • 好主意!但它确保同步吗?我是说。如果更新需要一些时间,同时另一个进程也想更新怎么办?即使在 myisam 中,一个查询也是原子的吗?
    • 一个查询在 myiasm 中是原子的。单个查询将在查询期间锁定表,更新时使用排他锁或选择时使用共享锁。
    【解决方案2】:

    如果您不能锁定表,那么我会以未修改的行为条件进行更新。比如:

    $timestamp = mysql_query("SELECT DATE_SUB(NOW(), INTERVAL 1 DAY)");
    
    $jobs = mysql_query("
    SELECT itemId 
    FROM items 
    WHERE 
    jobserver IS NULL 
    AND 
    updated_at < ".$timestamp."
    LIMIT 100
    ");
    
    // Update only those which haven't been updated in the meantime
    mysql_query("UPDATE items SET jobserver = 'current_job_server' WHERE itemId IN (".join(',',mysql_fetch_assoc($jobs)).") AND updated_at < ".$timestamp);
    
    // Now get a list of jobs which were updated
    $actual_jobs_to_do = mysql_query("
    SELECT itemId
    FROM items
    WHERE jobserver = 'current_job_server'
    ");
    
    // Continue processing, with the actual list of jobs
    

    您甚至可以组合选择和更新查询,如下所示:

    mysql_query("
    UPDATE items
    SET jobserver = 'current_job_server'
    WHERE jobserver IS NULL
    AND updated_at < ".$timestamp."
    LIMIT 100
    ");
    

    【讨论】:

      猜你喜欢
      • 2011-05-02
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      相关资源
      最近更新 更多