MySQL自增鎖模式innodb_autoinc_lock_mode參數理解調優

前段時間某數據表運行過程當中,出現自增字段忽然跳躍式增加的問題,潛心研究發現,問題致使緣由多是由於併發寫入致使html

因而經過各類途徑查閱是由於innodb_autoinc_lock_mode參數設置的不一樣表現所在,因而進行了調整,在此對該參數的理解記錄一二。mysql

官方原文地址:https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html#innodb-auto-increment-initializationsql

中文翻譯地址:https://blog.csdn.net/ashic/article/details/53810319安全

其文章中主要說起,mysql的3種插入方式以及innodb_autoinc_lock_mode的3種參數選擇相關內容session

三種模式簡要說明併發

首先,該參數僅在InnoDB引擎下生效,myisam引擎下,不管什麼樣自增id鎖都是表級鎖
0:traditonal (每次都會產生表鎖)
1:consecutive (mysql的默認模式,會產生一個輕量鎖,simple insert會得到批量的鎖,保證連續插入)
2:interleaved (不會鎖表,來一個處理一個,併發最高)高併發

如何理解,以及參數如何選擇?優化

一、innodb_autoinc_lock_mode爲0時的,也就是官方說的traditional級別url

該自增鎖是表鎖級別,且必須等待當前SQL執行完成後或者回滾掉纔會釋放,這樣在高併發的狀況下可想而知自增鎖競爭是比較大的spa

二、innodb_autoinc_lock_mode爲1時的,也就是官方說的consecutive級別

這時若是是單一的insert SQL,能夠當即得到該鎖,並當即釋放,而沒必要等待當前SQL執行完成(除非在其餘事務中已經有session獲取了自增鎖)。另外當SQL是一些批量insert sql時,好比insert into ...select ...,load data,replace ..select..時,這時仍是表級鎖,能夠理解成退化爲必須等待當前SQL執行完才釋放。能夠認爲,該值爲1時是相對比較輕量的鎖,也不會對複製產生影響,惟一的缺陷是產生的自增值不必定是徹底連續的

三、innodb_autoinc_lock_mode爲2時,也就是官方說的interleaved 級別

全部insert種類的SQL均可以立馬得到鎖並釋放,這時的效率最高。可是會引入一個新的問題:當binlog_format爲statement時,這時的複製無法保證安全,由於批量的insert,好比insert ..select..語句在這個狀況下,也能夠立馬獲取到一大批的自增id值,沒必要鎖整個表,slave在回放這個sql時必然會產生錯亂

問題分析

在此咱們看到mysql的默認模式是2,官方表示其是連續插入,但實際上在這一模式simple insert作了優化,因爲simple insert一次性插入值的個數能夠立馬獲得肯定,因此mysql能夠一次生成幾個連續的值,用於這個insert語句,而只要語句獲得了相應的值後就能夠提早釋放鎖,這就致使插入是連續的,但若是插入的語句存在錯誤的話(本次的值已經被分配,下次會增長),實際上自增的字段可能不連續

也就是說該模式只保證插入的連續性,但自增字段的連續性沒法保證,而咱們遇到的問題偏偏是要保證自增字段的連續性。

因而綜合考慮以後咱們啓用了0模式,觀察一段時間以後發現知足咱們的需求,保證了字段的連續性。

至此問題獲得解決。

 

做者:舊舊的 <393210556@qq.com> 解決問題的方式,就是解決它一次

相關文章
相關標籤/搜索