Duplicate keys error after switching to MySQL Galera
문제
I recently switched from a single MySQL installation to MySQL Galera, running on 3 nodes addressed via HAProxy. Ever since switching I do get randomly "duplicate key" errors reported which theoretically should not be possible as I do check if the dataset is already available.
e.g.:
MySQL Error executing stmt:
INSERT INTO user_ips
(user_id,ip)
VALUES
('444079','41.205.7.198, 176.9.19.101')
Error No: 1062
Error: Duplicate entry '444079-41.205.7.198, 1' for key 'user_id'
My code looks like this:
function save_user_ip($user_id){
global $T62, $link;
$ip = $_SERVER['REMOTE_ADDR'];
// do we already know that user by this ip?
$stmt="
SELECT ID AS ip_id
FROM $T62
WHERE user_id = '$user_id' AND ip = '$ip'
";
$row = db_get_row2($stmt);
$ip_id = isset($row->ip_id) ? $row->ip_id : "";
if (!$ip_id){ // ip unknown for that user, save it
$stmt="
INSERT INTO $T62
(user_id,ip)
VALUES
('$user_id','$ip')
";
db_query($stmt);
$ip_id = db_insertid($link);
}
return $ip_id;
}
Running this on a test page it works as intended. On the production server under load it however does not always work. I thought about INSERT IGNORE but would rather not run an insert on all actions as writes are slower and it also triggers a warning.
Running SHOW CREATE TABLE tablename
creates following output:
1146 - Table 'tablename' doesn't exist
One possible solution that seems to work at least on development cluster:
// save ip. Will ignore if already known ip
$stmt="
INSERT IGNORE INTO $T62
(user_id,ip)
VALUES
('$user_id','$ip')
";
#echo $stmt; exit;
db_query($stmt);
$ip_id = db_insertid($link);
// if ip already known, retrieve it
if (!$ip_id){
$stmt="
SELECT ID AS ip_id
FROM $T62
WHERE user_id = '$user_id' AND ip = '$ip'
";
$row = db_get_row2($stmt);
$ip_id = $row->ip_id;
}
return $ip_id;
Not sure how this improves the situation on prod or if it makes things even worse. There might be a more elegant solution.
Thank you in advance for any help on this.
해결책
User error.
Since when does an ip
look like 41.205.7.198, 176.9.19.101
?
444079-41.205.7.198, 1
implies that 41.205.7.198, 1
was what was used as the ip
. That's the first 15 characters, so I guess you have VARCHAR(15)
. (Note: this is why the first comment was asking for SHOW CREATE TABLE
.)
So, your funny IP got truncated, leading to a user-caused DUP KEY.