I am using the trigger shown below to automatically assign a random key to inserted rows, retrying the random generation if an existing row is found. 99.9% of the time this works exactly as expected. However, every couple of weeks or so the trigger locks up, the REPEAT loop within it apparently becoming infinite; the query continues indefinitely, effectively locking up the application, and has to be KILLed.
As far as I can see, there is nothing about the logic involved that makes it seem as if this should ever happen. The keyspace involved is certainly nowhere near exhaustion and never will be. What is going on?
The trigger:
DELIMITER //;
CREATE TRIGGER `mytable_insert` BEFORE INSERT ON `mytable`
FOR EACH ROW
BEGIN
DECLARE `curr` BIGINT UNSIGNED;
DECLARE `sel` BIGINT UNSIGNED;
IF NEW.`mykey` IS NULL THEN
REPEAT
SELECT FLOOR(RAND() * 18446744073709551615) INTO `sel`;
SELECT `id` INTO `curr` FROM `mytable` WHERE `mykey` = `sel` LIMIT 1;
UNTIL `curr` IS NULL END REPEAT;
SET NEW.`mykey` = `sel`;
END IF;
END
The error is this line
If no row matches
mykey = selthen curr isn’t assigned at all.So curr will never be null if it’s ever assigned anything else.
Replace with something like this (untested)