MySQL/InnoDB處理AUTO_INCREMENT(一)

http://dev.mysql.com/doc/refman/5.6/en/innodb-auto-increment-handling.html

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官方文檔的描述:http://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,.....]


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章