MySQL在INSERT IGNORE未新增記錄時避免AUTO_INCREMENT自增

在MySQL5.7中作INSERT IGNORE時發現, 即便INSERT未成功執行, 表的自增主鍵卻自動加1了, 在某些狀況下須要避免這種行爲. 須要修改的變量是 innodb_autoinc_lock_mode, 將其設爲0後, 在INSERT未成功執行時不會自增主鍵.mysql

innodb_autoinc_lock_mode在MySQL各版本的默認值sql

根據MySQL官方手冊的說明: 安全

There are three possible settings for the innodb_autoinc_lock_mode configuration parameter. The settings are 0, 1, or 2, for 「traditional」, 「consecutive」, or 「interleaved」 lock mode, respectively. As of MySQL 8.0, interleaved lock mode (innodb_autoinc_lock_mode=2) is the default setting. Prior to MySQL 8.0, consecutive lock mode is the default (innodb_autoinc_lock_mode=1). 併發

在MySQL8中, 默認值爲 2 (interleaved, 交錯), 在MySQL8之前, 準確地說在8以前, 5.1以後, 默認值爲 1 (consecutive, 連續), 在更早的版本是 0性能

innodb_autoinc_lock_mode的說明優化

這個值主要用於平衡性能與安全(主從的數據一致性), insert主要有如下類型orm

  • simple insert 如insert into t(name) values('test')
  • bulk insert 如load data | insert into ... select .... from ....
  • mixed insert 如insert into t(id,name) values(1,'a'),(null,'b'),(5,'c');

 innodb_autoinc_lock_mode = 0:three

  • 與更高版本的MySQL向後兼容
  • 在這一模式下,全部的insert語句都要在語句開始的時候獲得一個表級的auto_inc鎖,在語句結束的時候才釋放這把鎖,一個事務可能包涵有一個或多個語句
  • 它能保證值分配的可預見性,與連續性,可重複性,這個也就保證了insert語句在複製到slave的時候還能生成和master那邊同樣的值(它保證了基於語句複製的安全)
  • 因爲在這種模式下auto_inc鎖一直要保持到語句的結束,因此這個就影響到了併發的插入

innodb_autoinc_lock_mode = 1:事務

  • 這一模式對simple insert作了優化,因爲simple insert一次性插入值的個數能夠當即肯定, 因此mysql能夠一次生成幾個連續的值用於這個insert語句, 總的來講這個對複製也是安全的(保證了基於語句複製的安全)
  • 這一模式也是MySQL8.0以前的默認模式, 這個模式的好處是auto_inc鎖不要一直保持到語句的結束, 只要語句獲得了相應的值後就能夠提早釋放鎖

innodb_autoinc_lock_mode = 2:rem

  • 因爲這個模式下已經沒有了auto_inc鎖, 因此這個模式下的性能是最好的, 可是它也有一個問題, 就是對於同一個語句來講它所獲得的auto_incremant值可能不是連續的
  • 如今mysql已經推薦把二進制的格式設置成row, 因此在binlog_format不是statement的狀況下這個模式能夠達到最好的性能
相關文章
相關標籤/搜索