• MySQL自增锁


    最近在工作中遇到很多使用MySQL自带的autoincrement函数作为发号器,在实际使用中当并发比较小的时候还没有问题,一旦并发增加就会出现很多问题,特此进行如下总结。

    一、自增配置

    通过如下建表语句就可以完成自增的配置

    CREATE TABLE `test_inc` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    二、修改自增大小

    通过如下sql可以自动生成数字:

    insert into test_inc values();

    当增加3行后表中数据如下:

    +----+
    | id |
    +----+
    | 1 |
    | 2 |
    | 3 |
    +----+

    CREATE TABLE `test_inc` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

    使用 alter table test_inc auto_increment=10;将自增修改成10后再次插入的数据为10.

    +----+
    | id |
    +----+
    | 1 |
    | 2 |
    | 3 |
    | 10 |
    | 11 |
    +----+

    三、自增幅度

    自增幅度通过auto_increment_offset和auto_increment_increment这2个参数进行控制

    set global auto_increment_increment=2;
    set global auto_increment_offset=2;
    set session auto_increment_increment=2;
    set session auto_increment_offset=2;

    生成偶数的自增

    set global auto_increment_increment=2;
    set global auto_increment_offset=1;
    set session auto_increment_increment=2;
    set session auto_increment_offset=1;

    生成奇数的自增

    auto_increment_offset表示起始数字

    auto_increment_increment表示调动幅度(即每次增加n个数字,2就代表每次+2)

    四、获得最后一个数字

    通过使用last_insert_id()函数可以获得最后一个插入的数字

    select last_insert_id();

    五、自增锁

    如果存在自增字段,MySQL会维护一个自增锁,和自增锁相关的一个参数为(5.1.22版本之后加入)

    innodb_autoinc_lock_mode:可以设定3个值,0,1,2

    0:traditonal (每次都会产生表锁)
    
    1:consecutive (会产生一个轻量锁,simple insert会获得批量的锁,保证连续插入)
    
    2:interleaved (不会锁表,来一个处理一个,并发最高)

    ps:这个参数值控制InnoDB引擎的设置,所有Myisam均为traditonal,每次均会进行表锁。但是Innodb会视参数不通二产生不通的锁。目前MySQL默认的配置为1。

    六、自增的过程

    第一种,插入空值的时候

    当innodb_autoinc_lock_mode=0时

    1、申请AUTO_INC锁
    
    2、得到当前的AUTO_INCREMENT值n,并加1
    
    3、执行插入操作,并将n写入新增的对应字段中。
    
    4、释放AUTO_INC锁。

    第二种,插入已经有值的自增

     

    1、插入第一条数据
    
    2、如果失败流程结束
    
    3、如果成功,申请AUTO_INC锁
    
    4、调用set_max函数,修改AUTO_INCREMENT
    
    5、语句结束,释放AUTO_INC锁

    七、存在的问题

    1、复制的问题

    在innodb_autoinc_lock_mode=2的时候,由于是来一个分配一个,故当replication模式为SBR的时候,如果发生Bulk inserts会在分配的时候向其他insert分配,就会出现主从不一致的情况,但是如果改为RBR就不会出现这种情况。

    也就是说在RBR模式下,innodb_autoinc_lock_mode=2是安全的,其他情况还是建议设置为1.

    2、load data的问题

    当使用load data语句的时候,就算innodb_autoinc_lock_mode=1也会退化回0,这是因为为了保证数据的一致性。首先要说一下load data的执行过程,在主库上load data为原始SQL语句,而在从库上会先将文件传输过去在tmp下生成临时问题,然后在执行load data语句。为了保证主库和从库的自增ID的一致性,binlog中会有set insert_ID命令,标明这个load语句的第一行的自增ID值,这样在表锁的情况下,就可以保证一致性了。

    八、insert的补充说明

    1.“INSERT-like”:
    
    INSERT, INSERTSELECT, REPLACE, REPLACESELECT, and LOAD DATA, INSERTVALUES(),VALUES()
    
    2.“Simple inserts”
    
    就是通过分析insert语句可以确定插入数量的insert语句, INSERT, INSERTVALUES(),VALUES()
    
    3.“Bulk inserts”
    
    就是通过分析insert语句不能确定插入数量的insert语句, INSERTSELECT, REPLACESELECT, LOAD DATA
    
    4.“Mixed-mode inserts”
    
    INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');
    
    INSERTON DUPLICATE KEY UPDATE

    九、官方链接

    http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_autoinc_lock_mode 

  • 相关阅读:
    Qt4.7.4下单独编译QtWebkit
    CronHowto Community Ubuntu Documentation
    菜鸟学Python(9):给文件添加内容,得到文件信息
    yet another software souring company based on san franciso
    Get Started With Chickenfoot
    Berkeley DB(四) DB Environment
    搭建SSH框架链接Oracle数据库
    Linux下手动编译安装Apache2.x
    Errore HTTP 404.2 Not Found" IIS 7.5 请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理
    关于二分法中取中间值时向下和向上取整的问题(由大白LA3971想到的)
  • 原文地址:https://www.cnblogs.com/billyxp/p/2871737.html
Copyright © 2020-2023  润新知