SHOW VARIABLES LIKE 'binlog_format';
SET BINLOG_FORMAT='statement';
 
create table t1(id int primary key auto_increment, a int not null , b int,c int, index (a),index bc(b,c))engine=innodb;
 
insert into t1(a,b,c) values(1,1,1),(2,2,2),(3,3,3),(4,4,4);
 
insert into t1(a,b,c) select a,b,c from t1;
 
-- 新建一个log文件写入binlog信息
FLUSH BINARY LOGS;

问题1

主键id不连续问题(有规律性的+4、+8)

解答

执行完insert into t1(a,b,c) values(1,1,1),(2,2,2),(3,3,3),(4,4,4);分配了几个id,为什么是连续1~4

撇开以上问题

MySQL批量申请自增id的策略:
语句执行过程中,第一次申请自增id,会分配1个(2的0次方)
不够则第二次申请自增id,会再分配2个(2的1次方)
不够则第三次申请自增id,会再分配4个(2的2次方),以此类推。

第一次执行insert into t1(a,b,c) select a,b,c from t1;需要插入4条数据记录,预申请1+2+4=7个id才够用(预申请id范围5-11),实际用掉4个(id范围5-8)。
第二次执行insert into t1(a,b,c) select a,b,c from t1;需要插入8条数据记录,7个id不够用,预申请1+2+4+8=15个id才够用(预申请id范围12-26),实际用掉8个(id范围12-19)。
第三次执行insert into t1(a,b,c) select a,b,c from t1;需要插入16条数据记录,15个id不够用,预申请1+2+4+8+16=31个id才够用(预申请id范围27-57),实际用掉16个(id范围27-42)。
第三次执行insert into t1(a,b,c) select a,b,c from t1;需要插入32条数据记录,31个id不够用,预申请1+2+4+8+16+32=63个id才够用(预申请id范围58-120),实际用掉32个(id范围58-89)。以此类推。

拓展

发生id跳跃的几种情况

  • 唯一键冲突
  • 事务回滚
  • 批量insert 比如 insert select 或者 load data等

参考

丁奇:https://www.iteye.com/blog/dinglin-1279536
小牛刀:https://www.jb51.net/database/307352frq.htm
官网文档:https://dev.mysql.com/doc/refman/8.4/en/innodb-auto-increment-handling.html
MySQL 5.7 参考手册 :InnoDB 中的AUTO_INCREMENT处理