1.innodb_autoinc_lock_mode 自增列的锁状态,有三种选值: 0 1 2
innodb_autoinc_lock_mode =0
所有的isert 都会持有AUTO-INC table-level lock直到语句结束,statement-based 这种复制模式下,从库的自增列值会和主库保持一致。
innodb_autoinc_lock_mode =1
这种模式为默认模式,可以预估需要插入多少行,分配多少个自增值得简单插入会避免使用AUTO-INC table-level lock。
INSERT ... SELECT,
REPLACE ... SELECT, and
LOAD DATA对于这种复杂insert还是会选择持有AUTO-INC table-level lock直到语句结束,这种情况下,如果既有简单插入又有行数不确定的出入一起执行的时候,innndb一般会分配比要求的行数更多的自增列值,但是分配的值还是会保证连续,多分配的值则会丢失。
innodb_autoinc_lock_mode =2
这种模式允许并发,可扩展性,不会持有table-level
AUTO-INC lock
2.自增值在MySQL8.0有一个较大的改变,以前的自增值会在重启之后取max(primary_id)+1,这种情况某些情况会导致主键冲突或者其他问题。
相关bug:
https://bugs.mysql.com/bug.php?id=199
相关bug解决:
https://dev.mysql.com/worklog/task/?id=6204
However, the same has already been fixed in 8.0 by WL#6204 - InnoDB persistent max value for autoinc columns. Upgrading to 8.0 will fix the issue.
具体的改进为:
1. The AUTOINC counters would get persisted through redo logs 通过redo log持久化 2. All AUTOINC counters would be collected from redo logs and applied to in-memory counters if they're bigger. 所有的自增值将会记入redo log 并且会在很大的时候应用到内存中的计数器 3. There won't be any rollback of AUTOINC counters. 他们不会被rollback 4. 'SELECT MAX(c) FROM t' would not be needed except when IMPORT tablespace. SELECT MAX(c) FROM t'除了在表空间导入的时候,其他时候都不需要了 5. The largest updated counter will be logged and will not change with reboot. 最大的更新计数器不会在重启的时候改变 6. Considering performance, we could write some extra redo logs, but no new MTRs. 对于性能来说,会有一些额外的redo log写入,但是没有新的MTRs
3.另外还有一个改变点就是replace into的bug,replace的时候如果唯一键值存在,则会记录为delete+insert,影响行数是2,但是binlog的记录是update操作,这样从库同步仅执行了update,不会更新自增值。
In MySQL 8.0, updating an existing AUTO_INCREMENT column value in an InnoDB table also resets the AUTO_INCREMENT sequence.
