mysql auto_increment 的坑

  • Statement-Based Replication,不要设置innodb_autoinc_lock_mode=2 会导致主从数据不一致
innodb_autoinc_lock_mode=2 时,auto_inc锁顺序:
0)   开始语句执行:
1)   申请AUTO_INC锁
2)   得到当前AUTO_INCREMNT值n,给AUTO_INCREMENT 加1
3)   释放AUTO_INC锁
4)   插入一条记录
5)   并发的重复执行1,2,3,4
6)   语句结束

insert模式
insert like
所有的插入语句范式
INSERT, INSERT … SELECT, REPLACE, REPLACE … SELECT, and LOAD DATA, INSERT … VALUES(),VALUES()
包括simple inserts, bulk inserts, mixed-mode inserts
Simple inserts
可以确定插入记录条数
INSERT, INSERT … VALUES(),VALUES()
Bulk inserts
不可以确定插入记录条数
INSERT … SELECT
REPLACE … SELECT
LOAD DATA
Mixed-mode inserts
不确定是否分配auto_increment_id
INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');
INSERT … ON DUPLICATE KEY UPDATE

对于Bulk inserts 和 Mixed-mode inserts (比如:INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');  和load file语句) auto_increment的列的值是不连续的,而且主备上值在并发环境下可能是不一致的。

  • replace into 语句坑
产生条件
1.主键是auto_increment 
2.有另一unique key 的唯一键
3.通过replace into 更新唯一键的值
4.表中存在repalce into 中指定的唯一键的记录
5.主机和备机采用row模式复制
行为:原因是:主机执行的是delete+insert语句,备机执行的是update语句
结果是:备机的auto_increment的值比主机小1, 主备发生切换后导致键值冲突
    解决办法:使用nsert into table values(,....) on duplicate key update 替换

  • InnoDB 自增列出现重复值
原因
AUTO_INCREMENT是实时存储内存中
mysqld 重启后行类似select max(id)+1 from t1;方法来得到AUTO_INCREMENT
产生场景
如果mysql在重启前迁移部分数据到历史库
重启后mysql 会重用auton_increment的值
再次迁移数据到历史库会导致数据库记录重复出现
解决办法
每次迁移的历史数据存放在不同的库表
历史库字段去掉auto_increment属性
采用replace into 方式导入



参考:
http://www.kancloud.cn/taobaomysql/monthly/67160
https://blog.xupeng.me/2013/10/11/mysql-replace-into-trap/
http://blog.csdn.net/jiao_fuyou/article/details/46485631







你可能感兴趣的:(mysql/oracle)