我们已经复制了一两年了,几乎没有遇到什么问题。有时我们会收到错误的 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
ON DUPLICATE KEY
这是触发该操作的同一列app
如果允许该行为,将会不必要地影响指数
建议:您应该将其app=VALUES(app)
从ON DUPLICATE KEY
条款中删除。
MySQL 的早期版本可能只是忽略了ON DUPLICATE KEY
子句中的违规列,而您现在使用的最新版本对此问题更加了解。