我有一个MySQL主从配置。
在两台服务器上,我都有两个表:table1
和table2
我在两台服务器上都有以下触发器:
Trigger: test_trigger
Event: UPDATE
Table: table1
Statement: insert into table2 values(null)
Timing: AFTER
table2
的结构如下:
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
+-------+---------+------+-----+---------+----------------+
问题是,在MySQL 5.1.*
上,当从方调用触发器时,它会添加在主方上插入的id,而不是根据自己的auto_increment值应该插入的id。
假设我有以下数据:
在主机上:
SELECT * FROM table2;
Empty set (0.08 sec)
从机上:
SELECT * FROM table2;
+----+
| id |
+----+
| 1 |
+----+
1 row in set (0.00 sec)
(忽略从机不是主机的完整镜像这一事实)
给定上述场景,当我在Master上更新表1中的一行时,Slave停止并返回错误:
查询中键"PRIMARY"的错误"重复条目"1"。
我不明白为什么奴隶试图插入一个特定的ID。
很奇怪的是,在MySQL 5.0.*
上没有发生这种情况。
如果可能,请切换到基于行的复制。
除了基于语句的复制的最基本情况外,自动增量几乎不适用于任何情况。
对于任何生成多个auto_increment值的语句(通过触发器、多行插入等),只有第1个auto_increment值在从语句上始终是正确的(只有第1次被记录)。
如果slave从日志中读取了一个auto_increment值,但没有"使用"它,则该值将用于下一条语句(这可能完全无关)。当从设备出于某种原因跳过相应的插入语句时(配置中被忽略的表/db、proc/trigger中的条件插入等),就会发生这种情况
我在一个审计日志类型表中遇到了类似的问题(对于表1的每一次更改,触发器都会在表2中插入一个事件),还有其他几个与自动增量相关的问题。
我不确定这个解决方案是否适合你的情况,但我会发布它以防万一:
-
将"updated_count"字段添加到表1中。它从0开始(插入时),每次更新时递增1(使用BEFORE insert/update触发器)。
-
删除表2的auto_increment并将其PK更改为复合密钥
(table1_pk,table1_update)
。然后在表2的PK的AFTER INSERT/UPDATE触发器中使用表1的PK和"updated_count"。