日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

InnoDB自增原理都搞不清楚,还怎么CRUD?

發布時間:2025/3/16 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 InnoDB自增原理都搞不清楚,还怎么CRUD? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

雖然我們習慣于給主鍵ID指定AUTO_INCREMENT屬性,但是AUTO_INCREMENT也是可以指定到非主鍵字段的,唯一的約束就是這個字段上面得加索引,有了索引,就可以通過類似SELECT MAX(*ai_col*)的語句快速讀到這列數據的最大值。

本文要探討的話題是MySql的InnoDB引擎處理自增數據列的原理

MySql 5.1之前的實現

在這個版本之前,用AUTO_INCREMENT修飾的數據列確實是嚴格連續自增的。MySql的實現是會針對每個插入語句加一個全表維度的鎖,這個鎖可以保證每次只有一條插入語句在執行,每插入一行數據,就會生成一個自增數據。

mysql>?CREATE?TABLE?t1?(->?c1?INT?UNSIGNED?NOT?NULL?AUTO_INCREMENT?PRIMARY?KEY,?->?c2?CHAR(1)->?)?ENGINE=InnoDB?AUTO_INCREMENT=100;

假如我們在數據庫中新建上面的這張表,接著我們執行插入語句。

mysql>?INSERT?INTO?t1?(c1,c2)?VALUES?(NULL,'a'),?(NULL,'b'),?(NULL,'c'),?(NULL,'d');

針對這條MySql執行的流程為:

  • 全表加 AUTO-INC鎖

    1.1 生成主鍵ID:101

    1.2 將行(101, 'a')插入表中

    1.3 生成主鍵ID: 102

    1.4 將行(102, 'b')插入表中

    ...

  • 釋放 AUTO-INC鎖

  • MySql5.1之前的這種實現方式可以保證AUTO_INCREMENT嚴格自增,但是并發程度也最差,因為AUTO_INCREMENT鎖是全表加鎖直到這條語句結束

    MySql 5.1版本帶來的優化

    前文中的insert語句是比較簡單的,所謂簡單的insert語句指的是插入的的數據行數是可以提前確定的,與之相對的是Bulk insert比如INSERT ... SELECT這類語句,這類插入語句的插入行數不能提前確定。

    在這個版本以及之后,對于簡單語句的插入,不再加全表的AUTO-INC鎖,只會在產生自增列數據的時候加一個輕量級的互斥鎖,等自增數據分配好,鎖就釋放了,因此像上面的例子,在MySql5.1之后的執行流程如下

  • 加輕量級互斥鎖

    1.1 分配自增數據

  • 釋放鎖

  • 將行(101, 'a')插入表中

  • 將行(102, 'b')插入表中

    ...

  • 可以看到,對于簡單的插入語句,并發情況下的臨界區變小了,且不再持有全表的鎖,提升了并發性能。當然,如果在嘗試加鎖的過程中遇到有其他事務持有全表的AUTO-INC鎖,還是要等待全表的AUTO-INC鎖釋放再執行本次插入操作

    對于Bulk insert的插入語句,仍然避免不了全局的AUTO-INC鎖,這類語句,他們的執行流程仍然保持和5.1之前版本一致,比如以下表為例

    CREATE?TABLE?t1?(c1?INT(11)?NOT?NULL?AUTO_INCREMENT,c2?VARCHAR(10)?DEFAULT?NULL,PRIMARY?KEY?(c1) )?ENGINE=InnoDB;

    執行下面兩條語句

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

    由于在執行Tx1時,InnoDB無法知道要插入的具體行數,因此會獲取一個全表的鎖,每執行一條插入語句就會給自增列賦新的值。因為有全表的鎖,所以Tx1這條語句插入的所有行數都是連續自增的,Tx2自增列的值要么小于Tx1自增列的最小值,要么大于Tx1自增列中的最大值,這取決于這兩條語句的執行順序

    InnoDB采取這樣的決策一個重要的原因是主從復制,在MySql8.0之前,MySql的主從是基于語句復制的。在剛才的例子中,如果Tx1執行的時候沒有全表的鎖,那有可能在Tx1執行的過程中Tx2也在執行,這就會導致Tx1和Tx2自增列的數據每次執行結果都不相同,也就無法在從庫中通過語句回放復制。

    MySql 8.0版本之后的優化

    雖然MySql5.1版本對簡單的插入語句做了優化,避免了全表加鎖,但對于INSERT ... SELECT這樣的復雜插入語句,仍然避免不了全表的AUTO-INC鎖,主要是基于執行語句的主從復制要能在從庫完全回放復制主庫,所有的語句執行結果就不能和執行順序有關。

    在MySql 8.0以及之后默認的主從復制策略變成了基于數據行實現,在這樣的背景下INSERT ... SELECT這樣的復雜插入語句也不需要全表加鎖來生成自增列數據了,所有的插入語句只有在生成自增列數據的時候要求持有一個輕量級的互斥鎖,等到自增數據生成好之后釋放鎖。在這種實現下,所有插入語句的自增列都不能保證連續自增,但是并發性能確實最好的。

    總結

    需要說明的是,如果插入語句所處的事務回滾了,生成的自增列數據是不會回滾的,這種情況下會造成自增列數據非連續增長。

    以上所述都是各個MySql版本的默認實現,MySql 5.1引入了一個新的參數 innodb_autoinc_lock_mode 通過修改這個字段的值,可以改變InnoDB生成自增列的策略,其值總結如下:

    值名稱含義
    0traditional lock mode每次插入語句執行都會全表加鎖至語句結束,5.1版本之前默認實現
    1consecutive lock mode簡單插入不再全表加鎖,INSERT ... SELECT類的語句才持有全表鎖,5.1至8.0默認實現
    2interleaved lock modeINSERT ... SELECT類的語句也不會全表加鎖,只有生成自增列數據時才加鎖,8.0之后默認實現

    不推薦顯式指定自增列數據,因為在5.7以及之前的版本,如果通過update語句顯式指定一個比SELECT MAX(*ai_col*)還大的自增列值,后續insert語句可能會拋"Duplicate entry"錯誤,這一點在8.0版本之后也有了改變,如果通過顯式的update語句顯式指定一個比SELECT MAX(*ai_col*)還大的自增列值,那該值就會被持久化,后續的自增列值都從該值開始生成。

    假如有下面這張表

    mysql>?CREATE?TABLE?t1?(->?c1?INT?UNSIGNED?NOT?NULL?AUTO_INCREMENT?PRIMARY?KEY,?->?c2?CHAR(1)->?)?ENGINE?=?INNODB?AUTO_INCREMENT=100;

    試想,在我們執行完下面這條語句之后表的內容變成了什么?

    mysql>?INSERT?INTO?t1?(c1,c2)?VALUES?(1,'a'),?(NULL,'b'),?(5,'c'),?(NULL,'d');

    MySql 5.1之前,或者innodb_autoinc_lock_mode設置為0

    mysql>?SELECT?c1,?c2?FROM?t1?ORDER?BY?c2; +-----+------+ |?c1??|?c2???| +-----+------+ |???1?|?a????| |?101?|?b????| |???5?|?c????| |?102?|?d????| +-----+------+

    在這種模式下,每插入一行數據就會生成一個自增值賦到c1這一行,因此c1的下一個自增值是103

    MySql 8.0之前,或者innodb_autoinc_lock_mode設置為1

    mysql>?SELECT?c1,?c2?FROM?t1?ORDER?BY?c2; +-----+------+ |?c1??|?c2???| +-----+------+ |???1?|?a????| |?101?|?b????| |???5?|?c????| |?102?|?d????| +-----+------+

    當前表的數據與前一個場景一致,但是下一個自增值卻是105,因為在這個場景下,自增數據是在插入語句執行的最開始一次性生成的

    MySql 8.0之后,或者innodb_autoinc_lock_mode設置為2

    mysql>?SELECT?c1,?c2?FROM?t1?ORDER?BY?c2; +-----+------+ |?c1??|?c2???| +-----+------+ |???1?|?a????| |???x?|?b????| |???5?|?c????| |???y?|?d????| +-----+------+

    在這種場景下,因為同時可能有其他的插入語句執行,因此x和y的值是不確定的,下一個自增值也是未知的。

    有道無術,術可成;有術無道,止于術

    歡迎大家關注Java之道公眾號

    好文章,我在看??

    總結

    以上是生活随笔為你收集整理的InnoDB自增原理都搞不清楚,还怎么CRUD?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲人体一区 | 97在线公开视频 | 中文字幕在线网 | 精品国产一区二区三区四区阿崩 | 亚洲天堂麻豆 | 欧美群妇大交乱 | 夜色88v精品国产亚洲 | av资源免费| 免费无码又爽又黄又刺激网站 | 亚洲六月丁香色婷婷综合久久 | 国产人妻精品久久久久野外 | 欧美色狠 | 成人精品国产免费网站 | av无码久久久久久不卡网站 | 波多野结衣亚洲视频 | 国产97色在线| 一区二区三区色 | 成人黄色免费看 | 新版红楼梦在线高清免费观看 | 激情视频久久 | 在线免费视频你懂的 | 亚洲社区在线观看 | 又污又黄的网站 | 日本熟妇人妻xxxxx | av片子在线观看 | 日韩激情影院 | 国产成人高清视频 | 无码久久av一区二区三区 | 欧洲美熟女乱又伦 | 狠狠躁夜夜躁av无码中文幕 | 欧美一级免费在线 | 天天摸天天操天天射 | caoporen在线 | 涩涩涩在线视频 | 精品国产96亚洲一区二区三区 | 欧美淫视频 | 黄色视屏在线播放 | 国产小视频在线播放 | 草草屁屁影院 | 国产精品亚洲欧美在线播放 | 亚洲天堂影院在线观看 | 欧美三日本三级少妇三 | 欧美人与动牲交a欧美精品 欧美三级在线看 | 国内自拍区 | 国产精品久久久久久久久久东京 | 男人舔女人下部高潮全视频 | 性高跟鞋xxxxhd国产电影 | 四川丰满少妇被弄到高潮 | 国内一级视频 | 欧美一区二区三区不卡视频 | 亚洲视频精品一区 | 国产av不卡一区 | 大又大又粗又硬又爽少妇毛片 | 欧美视频在线观看 | 天天干少妇 | 国产亚洲一区二区三区不卡 | 97综合视频 | 一级免费在线 | 色图网址 | 翔田千里88av中文字幕 | 久久久久亚洲av无码专区喷水 | 亚洲va在线∨a天堂va欧美va | 成人动漫在线观看免费 | 日本三级日本三级日本三级极 | 麻豆国产精品视频 | 欧美另类高清videos的特点 | 国产日批视频 | 欧美巨鞭大战丰满少妇 | 免费网站在线观看人数在哪动漫 | 色人人| 久久久久久久国产精品毛片 | 涩涩涩在线视频 | 99热6这里只有精品 三级av在线免费观看 | 亚洲天堂一区二区在线观看 | 欲求不满在线小早川怜子 | 尤物精品视频在线观看 | www.插插插 | 国产精品国产三级国产在线观看 | 五月天综合网站 | 国产高清sp | 天天干视频在线观看 | 中文字幕人乱码中文字 | 国产69精品久久久久久久 | 欧美精品成人一区二区在线观看 | 日韩女同互慰一区二区 | 新婚之夜玷污岳丰满少妇在线观看 | 日日热| 一区二区高清在线观看 | 色婷婷av一区二区三区软件 | 91欧美大片 | 能在线观看的av网站 | 永久国产 | xxxwww国产 | 欧美.www | 久色精品视频 | 国产丝袜视频在线观看 | 男女啪啪av | 3d动漫啪啪精品一区二区中文字幕 | 自拍偷拍第2页 |