MySQL触发器可实现同库内轻量级、强一致的数据自动同步,但仅适用于结构简单、低频、容错要求不严的场景;不能替代复制或CDC工具,同步必须用AFTER触发器,目标表须为本地同实例表并设计幂等性。

MySQL触发器可以实现同库内轻量级、强一致的数据自动同步,但仅适用于结构简单、频率不高、容错要求不严的场景。它不是通用同步方案,不能替代复制或CDC工具。
同步必须用AFTER触发器获取完整数据
主表若含自增主键,BEFORE INSERT中NEW.id为NULL,无法用于关联写入;只有AFTER INSERT才能安全读取真实ID。例如同步用户注册到日志表:
- 先建目标表:
CREATE TABLE user_log (id INT, name VARCHAR(50), created_at TIMESTAMP); - 再建触发器:
CREATE TRIGGER sync_user_log AFTER INSERT ON users FOR EACH ROW INSERT INTO user_log VALUES (NEW.id, NEW.name, NOW()); - UPDATE/DELETE同步同理,分别用OLD.id和OLD字段值
避免无差别同步,只响应关键字段变化
UPDATE触发器容易因时间戳、更新计数器等辅助字段变动而误触发。应显式判断业务关键字段:
- 写法正确:
IF OLD.status != NEW.status THEN INSERT INTO status_history ... END IF; - 避免全字段比对:
OLD.* != NEW.*在有NULL时恒为FALSE,不可靠 - 字符串建议清洗后比较:
TRIM(OLD.phone) != TRIM(NEW.phone)
同步目标必须是本地同实例表,且需幂等设计
触发器无法跨库执行INSERT(除非用FEDERATED引擎映射远程表,但稳定性差、调试难);也不能调用存储过程发HTTP请求——失败会直接中断主事务。
- 安全做法:只写入同一MySQL实例下的另一张表,如归档表、统计宽表、日志表
- 幂等关键:目标表主键或唯一键要能防止重复插入,比如用
(source_id, event_time)作联合唯一索引 - 注意锁竞争:目标表若被长事务占用,会拖慢源表DML,批量操作尤其敏感
别把触发器当消息队列用
触发器是同步阻塞执行,一旦目标写入失败(如磁盘满、约束冲突、死锁),原始INSERT/UPDATE就会报错回滚,不会重试也不会落盘待处理。
- 典型错误:
ERROR 1062 (23000): Duplicate entry或ERROR 1205 (40001): Deadlock found - 高频更新场景慎用:每行变更都触发一次SQL,性能开销线性增长
- 真正需要跨服务同步时,应改用MySQL Binlog + Debezium/Kafka,或阿里云DTS等专业工具


















