我有一个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。
假设我有以下数据:
On Master:
SELECT * FROM table2;
Empty set (0.08 sec)
On Slave:
SELECT * FROM table2;
+----+
| id |
+----+
| 1 |
+----+
1 row in set (0.00 sec)
(只是忽略奴隶不是主人的完整镜像这一事实)
鉴于上述情况,当我从Master上的table1更新一行时,Slave停止并返回错误:
错误'查询时键'PRIMARY''的重复条目'1'。
我不明白为什么奴隶试图插入特定的ID。
奇怪的是,MySQL 5.0.*
这不会发生。
答案 0 :(得分:0)
如果可能,请切换到基于行的复制。
除了基于语句复制的最基本情况之外,自动增量几乎被打破了。对于生成多个auto_increment值的任何语句(通过触发器,多行插入等),只有第一个auto_increment值在从站上始终是正确的(仅记录1-st)。
如果从属设备从日志中读取auto_increment值,但没有“使用”它,则该值将用于下一个语句(可以完全不相关)。当从属设备因某种原因(配置中忽略的表/ db,proc /触发器中的条件插入等)跳过相应的insert语句时会发生这种情况。
我遇到了类似的问题 - 审计日志类型表(触发器在table2中为table1的每次更改都插入一个事件)以及其他一些与自动增量相关的问题。
我不确定这个解决方案是否适合您的情况,但我会发布以防万一:
向table1添加'updated_count'字段。它从0开始(在插入时)并在每次更新时增加1(使用BEFORE INSERT / UPDATE触发器)。
删除table2的auto_increment并将其PK更改为复合键(table1_pk,table1_update)
。然后在table2的PK的AFTER INSERT / UPDATE触发器中使用table1的PK和'updated_count'。