[Mysql]mysql原理之Auto_increment

引言

MySQL中auto_increment字段估計你們都常常用到,特別是innodb引擎。我也常常用,只知道mysql能夠保證這個字段在多進程操做時的原子性,具體原理又是什麼,後來查閱了MySQL手冊以及相關資料,瞭解了個大概。
本文只探究了mysql5.5中innodb引擎auto_increment的問題。mysql

 

定義

  1. 使用auto_increment的字段可能生成惟一的標識。

如何使用

  1. 可在建表時可用「AUTO_INCREMENT=n」選項來指定一個自增的初始值。
  2. 可用alter table table_name AUTO_INCREMENT=n命令來重設自增的起始值。

使用規範

  1. AUTO_INCREMENT是數據列的一種屬性,只適用於整數類型數據列。
  2. 設置AUTO_INCREMENT屬性的數據列應該是一個正數序列,因此應該把該數據列聲明爲UNSIGNED,這樣序列的編號個可增長一倍。
  3. AUTO_INCREMENT數據列必須有惟一索引,以免序號重複(便是主鍵或者主鍵的一部分)。
  4. AUTO_INCREMENT數據列必須具有NOT NULL屬性。
  5. AUTO_INCREMENT數據列序號的最大值受該列的數據類型約束,如TINYINT數據列的最大編號是127,如加上UNSIGNED,則最大爲255。一旦達到上限,
    AUTO_INCREMENT就會失效。
  6. 當進行全表刪除時,MySQL AUTO_INCREMENT會從1從新開始編號。全表刪除的意思是發出如下兩條語句時:
    delete from table_name;
    或者
    truncate table table_name

原理(這裏面是重點)

傳統auto_increment原理

  1. mysql innodb引擎的表中的auto_increment字段是經過在內存中維護一個auto-increment計數器,來實現該字段的賦值,注意自增字段必須是索引,並且是索引的第一列,不必定要是主鍵。例如我如今在個人數據庫test中建立一個表t,語句以下:
    CREATE TABLE `t_test` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
      PRIMARY KEY (`id`),
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='測試表'
  2. 則字段a爲auto_increment類型,在mysql服務器啓動後,第一次插入數據到表t_test時,InnoDB引擎會執行等價於下面的語句:
    SELECT MAX(id) FROM t FOR UPDATE;
  3. Innodb獲取到當前表中id字段的最大值並將增長1(默認是增長1,若是要調整爲增長其餘數目,能夠設置auto_increment_increment這個配置的設置)而後賦值給該列以及內存中該表對應的計數器
    在傳統的auto_increment設置中,每次訪問auto-increment計數器的時候, INNODB都會加上一個名爲AUTO-INC鎖直到該語句結束(注意鎖只持有到語句結束,不是事務結束).AUTO-INC鎖是一個特殊的表級別的鎖,用來提高包含auto_increment列的併發插入性能.所以,兩個事務不能同時獲取同一個表上面的AUTO-INC鎖,若是持有AUTO-INC鎖太長時間可能會影響到數據庫性能(好比INSERT INTO t1... SELECT ... FROM t2這類語句).

改進後

基於上面傳統方式的問題(性能太差),在mysql5.1開始,新增長了一個配置項innodb_autoinc_lock_mode來設定auto_increment方式.
能夠設置的值爲0,1,2.其中0就是第一節中描述的傳統auto_increment機制,而1和2則是新增長的模式,默認該值爲1,能夠中mysql配置文件中修改該值.這裏主要來看看這兩種新的方式的差異;sql

在描述差異前須要先明確幾個插入類型:數據庫

  1. simple inserts
    可以肯定具體的插入行數的語句。
  2. bulk inserts
    事先沒法肯定插入行數的語句
  3. mixed-mode inserts
    有些行指定了auto_increment列的值有些沒有指定

下面看看設置innodb_autoinc_lock_mode爲不一樣值時的狀況:安全

  1. innodb_autoinc_lock_mode=0(traditional lock mode)
    傳統的auto_increment機制,這種模式下全部針對auto_increment列的插入操做都會加AUTO-INC鎖,分配的值也是一個個分配,是連續的,正常狀況下也不會有間隙(固然若是事務rollback了這個auto_increment值就會浪費掉,從而形成間隙)。
  2. innodb_autoinc_lock_mode=1(consecutive lock mode)
    這種狀況下,針對bulk inserts纔會採用AUTO-INC鎖這種方式,而針對simple inserts,則採用了一種新的輕量級的互斥鎖來分配auto_increment列的值。固然,若是其餘事務已經持有了AUTO-INC鎖,則simple inserts須要等待.
    須要注意的是,在innodb_autoinc_lock_mode=1時,語句之間是可能出現auto_increment值的間隔的。好比mixed-mode inserts以及bulk inserts中都有可能致使一些分配的auto_increment值被浪費掉從而致使間隙。後面會有例子。
  3. innodb_autoinc_lock_mode=2(interleaved lock mode) 這種模式下任何類型的inserts都不會採用AUTO-INC鎖,性能最好,可是在同一條語句內部產生auto_increment值間隙。此外,這種模式對statement-based replication也不安全。
相關文章
相關標籤/搜索