欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL/InnoDB处理AUTO_INCREMENT(一)

程序员文章站 2022-05-18 14:33:45
mysql/innodb处理auto_increment(一) auto_increment handling in innodb 下面所使用的表 create tabl...

mysql/innodb处理auto_increment(一)

auto_increment handling in innodb

下面所使用的表

create table people  (
    person_id bigint not null auto_increment,
    first_name varchar(20),
    last_name varchar(20),
    primary key (person_id)
);

traditional innodb auto-increment locking

the initialization of auto-increment counter

auto-increment counter的初始化据我的分析存在于三个节点:

服务器启动后表的第一次插入前

通过show table status命令查询表的状态信息,如果auto-increment counter没有初始化,就要在show table status之前初始化。

表新建后,要初始化auto-increment counter。

下面是mysql官方文档的描述:https://dev.mysql.com/doc/refman/5.6/en/innodb-auto-increment-traditional.html

if you specify an auto_increment column for an innodb table, the table handle in the innodb data dictionary contains ????a special counter called the auto-increment counter that is used in assigning new values for the column. this counter is stored only in main memory, not on disk.????

innodb uses the following algorithm to initialize the auto-increment counter for a table t that contains an auto_increment column named ai_col: after a server startup(在服务器启动后,counter的值由于存在内存中,会消失), for the first insert into a table t(对于第一次插入), innodb executes the equivalent(等价的,等效的) of this statement:

select max(ai_col) from t for update;

innodb increments the value retrieved(取回,恢复) by the statement and assigns it to the column and to the auto-increment counter for the table. by default, the value is incremented by one(默认的这个值会增加one). this default can be overridden by the auto_increment_increment configuration setting.

if the table is empty, innodb uses the value 1. this default can be overridden by the auto_increment_offset configuration setting.

if a show table status statement examines(调查) the table t before the auto-increment counter is initialized, innodb initializes but does not increment the value and stores it for use by later inserts. ?this initialization uses a normal exclusive-locking read on the table and the lock lasts to the end of the transaction.?

如下所示,通过truncate将一张表初始化,通过show table status可以看到auto_increment为1,这只是存储到counter中以供下次插入使用的。这个初始化过程会加一个排它锁把表锁住,这个锁会一直持续到事务结束。

mysql> truncate people;
query ok, 0 rows affected (0.54 sec)

mysql> show table status from local_database like 'people'\g
*************************** 1. row ***************************
           name: people
         engine: innodb
        version: 10
     row_format: compact
           rows: 0
 avg_row_length: 0
    data_length: 16384
max_data_length: 0
   index_length: 0
      data_free: 0
 auto_increment: 1
    create_time: 2014-11-04 15:36:51
    update_time: null
     check_time: null
      collation: latin1_swedish_ci
       checksum: null
 create_options:
        comment:
1 row in set (0.00 sec)

mysql> select max(person_id) from people;
+----------------+
| max(person_id) |
+----------------+
|           null |
+----------------+
1 row in set (0.00 sec)

auto-increment counter

accessing the auto-increment counter

最重要的一个概念:table-level auto-inc lock,作用就是当执行一个insert语句时,这个锁会把表锁住,知道这个insert语句执行完成,然后表解锁,而不是等到这个事务结束。

when accessing the auto-increment counter, innodb uses a special table-level auto-inc lock that it keeps to the end of the current sql statement, not to the end of the transaction. the special lock release strategy was introduced to improve concurrency for inserts into a table containing an auto_increment column. nevertheless(然而,尽管如此), two transactions cannot have the auto-inc lock on the same table simultaneously(同时,一起,一齐), which can have a performance(性能) impact(影响) if the auto-inc lock is held for a long time. that might be the case for a statement such as insert into t1 ... select ... from t2 that inserts all rows from one table into another.

auto_increment_increment&&auto_increment_offset

auto_increment_increment:自增值的自增量

auto_increment_offset: 自增值的偏移量

设置了两个值之后,改服务器的自增字段值限定为:

auto_increment_offset + auto_increment_increment*n 的值,其中n>=0,但是上限还是要受定义字段的类型限制。

比如:

auto_increment_offset=1

auto_increment_increment=2

那么id则是所有的奇数[1,3,5,7,.....]

如果:

auto_increment_offset=5

auto_increment_increment=10

那么id则是所有的奇数[5,15,25,35,.....]