精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

為什么 MySQL 的自增主鍵不單調也不連續

數據庫 MySQL
當我們在使用關系型數據庫時,主鍵(Primary Key)是無法避開的概念,主鍵的作用就是充當記錄的標識符,我們能夠通過標識符在一張表中定位到唯一的記錄。

當我們在使用關系型數據庫時,主鍵(Primary Key)是無法避開的概念,主鍵的作用就是充當記錄的標識符,我們能夠通過標識符在一張表中定位到唯一的記錄。

在關系型數據庫中,我們會選擇記錄中多個字段的最小子集作為該記錄在表中的唯一標識符[^1],根據關系型數據庫對主鍵的定義,我們既可以選擇單個列作為主鍵,也可以選擇多個列作為主鍵,但是主鍵在整個記錄中必須存在并且唯一。最常見的方式當然是使用 MySQL 默認的自增 ID 作為主鍵,雖然使用其他策略設置的主鍵也是合法的,但是不是通用的以及推薦的做法。

圖 1 - MySQL 的主鍵

MySQL 中默認的 AUTO_INCREMENT 屬性在多數情況下可以保證主鍵的連續性,我們通過 show create table 命令可以在表的定義中能夠看到 AUTO_INCREMENT屬性的當前值,當我們向當前表中插入數據時,它會使用該屬性的值作為插入記錄的主鍵,而每次獲取該值也都會將它加一。

  1. CREATE TABLE `trades` ( 
  2.   `id` bigint(20) NOT NULL AUTO_INCREMENT, 
  3.   ... 
  4.   `created_at` timestamp NULL DEFAULT NULL, 
  5.   PRIMARY KEY (`id`), 
  6. ENGINE=InnoDB AUTO_INCREMENT=17130 DEFAULT CHARSET=utf8mb4 

在很多開發者的認知中,MySQL 的主鍵都應該是單調遞增的,但是在我們與 MySQL 打交道的過程中會遇到兩個問題,首先是記錄的主鍵并不連續,其次是可能會創建多個主鍵相同的記錄,我們將從以下的兩個角度回答 MySQL 不單調和不連續的原因:

  • 較早版本的 MySQL 將 AUTO_INCREMENT 存儲在內存中,實例重啟后會根據表中的數據重新設置該值;
  • 獲取 AUTO_INCREMENT 時不會使用事務鎖,并發的插入事務可能出現部分字段沖突導致插入失敗;

需要注意的是,我們在這篇文章中討論的是 MySQL 中最常見的 InnoDB 存儲引擎,MyISAM 等其他引擎提供的 AUTO_INCREMENT 實現原理不在本文的討論范圍中。

刪除記錄

AUTO_INCREMENT 屬性雖然在 MySQL 中十分常見,但是在較早的 MySQL 版本中,它的實現還比較簡陋,InnoDB 引擎會在內存中存儲一個整數表示下一個被分配到的 ID,當客戶端向表中插入數據時會獲取 AUTO_INCREMENT 值并將其加一。

圖 2 - AUTO_INCREMENT 的使用

因為該值存儲在內存中,所以在每次 MySQL 實例重新啟動后,當客戶端第一次向 table_name 表中插入記錄時,MySQL 會使用如下所示的 SQL 語句查找當前表中 id 的最大值,將其加一后作為待插入記錄的主鍵,并作為當前表中 AUTO_INCREMENT 計數器的初始值[^2]。

  1. SELECT MAX(ai_col) FROM table_name FOR UPDATE; 

如果讓作者實現 AUTO_INCREMENT,在最開始也會使用這種方法。不過這種實現雖然非常簡單,但是如果使用者不嚴格遵循關系型數據庫的設計規范,就會出現如下所示的數據不一致的問題:

圖 3 - 5.7 版本之前的 AUTO_INCMRENT

因為重啟了 MySQL 的實例,所以內存中的 AUTO_INCREMENT 計數器會被重置成表中的最大值,當我們再向表中插入新的 trades 記錄時會重新使用 10 作為主鍵,主鍵也就不是單調的了。在新的 trades 記錄插入之后,executions 表中的記錄就錯誤的引用了新的 trades,這其實是一個比較嚴重的錯誤。

然而這也不完全是 MySQL 的問題,如果我們嚴格遵循關系型數據庫的設計規范,使用外鍵處理不同表之間的聯系,就可以避免上述問題,因為當前 trades 記錄仍然有外部的引用,所以外鍵會禁止 trades 記錄的刪除,不過多數公司內部的 DBA 都不推薦或者禁止使用外鍵,所以確實存在出現這種問題的可能。

然而在 MySQL 8.0 中,AUTO_INCREMENT 計數器的初始化行為發生了改變,每次計數器的變化都會寫入到系統的重做日志(Redo log)并在每個檢查點存儲在引擎私有的系統表中[^3]。

In MySQL 8.0, this behavior is changed. The current maximum auto-increment counter value is written to the redo log each time it changes and is saved to an engine-private system table on each checkpoint. These changes make the current maximum auto-increment counter value persistent across server restarts.

當 MySQL 服務被重啟或者處于崩潰恢復時,它可以從持久化的檢查點和重做日志中恢復出最新的 AUTO_INCREMENT 計數器,避免出現不單調的主鍵也解決了這里提到的問題。

并發事務

為了提高事務的吞吐量,MySQL 可以處理并發執行的多個事務,但是如果并發執行多個插入新記錄的 SQL 語句,可能會導致主鍵的不連續。如下圖所示,事務 1 向數據庫中插入 id = 10 的記錄,事務 2 向數據庫中插入 id = 11 和 id = 12 的兩條記錄:

圖 4 - 并發事務的執行

不過如果在最后事務 1 由于插入的記錄發生了唯一鍵沖突導致了回滾,而事務 2 沒有發生錯誤而正常提交,在這時我們會發現當前表中的主鍵出現了不連續的現象,后續新插入的數據也不再會使用 10 作為記錄的主鍵。

圖 5 - 不連續的主鍵

這個現象背后的原因也很簡單,雖然在獲取 AUTO_INCREMENT 時會加鎖,但是該鎖是語句鎖,它的目的是保證 AUTO_INCREMENT 的獲取不會導致線程競爭,而不是保證 MySQL 中主鍵的連續[^4]。

上述行為是由 InnoDB 存儲引擎提供的 innodb_autoinc_lock_mode 配置控制的,該配置決定了獲取 AUTO_INCREMENT 計時器時需要先得到的鎖,該配置存在三種不同的模式,分別是傳統模式(Traditional)、連續模式(Consecutive)和交叉模式(Interleaved)[^5],其中 MySQL 使用連續模式作為默認的鎖模式:

(1) 傳統模式 innodb_autoinc_lock_mode = 0;

在包含 AUTO_INCREMENT 屬性的表中插入數據時,所有的 INSERT 語句都會獲取表級別的 AUTO_INCREMENT 鎖,該鎖會在當前語句執行后釋放;

(2) 連續模式 innodb_autoinc_lock_mode = 1;

  • INSERT ... SELECT、REPLACE ... SELECT 以及 LOAD DATA 等批量的插入操作需要獲取表級別的 AUTO_INCREMENT 鎖,該鎖會在當前語句執行后釋放;
  • 簡單的插入語句(預先知道插入多少條記錄的語句)只需要獲取獲取 AUTO_INCREMENT 計數器的互斥鎖并在獲取主鍵后直接釋放,不需要等待當前語句執行完成;

(3) 交叉模式 innodb_autoinc_lock_mode = 2;

所有的插入語句都不需要獲取表級別的 AUTO_INCREMENT 鎖,但是當多個語句插入的數據行數不確定時,可能存在分配相同主鍵的風險;

這三種模式都不能解決 MySQL 自增主鍵不連續的問題,想要解決這個問題的終極方案是串行執行所有包含插入操作的事務,也就是使用數據庫的最高隔離級別 —— 可串行化(Serialiable)。當然直接修改數據庫的隔離級別相對來說有些簡單粗暴,基于 MySQL 或者其他存儲系統實現完全串行的插入也可以保證主鍵在插入時的連續,但是仍然不能避免刪除數據導致的不連續。

總結

早期 MySQL 的主鍵既不是單調的,也不是連續的,這些都是在當時工程上做出的一些選擇,如果嚴格地按照關系型數據庫的設計規范,MySQL 最初的設計造成問題的概率也比較低,只有當被刪除的主鍵被外部系統引用時才會影響數據的一致性,但是今天使用方式的不同卻增加出錯的可能性,而 MySQL 也在 8.0 中持久化了 AUTO_INCREMENT 以避免該問題的出現。

MySQL 中不連續的主鍵又是一個工程設計向性能低頭的例子,犧牲主鍵的連續性來支持數據的并發插入,最終提高了 MySQL 服務的吞吐量,作者在幾年前剛剛使用 MySQL 時就遇到過這個問題,但是當時并沒有深究背后的原因,今天重新理解該問題背后的設計決策也是個非常有趣的過程。我們在這里簡單總結一下本文的內容,重新回到今天的問題 — 為什么 MySQL 的自增主鍵不單調也不連續:

  • MySQL 5.7 版本之前在內存中存儲 AUTO_INCREMENT計數器,實例重啟后會根據表中的數據重新設置,在刪除記錄后重啟就可能出現重復的主鍵,該問題在 8.0 版本使用重做日志解決,保證了主鍵的單調性;
  • MySQL 插入數據獲取 AUTO_INCREMENT 時不會使用事務鎖,而是會使用互斥鎖,并發的插入事務可能出現部分字段沖突導致插入失敗,想要保證主鍵的連續需要串行地執行插入語句;

到最后,我們還是來看一些比較開放的相關問題,有興趣的讀者可以仔細思考一下下面的問題:

  • MyISAM 和其他的存儲引擎如何存儲 AUTO_INCREMENT 計數器?
  • MySQL 中的 auto_increment_increment 和 auto_increment_offset 是用來做什么的?

 

責任編輯:趙寧寧 來源: 真沒什么邏輯
相關推薦

2023-12-26 01:09:28

MySQL存儲釋放鎖

2020-05-06 15:02:58

MySQL數據庫技術

2020-06-09 09:19:14

數據庫

2023-10-24 15:27:33

Mysql自增主鍵

2021-09-28 17:48:20

MySQL主鍵索引

2022-12-06 09:00:11

MySQL自增主鍵查詢

2020-05-11 10:48:01

技術資訊

2022-07-03 22:00:49

MySQL自增值數據

2022-12-27 08:39:54

MySQL主鍵索引

2009-09-24 13:49:31

Hibernate自增

2010-08-31 08:38:55

SQL Server

2022-06-14 08:01:43

數據庫MySQL

2024-05-29 09:05:17

2025-07-03 02:15:00

MySQLID+UUIDB+樹

2010-06-04 11:15:23

MySQL自增主鍵

2024-06-07 10:14:23

2024-12-25 15:32:29

2021-01-26 21:00:24

SSL證書網絡安全加密

2024-10-24 09:22:30

2020-08-31 11:20:53

MySQLuuidid
點贊
收藏

51CTO技術棧公眾號

亚洲AV无码国产精品| 国产精品理伦片| 亚洲成人久久影院| 精品丝袜一区二区三区| 影音先锋男人的网站| 一级片中文字幕| 精品国产伦一区二区三区观看说明| 91偷拍与自偷拍精品| 欧美精品在线免费播放| 三上悠亚在线一区二区| 污视频网站免费观看| 亚洲色图欧美| 欧美日韩国产片| 欧美在线3区| 日韩精品无码一区二区| 国产日本亚洲| 国产精品国产a级| 国产精品福利无圣光在线一区| 折磨小男生性器羞耻的故事| 99福利在线| 精品国产乱码| 欧美天堂在线观看| 国产区日韩欧美| 久久久精品国产sm调教网站| 99久久久国产| 亚洲三级在线免费| 成人网中文字幕| 四虎地址8848| 日本免费一区二区三区等视频| 久久久精品免费网站| 欧美一级免费视频| 亚洲综合自拍网| 国产精品yjizz视频网| 成人一区二区在线观看| 久久久久久美女| 国产二级一片内射视频播放| 里番在线播放| 成人高清视频在线| 午夜精品视频在线| 加勒比精品视频| 日韩欧美高清一区二区三区| 一区二区三区四区激情| av噜噜色噜噜久久| 国产无遮挡又黄又爽又色| 国产一区二区在线视频你懂的| 亚洲高清在线视频| 日本福利视频导航| 国内精品偷拍视频| 亚洲人人精品| 亚洲天堂av女优| 中日韩av在线播放| 中文字幕中文字幕在线十八区| 久久久亚洲午夜电影| 国产精品高清一区二区三区| 国产精品老女人| 欧美日韩三级电影在线| 日韩一区二区三区电影在线观看 | 成人偷拍自拍| 一区二区免费视频| 国产伦精品一区二区三| 国内精品国产成人国产三级| 久久 天天综合| 欧美国产精品人人做人人爱| 一级性生活大片| 日本亚洲欧洲无免费码在线| 欧美在线制服丝袜| 桥本有菜av在线| 三区四区电影在线观看| 国产成人免费在线观看不卡| 性视频1819p久久| 久久在线视频精品| 最新成人av网站| 91精品国产91久久| 国产免费嫩草影院| av在线亚洲一区| 欧美一区二区三区视频免费 | 在线观看a视频| 国产精品人成在线观看免费| 影音先锋在线亚洲| 手机av在线免费观看| 欧美在线播放| 亚洲网站在线播放| 无码人妻一区二区三区一| 乡村艳史在线观看| 亚洲美女区一区| 秋霞毛片久久久久久久久| 狠狠色伊人亚洲综合网站l| 国产不卡在线播放| 国产中文字幕亚洲| 六月丁香激情综合| 欧美成人有码| 国内精品伊人久久| 国产一区二区视频在线观看免费| 欧美日本成人| 日韩h在线观看| 91av免费观看| 中文成人在线| 欧美精品一区二区三区四区| 九九热精品国产| 日本欧美韩国| 欧美视频精品一区| 中文字幕有码av| 欧美动物xxx| 天天色综合成人网| 给我免费播放片在线观看| www视频在线看| 综合自拍亚洲综合图不卡区| 亚洲欧美日韩国产成人综合一二三区 | 日本中文字幕精品| 91精品在线视频观看| 精品国产一区探花在线观看| 有坂深雪av一区二区精品| 久久riav二区三区| 性做久久久久久久| 国产剧情久久久| 成人嘿咻视频免费看| 亚洲精品美女免费| 免费看污片的网站| 婷婷成人在线| 精品亚洲国产成av人片传媒| 蜜桃视频最新网址| 欧美午夜免费影院| 国产精品视频成人| 在线观看免费视频一区| 亚洲成人精选| 欧美成人第一页| 在线观看日本视频| 爽爽淫人综合网网站| 日本精品视频网站| 69xxxx国产| 日韩精品成人一区二区在线| 国产精品福利网站| 日日夜夜精品免费| 亚洲免费观看高清完整版在线观看熊 | 韩国av在线免费观看| 国产在线不卡一区| 3d精品h动漫啪啪一区二区 | 精品国产乱码久久久久久影片| 日本爱爱爱视频| 波多野结衣一区| 亚州av一区二区| 国产成人三级在线观看视频| 中文字幕亚洲一区二区va在线| 久久精品香蕉视频| 久久精品资源| 日韩免费电影网站| 国产福利在线观看视频| 欧美性色综合| 99精品99久久久久久宅男| 黄色片免费在线观看| 亚洲最大色网站| 在线一区二区不卡| 成人h动漫精品一区二区器材| 久久激情视频免费观看| 久久久久久久久精| 国产精品系列在线观看| 国产视频不卡| 牛牛精品视频在线| 精品国产乱码久久久久久蜜臀| 国产盗摄一区二区三区在线| 狠狠色狠狠色合久久伊人| y111111国产精品久久婷婷| v片在线观看| 日韩午夜小视频| 免费一级a毛片夜夜看| 免费永久网站黄欧美| 国产女精品视频网站免费| 亚洲欧美国产高清va在线播放| 亚洲精品自拍动漫在线| japan高清日本乱xxxxx| 欧美成人亚洲| 国内精品二区| 神马电影网我不卡| 正在播放欧美视频| www..com国产| 国产又黄又大久久| 成人在线观看毛片| 精品成人免费一区二区在线播放| 日韩久久精品成人| 亚洲免费视频二区| 99久久亚洲一区二区三区青草| 亚洲欧洲一区二区福利| 久久精品xxxxx| 欧美黄色免费网站| 手机福利小视频在线播放| 中文字幕在线观看不卡| 欧美在线a视频| 精品动漫3d一区二区三区免费版 | 成人精品免费在线观看| 91美女福利视频| 中文字幕国内自拍| 欧美极品一区二区三区| 国产一区在线免费| 欧美va在线观看| 欧美精品一区二区三区蜜桃| www.国产成人| 国产精品全国免费观看高清| 岛国精品一区二区三区| 日韩精品视频网站| 青草全福视在线| 久久99视频| 91精品国产一区二区三区动漫| av资源中文在线天堂| 日韩精品一区在线| 中文字幕超碰在线| 亚洲品质自拍视频| 小早川怜子久久精品中文字幕| 韩国一区二区视频| 99爱视频在线| 日本亚洲不卡| 91精品国产一区| 香蕉视频在线看| 日韩成人激情视频| 国产精品综合在线| 91久久精品网| 天堂在线中文视频| 日韩精彩视频在线观看| 大片在线观看网站免费收看| 精品国产1区| 国内精品视频免费| 欧美特黄不卡| 国产伦精品免费视频| 亚洲国产福利| 久久久久久亚洲精品| 国产在线一区二区视频| 亚洲天堂免费视频| 天天色棕合合合合合合合| 欧美一卡二卡三卡四卡| 一级黄色片在线观看| 色综合天天做天天爱| mm131丰满少妇人体欣赏图| 国产成人在线视频网站| 182午夜在线观看| 久久久综合网| 少妇无码av无码专区在线观看| 欧美有码在线| 成人免费视频网站| 蜜桃av在线播放| 亚洲视频欧美视频| 五月婷婷激情在线| 精品国产一区二区三区四区四 | 天堂va蜜桃一区二区三区| 日韩人妻无码精品久久久不卡| 成人av地址| 91精品免费| 国产美女亚洲精品7777| 国产区亚洲区欧美区| 69堂精品视频在线播放| 国产精品96久久久久久| 麻豆视频在线观看免费网站| 欧美一级欧美三级在线观看 | 日韩精品一区二区三区中文不卡| 日本一区二区三区久久| 在线观看欧美精品| 日韩xxx视频| 欧美日韩精品二区第二页| 伊人网综合在线| 一区二区三区四区高清精品免费观看 | 日韩av资源在线| 成人免费看片39| 性欧美videosex高清少妇| 日韩在线观看中文字幕| 2022国产精品| 一区二区三区四区高清视频 | 国产精品啪啪啪视频| 一区二区三区网站| 国产乱子伦精品视频| 伊人久久大香线蕉| 亚洲va欧美va国产综合久久| 国产激情在线播放| 97视频国产在线| 中文字幕在线看片| 国产精品黄色av| 四虎影视成人精品国库在线观看| 91美女福利视频高清| 自拍偷拍亚洲视频| 国产成人精品免费视频| 久久天天久久| 51成人做爰www免费看网站| 国产精品对白| 欧美一区二区三区成人久久片| 欧美日韩国产在线观看网站 | 成人精品在线观看视频| 久久日韩粉嫩一区二区三区| 99视频在线观看视频| 福利一区二区在线| 亚洲av综合一区二区| 成人的网站免费观看| 国产ts丝袜人妖系列视频| 中文字幕不卡在线| 精品人妻一区二区三区日产乱码卜| 2023国产精品视频| 欧美h片在线观看| 中文字幕不卡在线观看| 久久精品视频免费在线观看| 国产精品成人免费精品自在线观看| 国内毛片毛片毛片毛片毛片| 亚洲福利视频一区二区| 伊人久久中文字幕| 欧美三级xxx| 伊人网综合在线| 亚洲国产日韩欧美在线动漫| 成人免费视频国产| 亚洲图片欧洲图片av| 男女视频在线| 国产精品爽爽ⅴa在线观看| aaa国产精品视频| 亚洲国产精品视频一区| 亚洲黄色一区| gogogo高清免费观看在线视频| 99视频超级精品| 永久久久久久久| 在线一区二区观看| 日韩中文字幕免费在线观看| 日韩精品中文字幕在线一区| 黄色在线免费观看大全| 欧美第一页在线| 日本一区二区三区中文字幕| 久久综合毛片| 久久综合亚洲| 欧美高清中文字幕| 影音先锋中文字幕一区| 亚洲这里只有精品| 久久综合色8888| 久久精品国产亚洲av无码娇色| 日韩精品亚洲一区二区三区免费| 日韩一区二区三区不卡视频| 91视频观看视频| 欧美日韩精品在线观看视频| 午夜精品免费在线| 日本少妇裸体做爰| 黑人精品xxx一区一二区| 日韩中文字幕在线观看视频| 日韩视频免费直播| 欧美成人视屏| 国产精品免费一区| 国产亚洲一区二区三区不卡| 亚洲精品影院| 久热精品视频| 巨胸大乳www视频免费观看| 亚洲综合清纯丝袜自拍| 一区二区久久精品66国产精品| 亚洲视频在线看| 香蕉视频亚洲一级| 蜜桃av色综合| 亚洲在线网站| aaaaa级少妇高潮大片免费看| 香蕉成人啪国产精品视频综合网| 国产成人精品免费看视频| 久久精品99久久久香蕉| 亚洲青青久久| 超级碰在线观看| 国产精品66部| 妺妺窝人体色www婷婷| 日韩欧美二区三区| 日韩精品卡一| 国产精品18久久久久久麻辣| 亚洲精品国产setv| 欧美日韩一区二区在线免费观看| 久久视频一区二区| 区一区二在线观看| 在线色欧美三级视频| 深夜国产在线播放| 成人9ⅰ免费影视网站| 国内精品美女在线观看| 污污视频网站免费观看| 日韩电影在线看| 国产人妻大战黑人20p| 欧美午夜精品电影| 欧美一区二区三区黄片| 久久免费成人精品视频| 日韩精选在线| 黑森林精品导航| 亚洲人吸女人奶水| 亚洲第一天堂影院| 97在线视频国产| 精品久久久久久久久久久下田| 一道本在线免费视频| 尤物av一区二区| 婷婷五月综合久久中文字幕| 青青a在线精品免费观看| 伊人久久大香线蕉av超碰| 亚洲精品蜜桃久久久久久| 26uuu久久综合| 亚洲图片欧美在线| 欧美激情在线观看视频| 亚洲电影一级片| 天天干天天av| 亚洲福利一二三区| 成人高清在线| 国产精品69久久| 伊人久久大香线蕉综合四虎小说| 久久久久久婷婷| 亚洲在线中文字幕| 日本福利片高清在线观看| 97久久精品国产| 精品国产1区| 日本三级日本三级日本三级极| 在线视频一区二区三| 人人澡人人添人人爽一区二区|