mysql auto_increment 原理_[Mysql]mysql原理之Auto_increment
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
引言
MySQL中auto_increment字段估計(jì)大家都經(jīng)常用到,特別是innodb引擎。我也經(jīng)常用,只知道m(xù)ysql可以保證這個(gè)字段在多進(jìn)程操作時(shí)的原子性,具體原理又是什么,后來(lái)查閱了MySQL手冊(cè)以及相關(guān)資料,了解了個(gè)大概。
本文只探究了mysql5.5中innodb引擎auto_increment的問題。
定義
使用auto_increment的字段可能生成唯一的標(biāo)識(shí)。
如何使用
可在建表時(shí)可用“AUTO_INCREMENT=n”選項(xiàng)來(lái)指定一個(gè)自增的初始值。
可用alter table table_name AUTO_INCREMENT=n命令來(lái)重設(shè)自增的起始值。
使用規(guī)范
AUTO_INCREMENT是數(shù)據(jù)列的一種屬性,只適用于整數(shù)類型數(shù)據(jù)列。
設(shè)置AUTO_INCREMENT屬性的數(shù)據(jù)列應(yīng)該是一個(gè)正數(shù)序列,所以應(yīng)該把該數(shù)據(jù)列聲明為UNSIGNED,這樣序列的編號(hào)個(gè)可增加一倍。
AUTO_INCREMENT數(shù)據(jù)列必須有唯一索引,以避免序號(hào)重復(fù)(即是主鍵或者主鍵的一部分)。
AUTO_INCREMENT數(shù)據(jù)列必須具備NOT NULL屬性。
AUTO_INCREMENT數(shù)據(jù)列序號(hào)的最大值受該列的數(shù)據(jù)類型約束,如TINYINT數(shù)據(jù)列的最大編號(hào)是127,如加上UNSIGNED,則最大為255。一旦達(dá)到上限,
AUTO_INCREMENT就會(huì)失效。
當(dāng)進(jìn)行全表刪除時(shí),MySQL AUTO_INCREMENT會(huì)從1重新開始編號(hào)。全表刪除的意思是發(fā)出以下兩條語(yǔ)句時(shí): delete from table_name;
或者
truncate table table_name
原理(這里面是重點(diǎn))
傳統(tǒng)auto_increment原理
mysql innodb引擎的表中的auto_increment字段是通過在內(nèi)存中維護(hù)一個(gè)auto-increment計(jì)數(shù)器,來(lái)實(shí)現(xiàn)該字段的賦值,注意自增字段必須是索引,而且是索引的第一列,不一定要是主鍵。例如我現(xiàn)在在我的數(shù)據(jù)庫(kù)test中創(chuàng)建一個(gè)表t,語(yǔ)句如下: CREATE TABLE `t_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='測(cè)試表'
則字段a為auto_increment類型,在mysql服務(wù)器啟動(dòng)后,第一次插入數(shù)據(jù)到表t_test時(shí),InnoDB引擎會(huì)執(zhí)行等價(jià)于下面的語(yǔ)句: SELECT MAX(id) FROM t FOR UPDATE;
Innodb獲取到當(dāng)前表中id字段的最大值并將增加1(默認(rèn)是增加1,如果要調(diào)整為增加其他數(shù)目,可以設(shè)置auto_increment_increment這個(gè)配置的設(shè)置)然后賦值給該列以及內(nèi)存中該表對(duì)應(yīng)的計(jì)數(shù)器
在傳統(tǒng)的auto_increment設(shè)置中,每次訪問auto-increment計(jì)數(shù)器的時(shí)候, INNODB都會(huì)加上一個(gè)名為AUTO-INC鎖直到該語(yǔ)句結(jié)束(注意鎖只持有到語(yǔ)句結(jié)束,不是事務(wù)結(jié)束).AUTO-INC鎖是一個(gè)特殊的表級(jí)別的鎖,用來(lái)提升包含auto_increment列的并發(fā)插入性能.因此,兩個(gè)事務(wù)不能同時(shí)獲取同一個(gè)表上面的AUTO-INC鎖,如果持有AUTO-INC鎖太長(zhǎng)時(shí)間可能會(huì)影響到數(shù)據(jù)庫(kù)性能(比如INSERT INTO t1... SELECT ... FROM t2這類語(yǔ)句).
改進(jìn)后
基于上面?zhèn)鹘y(tǒng)方式的問題(性能太差),在mysql5.1開始,新增加了一個(gè)配置項(xiàng)innodb_autoinc_lock_mode來(lái)設(shè)定auto_increment方式.
可以設(shè)置的值為0,1,2.其中0就是第一節(jié)中描述的傳統(tǒng)auto_increment機(jī)制,而1和2則是新增加的模式,默認(rèn)該值為1,可以中mysql配置文件中修改該值.這里主要來(lái)看看這兩種新的方式的差別;
在描述差別前需要先明確幾個(gè)插入類型:
simple inserts
能夠確定具體的插入行數(shù)的語(yǔ)句。
bulk inserts
事先無(wú)法確定插入行數(shù)的語(yǔ)句
mixed-mode inserts
有些行指定了auto_increment列的值有些沒有指定
下面看看設(shè)置innodb_autoinc_lock_mode為不同值時(shí)的情況:
innodb_autoinc_lock_mode=0(traditional lock mode)
傳統(tǒng)的auto_increment機(jī)制,這種模式下所有針對(duì)auto_increment列的插入操作都會(huì)加AUTO-INC鎖,分配的值也是一個(gè)個(gè)分配,是連續(xù)的,正常情況下也不會(huì)有間隙(當(dāng)然如果事務(wù)rollback了這個(gè)auto_increment值就會(huì)浪費(fèi)掉,從而造成間隙)。
innodb_autoinc_lock_mode=1(consecutive lock mode)
這種情況下,針對(duì)bulk inserts才會(huì)采用AUTO-INC鎖這種方式,而針對(duì)simple inserts,則采用了一種新的輕量級(jí)的互斥鎖來(lái)分配auto_increment列的值。當(dāng)然,如果其他事務(wù)已經(jīng)持有了AUTO-INC鎖,則simple inserts需要等待.
需要注意的是,在innodb_autoinc_lock_mode=1時(shí),語(yǔ)句之間是可能出現(xiàn)auto_increment值的間隔的。比如mixed-mode inserts以及bulk inserts中都有可能導(dǎo)致一些分配的auto_increment值被浪費(fèi)掉從而導(dǎo)致間隙。后面會(huì)有例子。
innodb_autoinc_lock_mode=2(interleaved lock mode)
這種模式下任何類型的inserts都不會(huì)采用AUTO-INC鎖,性能最好,但是在同一條語(yǔ)句內(nèi)部產(chǎn)生auto_increment值間隙。此外,這種模式對(duì)statement-based replication也不安全。
總結(jié)
以上是生活随笔為你收集整理的mysql auto_increment 原理_[Mysql]mysql原理之Auto_increment的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ssdp协议 upnp_SSDP 简单服
- 下一篇: Dws同步mysql数据_数据库技术丨G