複数のプロセスでまったく同じスクリプトを実行していますが、問題はそれらが同じデータを選択していることです。選択後に 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;";