MySQL性能(4)—AUTO_INCRMENT鎖機(jī)制(innodb_autoinc_lock_mode參數(shù)配置)

在mysql的InooDB存儲(chǔ)引擎中,常用的是自增(AUTO_INCRMENT)主鍵,因?yàn)镮nnoDB是聚簇索引。

使用自增主鍵可以保證數(shù)據(jù)行是按順序?qū)懭氲摹H羰鞘褂脽o(wú)序的聚簇索引疟呐,例如UUID,不僅索引占用的空間更大东且,而且也會(huì)導(dǎo)致頁(yè)分裂和碎片化現(xiàn)象启具。

引用自—高性能mysql第三版.png

使用自增索引,在高并發(fā)的情況下可能存在性能問(wèn)題珊泳,一個(gè)就是間隙鎖影響性能鲁冯,而另一個(gè)就是AUTO_INCREMENT鎖機(jī)制會(huì)影響性能拷沸。

1. InnoDB中AUTO_INCREMENT處理

若是在InnoDB中使用AUTO_INCREMENT機(jī)制,那么自增列必須是索引的一部分薯演,以便可以等效于對(duì)表進(jìn)行索引查找以獲取最大列值撞芍。

innodb_autoinc_lock_mode配置可以控制在向auto_increment列表插入數(shù)據(jù)時(shí)相關(guān)鎖的行為以及主從數(shù)據(jù)一致性的平衡。

1.1 插入(INSERT LIKE)的分類

1.1.1. Simple inserts(簡(jiǎn)單插入)

是可以預(yù)先確定將要插入行數(shù)的insert語(yǔ)句跨扮,包括單行和多行INSERT語(yǔ)句序无,例如INSERT, INSERT … VALUES(),VALUES()語(yǔ)法。

1.1.2. Bulk inserts(大量插入)

事先不知道要插入的行數(shù)的語(yǔ)句衡创,包括INSERT ... SELECT帝嗡,REPLACE ... SELECTLOAD DATA語(yǔ)句,但不是純INSERT璃氢,每處理一行時(shí)哟玷,一次為一列分配新增的AUTO_INCRMENT

1.1.3. Mixed inserts(混合模式插入)

  • 一些特殊的“簡(jiǎn)單插入”語(yǔ)句一也,用于指定部分(但不是全部)新行的自動(dòng)增量值巢寡,例如INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
  • 例如INSERT … ON DUPLICATE KEY UPDATE椰苟,在最壞的情況下實(shí)際上是INSERT緊跟著UPDATE抑月,其中AUTO_INCREMENT在更新階段可能會(huì)或者不會(huì)使用為列分配的值。

1.2 innodb_autoinc_lock_mode配置

1.2.1. 版本更新:

  • 在mysql5.1.22版本之前尊剔,是不支持innodb_autoinc_lock_mode配置的。
  • 在mysql8.0之前菱皆,默認(rèn)innodb_autoinc_lock_mode=1须误,即連續(xù)鎖定模式。
  • 在mysql8.0開(kāi)始仇轻,默認(rèn)innodb_autoinc_lock_mode=2京痢,即交錯(cuò)鎖定模式。

因?yàn)镸ysql8.0之前篷店,備份(binlog)默認(rèn)是基于語(yǔ)句(statement模式)的復(fù)制祭椰。而Mysql8.0開(kāi)始,binlog默認(rèn)是基于行(row模式)的復(fù)制疲陕。

基于語(yǔ)句的復(fù)制需要連續(xù)的自動(dòng)增量鎖定模式方淤,以確保為給定的SQL語(yǔ)句序列以可預(yù)測(cè)和可重復(fù)的順序分配自動(dòng)增長(zhǎng)值。而基于行的復(fù)制對(duì)SQL語(yǔ)句的執(zhí)行順序不敏感蹄殃。

1.2.2. 配置詳情

innodb_autoinc_lock_mode = 0 (“ 傳統(tǒng) ”鎖定模式)

該模式是Mysql5.1之前未引入innodb_autoinc_lock_mode配置參數(shù)時(shí)的行為携茂,提供了傳統(tǒng)的鎖定模式選項(xiàng)以實(shí)現(xiàn)向后兼容。

在這種模式下诅岩,所有INSERT語(yǔ)句(INSERT LIKE)都會(huì)獲得特殊的表級(jí)AUTO-INC鎖定讳苦,將其插入具有AUTO_INCREMENT列的表中带膜。此鎖定通常保持在語(yǔ)句的末尾(而不是事務(wù)的末尾)。

舉例分析:假設(shè)有兩個(gè)事務(wù)正在運(yùn)行鸳谜,每個(gè)事務(wù)都將行插入具有AUTO_INCREMENT列的表中膝藕。一個(gè)事務(wù)使用insert ... select插入1000行的語(yǔ)句,另一事務(wù)使用insert插入一個(gè)行的簡(jiǎn)單語(yǔ)句:

Tx1: INSERT INTO t1 (c2) SELECT 1000 rows from another table ...
Tx2: INSERT INTO t1 (c2) VALUES ('xxx');

InooDB無(wú)法預(yù)先判斷Tx1會(huì)插入多少行咐扭,Tx1使用表級(jí)鎖(保持在該語(yǔ)句的末尾)去阻塞Tx2的并發(fā)執(zhí)行芭挽,Tx1每次插入時(shí)均分配一個(gè)自增id,最終t1語(yǔ)句生成的遞增主鍵是連續(xù)的草描。在主從復(fù)制或者故障恢復(fù)時(shí)览绿,若binlog使用statement模式(基于語(yǔ)句的復(fù)制),主從服務(wù)器執(zhí)行insert語(yǔ)句得到的結(jié)果是完全相同的穗慕。

innodb_autoinc_lock_mode = 1 (“ 連續(xù) ”鎖定模式)

Mysql5.1.2-Mysql8.0innodb_autoinc_lock_mode的默認(rèn)配置饿敲。

  • simple inserts:直接通過(guò)分析語(yǔ)句,獲取要插入的的數(shù)量逛绵,然后一次性分配足夠的auto_increment id怀各,只會(huì)將整個(gè)分配過(guò)程鎖住。
  • Bulk inserts:[[b?lk]]因?yàn)椴荒艽_定插入的數(shù)量术浪,因此還會(huì)將表鎖灼岸浴;
  • Mixed-mode inserts:直接分析語(yǔ)句胰苏,獲取最壞情況下需要插入的數(shù)量硕蛹,然后一次性分配足夠的auto increment id,只會(huì)將整個(gè)分配過(guò)程鎖住硕并。

innodb_autoinc_lock_mode = 2 (“交叉”鎖定模式)

這種模式下插入語(yǔ)句(INSERT LIKE)來(lái)一個(gè)分配一個(gè)法焰,而不會(huì)鎖表,只會(huì)鎖住分配ID的過(guò)程倔毙,和innodb_autoinc_lock_mode = 1區(qū)別bulk insert是不會(huì)預(yù)分配多個(gè)埃仪,這種方式的并發(fā)性最高。

若是binlog的模式為statement模式陕赃,由于并發(fā)情況下Bulk inserts在分配的時(shí)會(huì)同時(shí)向其他insert分配卵蛉,會(huì)出現(xiàn)主從不一致的情況。

所以需要配合binlogrow模式使用么库。

2. InnoDB的自增主鍵特性

  1. 主從復(fù)制下鎖定策略

如果binlog為statement模式(基于語(yǔ)句的復(fù)制)傻丝,請(qǐng)將innodb_autoinc_lock_mode設(shè)置為0或1,并在主設(shè)備及從設(shè)備上使用相同的值诉儒。
如果binlog是row模式或者mixed模式桑滩,則innodb_autoinc_lock_mode均是安全的。因?yàn)榛谛械膹?fù)制對(duì)于SQL語(yǔ)句的執(zhí)行順序不敏感。

  1. “丟失”自增值和序列間隙

在所有鎖定模式(0,1和2)中运准,如果生成自增值的事務(wù)回滾幌氮,則這些自增值將“丟失”。為自動(dòng)遞增列生成值后胁澳,無(wú)論“INSERT like”語(yǔ)句是否完成该互,以及包含的事務(wù)是否回滾,都無(wú)法回滾該值韭畸。這樣丟失的值不會(huì)被重用宇智。因此,自增列中的值有間隙胰丁。

  1. 自增列上的NULL和0

在所有鎖模式(0,1和2)中随橘,如果用戶未INSERT中的AUTO_INCREMENT列指定NULL或0,InnoDB會(huì)將該行視為未指定值并為其生成新值锦庸。

  1. 為自動(dòng)遞增列指定負(fù)值

在所有鎖定模式(0,1和2)中机蔗,如果為“auto_increment”列指定負(fù)值,則自增特性不會(huì)生效(持久化的為負(fù)值)甘萧。

  1. “大量插入(bulk inserts)”下自增列與間隙

當(dāng)innodb_autoinc_lockm_mode設(shè)置為0或1時(shí)萝嘁,任何給定語(yǔ)句生成的自增值都是連續(xù)的,沒(méi)有間隙扬卷。因?yàn)闀?huì)使用表鎖一直到語(yǔ)句結(jié)束牙言,并且一次只能執(zhí)行一個(gè)這樣的語(yǔ)句。

在innodb_autoinc_lockm_mode=2的情況下怪得,在“bulk inserts”并發(fā)執(zhí)行時(shí)咱枉,生成的自增列可能存在間隙。

6. 更新自增列的值

第一步:插入數(shù)據(jù)(0和null會(huì)執(zhí)行自增策略)

create table t(x int auto_increment not null primary key);
insert into t(x) values(0),(null),(3);
select * from t;
+---+
| x |
+---+
| 1 |
| 2 |
| 3 |
+---+

第二步:修改sql中的自增列徒恋。

update t set x=4 where x=1;
select * from t;
+---+
| x |
+---+
| 2 |
| 3 |
| 4 |
+---+

第三步:再次插入

insert into t(x) values(0);
ERROR 1062 (23000): Duplicate entry '4' for key 'PRIMARY'

第四步:分析

執(zhí)行完第一步后蚕断,mysql的自增序列生成器知道下一個(gè)自增值為4;

執(zhí)行第二步因谎,mysql并不知道自增列4已經(jīng)被人占用基括,所以執(zhí)行第三步的時(shí)候就出現(xiàn)異常颜懊。

官方文檔

官方文檔—InnoDB中的AUTO_INCREMENT處理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末财岔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子河爹,更是在濱河造成了極大的恐慌匠璧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咸这,死亡現(xiàn)場(chǎng)離奇詭異夷恍,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)媳维,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)酿雪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)遏暴,“玉大人,你說(shuō)我怎么就攤上這事指黎∨罅梗” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵醋安,是天一觀的道長(zhǎng)杂彭。 經(jīng)常有香客問(wèn)我,道長(zhǎng)吓揪,這世上最難降的妖魔是什么亲怠? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮柠辞,結(jié)果婚禮上团秽,老公的妹妹穿的比我還像新娘。我一直安慰自己钾腺,他們只是感情好徙垫,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著放棒,像睡著了一般姻报。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上间螟,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天吴旋,我揣著相機(jī)與錄音,去河邊找鬼厢破。 笑死荣瑟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的摩泪。 我是一名探鬼主播笆焰,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼见坑!你這毒婦竟也來(lái)了嚷掠?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荞驴,失蹤者是張志新(化名)和其女友劉穎不皆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體熊楼,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡霹娄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片犬耻。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踩晶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出枕磁,到底是詐尸還是另有隱情合瓢,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布透典,位于F島的核電站晴楔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏峭咒。R本人自食惡果不足惜税弃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凑队。 院中可真熱鬧则果,春花似錦、人聲如沸漩氨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叫惊。三九已至款青,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間霍狰,已是汗流浹背抡草。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔗坯,地道東北人康震。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像宾濒,于是被迫代替她去往敵國(guó)和親腿短。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容