天天看點

MySQL源碼學習:innodb_autoinc_lock_mode 下自增id不連續的原因

一、問題複現

檔案/tmp/data.sql中兩列,每列一個數字1;

輸入

create table `t` (

`id` int(10) unsigned not null auto_increment,

`k` int(10) unsigned not null default '0',

primary key (`id`)

) engine=innodb auto_increment=1 default charset=utf8;

load data infile '/tmp/data.sql' into table t(k);

show create table t;

結果:

) engine=innodb auto_increment=4 default charset=utf8

二、原因分析

我們知道在5.1.22在之後,innodb為了解決自增主鍵鎖表的問題,引入了參數innodb_autoinc_lock_mode。這個值為0時,每次申請自增主鍵時需要鎖表。

這個參數的預設值是1,設為此值時,每次會“預申請”多餘的id(handler.cc: compute_next_insert_id),而insert執行完成後,會特别将這些預留的id空出,動作就是特意将預申請後的目前最大id回寫到表中(dict0dict.c:dict_table_autoinc_update_if_greater)。

三、簡單計算預留

注意這個預留的政策是“不夠時多申請幾個”, 實際執行中是分步申請。至于申請幾個,是由當時“已經插入了幾條資料n”決定的。當auto_increment_offset=1時,預申請的個數是 n-1。

是以會發現,當data.sql中隻有一行時,你看不到這個現象,并不預申請。

而當有兩行時(如文章開頭的例子),則需要。多申請的數目為1,是以執行後的自增值為4 (1+2+1)。

若data.sql中有三行呢?由于執行第三行的id已經在執行第二行時預留了,是以直接使用,結果的自增值仍為4。

後續的就類推了,可自行分析下。

實際insert行

自增id增加值

2、3

3

4、5、6、7

7

8~15

15

繼續閱讀