• MySQL丶auto_increment


    背景:

      Innodb引擎使用B_tree结构保存表数据,这样就需要一个唯一键表示每一行记录(比如二级索引记录引用)。

      Innodb表定义中处理主键的逻辑是:

      1.如果表定义了主键,就使用主键唯一定位一条记录

      2.如果没有定义主键,Innodb就生成一个全局唯一的rowid来定位一条记录

    auto_increment的由来:

      1.Innodb强烈推荐在设计表中自定义一个主键,因为rowid是全局唯一的,所以如果有很多表没有定义主键,就会在生成rowid上产生争用。

    /* Dictionary system struct */
    struct dict_sys_struct{
    mutex_t	mutex;
    row_id_t	row_id;
    ......
    }
    

      row_id由mutex保护,并在每次checkpoint的时候,写入到数据字典的文件头。

      2.当用户自定义了主键后,由于大部分实际应用部署的分布式,所以主键值的生成上,采用集中式的方式,更容易实现唯一性,所以auto_increment非常合适。

      auto_increment也带来两个好处:

      1. auto_increment的值是表级别的,不会在db级别上产生争用

      2. 由于auto_increment的顺序性,减少了随机读的可能,保证了写入的page的缓冲命中。(不可否认,写入的并发足够大时,会产生热点块的争用)

    auto_increment引起的bug:

      环境:MySQL 5.6.16版本, binlog_format=row

      case复现:

    create table test.kkk ( c int(11) default null, id int(11) not null auto_increment, d int(11) default null, primary key (id), unique key d (d) )
    engine=innodb default charset=latin1;
    insert into test.kkk values(5, 27,4);
    replace into test.kkk(c, id, d) values(6, 35, 4);
    commit;	
    

    show create table时: 主库:auto_increment=36 备库:auto_increment=28

      当进行主备切换后,导致主键冲突,slave恢复异常。

      同样insert on duplication update 语句同样存在这样的问题。

    螃蟹在剥我的壳,笔记本在写我,漫天的我落在枫叶上雪花上,而你在想我。 --章怀柔
  • 相关阅读:
    面向对象继承
    webpack 错误提示 Error: Can't resolve 'css-loader'或Error: Can't resolve 'style-loader'
    Math.min() Math.max()
    表单
    addEventListener()
    H5图片背景
    ruby获取最新ruby
    js对象拷贝
    Oh-My-Zsh 下远程ssh的乱码问题
    MSSQL、MySQL 数据库删除大批量千万级百万级数据的优化
  • 原文地址:https://www.cnblogs.com/lovezhr/p/13269231.html
Copyright © 2020-2023  润新知