为什么复制失败并出现错误“密钥重复输入”?

为什么复制失败并出现错误“密钥重复输入”?

我们已经复制了一两年了,几乎没有遇到什么问题。有时我们会收到错误的 SQL 查询,导致复制停止,我们使用以下命令使其再次运行:

STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;
SHOW SLAVE STATUS \G;

这通常没问题,但是今天我们在尝试复制(仅供参考 Invision Power Board)数据库时开始出现错误:

               Last_SQL_Error: Error 'Duplicate entry 'forums-pid-994' for key '
app'' on query. Default database: 'forum_db'. Query: 'INSERT INTO ibf_rep
utation_cache (`app`,`type`,`type_id`,`rep_like_cache`) VALUES('forums','pid',99
4,'a:2:{s:10:\"cache_data\";a:0:{}s:12:\"cache_expire\";i:1326339370;}') ON DUPL
ICATE KEY UPDATE app=VALUES(app),type=VALUES(type),type_id=VALUES(type_id),rep_l
ike_cache=VALUES(rep_like_cache)'

似乎有许多这样的查询是 Invision Power Board 软件的一部分,因此删除它不是一个选择。奇怪的是,当我在同一台 MySQL 服务器上运行该查询时,它没有出现问题。

笔记:我们昨天从 MySQL 5.1.36 升级到了 MySQL 5.5.16,所以这几乎肯定是相关的。它位于 Windows 服务器上。

表格的布局如下:

mysql> DESC forum_db.ibf_reputation_cache;
+----------------+---------------------+------+-----+---------+----------------+

| Field          | Type                | Null | Key | Default | Extra          |

+----------------+---------------------+------+-----+---------+----------------+

| id             | bigint(10) unsigned | NO   | PRI | NULL    | auto_increment |

| app            | varchar(32)         | NO   | MUL | NULL    |                |

| type           | varchar(32)         | NO   | MUL | NULL    |                |

| type_id        | int(10) unsigned    | NO   |     | NULL    |                |

| rep_points     | int(10)             | NO   |     | 0       |                |

| rep_like_cache | mediumtext          | YES  |     | NULL    |                |

+----------------+---------------------+------+-----+---------+----------------+

6 rows in set (0.12 sec)

答案1

让我们从错误消息开始:

               Last_SQL_Error: Error 'Duplicate entry 'forums-pid-994' for key '
app'' on query. Default database: 'forum_db'. Query: 'INSERT INTO ibf_rep
utation_cache (`app`,`type`,`type_id`,`rep_like_cache`) VALUES('forums','pid',99
4,'a:2:{s:10:\"cache_data\";a:0:{}s:12:\"cache_expire\";i:1326339370;}') ON DUPL
ICATE KEY UPDATE app=VALUES(app),type=VALUES(type),type_id=VALUES(type_id),rep_l
ike_cache=VALUES(rep_like_cache)'

复制是抱怨该指数被称为app显然,您在该列上有一个 UNIQUE 索引。另外,请注意查询的ON DUPLICATE KEY子句。您有。由于两个原因,app=VALUES(app)此列无法替换:ON DUPLICATE KEY

  1. ON DUPLICATE KEY这是触发该操作的同一列
  2. app如果允许该行为,将会不必要地影响指数

建议:您应该将其app=VALUES(app)ON DUPLICATE KEY条款中删除。

MySQL 的早期版本可能只是忽略了ON DUPLICATE KEY子句中的违规列,而您现在使用的最新版本对此问题更加了解。

相关内容