mysql|MySQL 的这个 BUG,坑了多少人?( 三 )
但是前面两种都出现了autoinc错误 , 唯独hz_freeze_balance_sharding表没有出错 。
难道是用户对这两种表的访问方式不一样?抓取用户的sql语句 , 果然 , 前两种表用的都是replace into操作 , 最后一种表用的是update操作 。 难道是replace into语句导致的问题?搜索官方bug, 又发现了一个疑似bug 。
bug #87861: “Replace into causes master/slave have different auto_increment offset values”
原因:
(1) Mysql对于replace into实际是通过delete + insert语句实现 , 但是在ROW binlog格式下 , 会向binlog记录update类型日志 。 Insert语句会同步更新autoincrement , update则不会 。
(2) replace into在Master上按照delete+insert方式操作 ,autoincrement就是正常的 。 基于ROW格式复制到slave后 , slave机上按照update操作回放 , 只更新行中自增键的值 , 不会更新autoincrement 。
因此在slave机上就会出现max(id)大于autoincrement的情况 。 此时在ROW模式下对于insert操作binlog记录了所有的列的值 , 在slave上回放时并不会重新分配自增id , 因此不会报错 。 但是如果slave切master , 遇到Insert操作就会出现”Duplicate key”的错误 。
(3) 由于用户是从5.6迁移到5.7 , 然后直接在5.7上进行插入操作 , 相当于是slave切主 , 因此会报错 。
解决方案
业务侧的可能解决方案:
(1) binlog改为mixed或者statement格式
(2) 用Insert on duplicate key update代替replace into
内核侧可能解决方案:
(1) 在ROW格式下如果遇到replace into语句 , 则记录statement格式的logevent , 将原始语句记录到binlog 。
(2) 在ROW格式下将replace into语句的logevent记录为一个delete event和一个insert event 。
心得
(1) autoincrement的autoinc_lock_mode及auto_increment_increment这两个参数变化容易导致出现重复的key , 使用过程中要尽量避免动态的去修改 。
(2) 在碰到线上的问题时 , 首先应该做好现场分析 , 明确故障发生的场景、用户的SQL语句、故障发生的范围等信息 , 同时要对涉及实例的配置信息、binlog甚至实例数据等做好备份以防过期丢失 。
只有这样才能在找官方bug时精准的匹配场景 , 如果官方没有相关bug , 也能通过已有线索独立分析 。
推荐阅读
- 智趣科技|放心,这个扎手真不疼!糖护士血糖尿酸测试仪测评
- AMD,英特尔|又一批第十代酷睿CPU来了 这个全新i9价格有点香
- 三星手机|三星手机的oneui2系统真的很垃圾吗?
- 中年|历史上被称作用情最专一的皇帝,却死于不测,这个人是谁?
- 群众网|这个国产科技品牌连续十年蝉联全球第一,却很低调,甚至被人误解
- 小米手机|小米10Pro跳水700,这个价位随便买吧
- 新智元|两图生万物!这个超强图像转换神器,小样本一秒猫狗合体变新物种
- 雷科技|查岗抓奸新工具?高德地图这个新功能,让你的行踪无所遁形
- 数据库|面试官:说说MySQL数据库分库分表,并且会有哪些问题?
- 滋补|猪身上就这个部位最贵夏天应该多吃点,比牛羊肉更滋补