2

複数のプロセスでまったく同じスクリプトを実行していますが、問題はそれらが同じデータを選択していることです。選択後に 1 に設定されるフラグ「in_use」がありますが、他のプロセスが速すぎて、スクリプト自体がすべてのデータを in_use = 1 に更新する前に同じデータを選択します。おそらくクエリ内で、同じデータが選択されていないことを確認してください。なんとなくロック?

現在、プロセスごとに in_use を更新していますが、高速でも安全でもありません。

DELIMITER //

DROP PROCEDURE IF EXISTS `getDomainsForWhois`;

CREATE PROCEDURE `getDomainsForWhois`(
    IN in_tld VARCHAR(10), 
    IN in_max_limit INT
) 

BEGIN 
    SELECT 
        d.domainID, 
        CONCAT(SUBSTRING_INDEX(REPLACE(d.domainName, LOWER(d.tld), ''), '.' , -1), LOWER(d.tld)) as domainName, 
        d.tld 
    FROM 
        Domains d 
    WHERE (
        d.parentDomainID IS NULL 
    AND 
        d.tld = in_tld 
    AND 
        d.dateFetched <= DATE_SUB(CURRENT_TIMESTAMP(),INTERVAL 1 DAY) 
    AND 
        d.in_use = 0 
    ) 
    GROUP BY 
        domainName 
    ORDER BY 
        d.dateFetched ASC 
    LIMIT 
        0,in_max_limit
    FOR
        UPDATE;
END//

これは基本的にスクリプトを実行する方法です。このスクリプトは、複数のプロセス (cron) から同時に実行されます。

domains=`mysql -u USER -pPASSWORD DBNAME --skip-column-names -e "LOCK TABLE Domains WRITE; CALL getDomainsForWhois('.$1', $2)"`;
while read domainID domainName domainTld
do
        mysql -u USER -pPASSWORD DBNAME -e "UPDATE Domains SET in_use = 1 WHERE domainID = $domainID";
done << EOF
$domains
EOF

mysql -u USER -pPASSWORD DBNAME -e "UNLOCK TABLES;";
4

1 に答える 1

0

テーブルをロックするだけで調べることはおそらく可能でしょう

http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html

したがって、SELECTの前に

LOCK TABLE Domains WRITE;

そして、あなたがした後

UNLOCK TABLES;
于 2013-03-27T13:28:07.177 に答える