精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

亚洲国产成人va在线观看天堂| 美女国产一区二区三区| 亚洲第一视频网站| caoporn超碰97| 国产免费av在线| 国产精品资源站在线| 97视频在线观看免费高清完整版在线观看 | 黄色网在线免费观看| 国产一区二区免费在线| 久久国产精品久久久| 亚洲自拍偷拍精品| 在线国产成人影院| 亚洲欧美另类久久久精品2019| 国产精品二区在线| 免费在线观看黄网站| 竹菊久久久久久久| 69久久99精品久久久久婷婷| 国产av麻豆mag剧集| 国产小视频福利在线| 狠狠网亚洲精品| 57pao精品| 国产97免费视频| 日韩激情啪啪| 欧美一区二区三区人| 国产男女免费视频| www视频在线观看免费| 国产一区二区在线观看视频| 欧美一级淫片丝袜脚交| jizz亚洲少妇| 国产精品自拍区| 精品粉嫩超白一线天av| 污污动漫在线观看| 精品三级久久| 亚洲天堂免费在线观看视频| 欧美日本国产精品| 韩国av在线免费观看| 免播放器亚洲一区| 秋霞成人午夜鲁丝一区二区三区| 国产精品老熟女一区二区| 天堂成人娱乐在线视频免费播放网站| 欧美一区二区三区四区高清| 午夜欧美福利视频| caoprom在线| 综合久久久久久久| 青青草国产精品| 黄色美女一级片| 国产综合色在线| 国产精品人成电影| 日韩xxx高潮hd| 欧美丰满日韩| 亚洲毛片在线免费观看| 男插女视频网站| 欧美日韩精品一区二区三区视频| 亚洲一区二区三区四区在线观看| 涩涩日韩在线| 天堂在线观看视频| 国产福利精品导航| 国产精品一二区| 日日噜噜噜噜人人爽亚洲精品| 欧美 日韩 国产一区二区在线视频| 在线观看欧美视频| 实拍女处破www免费看| 2020国产精品极品色在线观看| 欧美日韩成人激情| 亚洲色精品三区二区一区| 超碰中文在线| 亚洲乱码国产乱码精品精98午夜| 五月天久久综合网| 毛片网站在线| av中文字幕一区| 不卡一卡2卡3卡4卡精品在| 91美女精品网站| 老司机一区二区| 国产主播精品在线| 亚洲在线视频播放| 激情伊人五月天久久综合| 国产欧美日韩中文字幕在线| 中文字幕视频网站| 一级成人国产| 国产成人精品久久二区二区| 91视频在线视频| 日本欧美在线观看| 国产精品一区二区三区成人| 亚洲综合免费视频| 激情五月激情综合网| 亚洲永久免费观看| 黄色aaa毛片| 99麻豆久久久国产精品免费| 明星裸体视频一区二区| 激情视频在线观看免费| 国产精品天干天干在观线| 一区二区三区四区五区精品| 国产精品扒开做爽爽爽的视频| 亚洲欧美日韩综合aⅴ视频| 8x8ⅹ国产精品一区二区二区| 黄色在线观看视频网站| 欧美日韩免费看| 可以免费在线看黄的网站| 欧美黄页免费| 日韩精品一区二区三区视频| 国产福利短视频| 成人看的视频| 萌白酱国产一区二区| 久久精品视频日本| 日韩高清欧美激情| 91九色在线视频| 天天干视频在线观看| 国产日产欧产精品推荐色 | 99久久国产宗和精品1上映| 日本免费一区二区三区等视频| 日韩精品一区二区三区在线观看| 中文字幕一区二区三区人妻不卡| 欧美午夜精彩| 欧美人与性动交| 国产一级淫片a视频免费观看| 精品一区二区三区在线观看国产 | www.av导航| 久久人人97超碰com| 国产日韩视频在线播放| 精品人人视频| 欧美一级理论片| 97超碰在线免费观看| 一区二区三区四区在线观看国产日韩| 97香蕉久久超级碰碰高清版| 亚洲中文字幕在线观看| 91视频一区二区三区| 最新不卡av| 欧美特黄aaaaaaaa大片| 日韩欧美国产三级电影视频| 一级黄色性视频| 亚洲国产精品一区| 91精品啪aⅴ在线观看国产| 色综合成人av| 亚洲精品国产第一综合99久久 | 精品一区二区在线看| 久久riav二区三区| а√天堂官网中文在线| 在线免费观看不卡av| 日b视频在线观看| 亚洲精品888| 国产精品劲爆视频| 日韩a在线观看| 亚洲成人精品一区| 香蕉视频xxx| 色狮一区二区三区四区视频| 国产91|九色| 日本成人动漫在线观看| 亚洲精品免费在线播放| 亚洲精品午夜在线观看| 国产精品午夜一区二区三区| 97精品在线视频| 亚洲免费一级片| 亚洲精品少妇30p| 五月天视频在线观看| 久久精品国产亚洲夜色av网站| 日韩av电影在线网| 深夜福利在线观看直播| 亚洲国产一区二区在线播放| 亚洲黄色片免费看| 亚洲大全视频| 亚洲精品免费网站| 国产黄a三级三级三级av在线看| 欧美少妇一区二区| 中文字幕免费高清| 日韩国产精品久久久久久亚洲| 久久亚洲国产精品日日av夜夜| 成年网站在线视频网站| 亚洲国产第一页| 国产手机在线视频| 91在线视频网址| 国产69精品久久久久久久| 激情小说亚洲图片| 91高清免费视频| 你懂的视频在线观看| 天天综合色天天综合| a天堂视频在线观看| 在线综合亚洲| 日本一区视频在线| 国产a亚洲精品| 久久精品99久久久久久久久| 国产精品视频第一页| 亚洲日本一区二区| 亚洲少妇一区二区三区| 亚洲一级高清| 欧美日韩精品综合| 国产成+人+综合+亚洲欧美| 久久久精品免费| 亚洲毛片在线播放| 黑人与娇小精品av专区| 国产123在线| 狠狠久久亚洲欧美| 日本中文字幕在线视频观看| 亚洲精品推荐| 国产精品午夜国产小视频| 黄色网址在线免费| 亚洲福利视频网站| 中文字幕黄色片| 中文字幕在线视频一区| 国产精久久久久| 香蕉av777xxx色综合一区| 亚洲精品8mav| 97成人在线| 国产成人综合久久| 伊人222成人综合网| 国产丝袜一区二区三区| 国产精品无码久久av| 亚洲高清不卡在线| av黄色在线免费观看| 狠狠色伊人亚洲综合成人| 国产午夜福利100集发布| 成人免费在线观看av| 99久久精品免费看国产四区 | 国产日韩精品一区二区| www.综合网.com| 色噜噜久久综合伊人一本| 亚洲国产成人在线观看| 在线观看不卡一区| 国产极品在线播放| 中文字幕一区二区在线观看| 国产艳妇疯狂做爰视频| 久久精品国产精品亚洲红杏| 欧美啪啪免费视频| 女人色偷偷aa久久天堂| 水蜜桃一区二区| 黄色成人美女网站| 1卡2卡3卡精品视频| 日韩制服诱惑| 高清欧美性猛交xxxx黑人猛交| 国产免费永久在线观看| 亚洲第一国产精品| 国产又大又长又粗| 色天使色偷偷av一区二区| www.av视频在线观看| 亚洲色图视频网站| eeuss中文字幕| 91美女在线观看| 中文字幕天堂av| 国产乱子伦视频一区二区三区| 另类小说第一页| 亚洲影视在线| www国产精品内射老熟女| 午夜精品国产| 福利在线小视频| 日韩精品二区| 少妇特黄a一区二区三区| 校花撩起jk露出白色内裤国产精品| 99re6热在线精品视频播放速度| 日本一区二区三区中文字幕| 国产精品h片在线播放| 亚洲美女久久精品| 91国产精品91| 国产伦理精品| 国内精品久久久久久| 日本欧美电影在线观看| 久久视频国产精品免费视频在线| 最新国产在线观看| 国产一区二区成人| 国产主播福利在线| 亚洲人av在线影院| 免费毛片在线| 亚洲欧洲中文天堂| 成人精品福利| 伊人男人综合视频网| av在线天堂播放| www.亚洲天堂| 成人在线app| 欧美床上激情在线观看| 中文在线观看免费| 欧美黑人xxx| 91老司机福利在线| 97在线视频一区| 中文在线资源| 国产精品91在线观看| 日韩成人一区| 国产噜噜噜噜噜久久久久久久久| 欧美日韩大片| 国产精品久久久91| av高清一区| 国产噜噜噜噜久久久久久久久| 久久国产三级| 国产免费久久av| 四虎精品在线观看| 成人疯狂猛交xxx| 成人交换视频| 国产美女久久精品香蕉69| 国产美女久久| 99电影在线观看| 国产乱论精品| 亚洲最大色综合成人av| 亚洲欧美网站在线观看| 日本a级片在线播放| 亚洲精选91| 日韩在线一级片| 久久久久99| 91pony九色| 成人免费视频一区| 国产全是老熟女太爽了| 国产精品久久久久国产精品日日| 欧产日产国产v| 黑丝美女久久久| 国产精品系列视频| 亚洲国产精品推荐| www.亚洲.com| 久久久久久久久电影| 三上悠亚激情av一区二区三区 | 日韩国产高清视频在线| а√天堂中文在线资源bt在线| 欧美成人在线网站| 欧美成人影院| 亚洲在线视频观看| 欧美猛男男男激情videos| 一道本在线观看视频| 国产亚洲在线观看| 欧美日韩久久婷婷| 久久久久国产精品麻豆| 欧美交换国产一区内射| 日本精品一级二级| 黄色一级大片在线免费看国产一| 国产亚洲一区精品| 2020国产在线| 亚洲va久久久噜噜噜| 国产精品午夜一区二区三区| 久久亚洲国产成人精品无码区| 日本欧美一区二区三区乱码 | 久久日韩粉嫩一区二区三区| 国内偷拍精品视频| 欧美日韩亚洲另类| 欧美美女搞黄| 欧美激情视频一区| 视频91a欧美| 日韩伦理一区二区三区av在线| 亚洲高清二区| 亚洲AV成人精品| 亚洲欧美综合色| 最近国语视频在线观看免费播放| 亚洲精品二三区| 性欧美猛交videos| 成人国产精品久久久久久亚洲| 国产精选一区| 黄色片久久久久| 99久久99久久精品国产片果冻| 强乱中文字幕av一区乱码| 欧美日韩成人综合天天影院| 成人av电影观看| 日本精品一区二区三区在线播放视频| 一区二区亚洲视频| 成人午夜免费剧场| 久久精品二区亚洲w码| 中文字幕av久久爽一区| 色视频成人在线观看免| 五月天激情开心网| 91精品国产免费久久久久久 | 国产一区视频观看| 欧美日一区二区三区在线观看国产免| 一级淫片在线观看| 最好看的中文字幕久久| 国产又爽又黄免费软件| 中国china体内裑精亚洲片| 亚洲高清黄色| 欧美日韩一区二区三区在线视频| 国产欧美一级| 五月天激情小说| 午夜日韩在线电影| www.狠狠干| 久久成人av网站| 欧美1区2区3| 国产一二三在线视频| a亚洲天堂av| 无码人妻av一区二区三区波多野| 亚洲视频在线观看视频| 91福利精品在线观看| 一区二区三区欧美在线| 韩国av一区二区三区四区 | 日本一区二区三区视频视频| 中文有码在线播放| y97精品国产97久久久久久| 成人亚洲精品| 欧美一二三不卡| 97se亚洲国产综合在线| 国产精品99精品无码视| 亚洲精品电影网| 香蕉成人影院| 亚洲成人蜜桃| 国产自产高清不卡| 久久久久久久99| 日韩成人av网| 免费观看成人性生生活片| 亚洲精品国产精品国自产观看| 蜜桃av一区二区在线观看| 激情无码人妻又粗又大| 欧美日韩亚洲另类| 18+激情视频在线| 日本精品一区二区三区高清 久久| 免费人成精品欧美精品| 黄色片在线观看网站| 日韩精品视频免费专区在线播放| 亚洲国产福利| 亚洲精品日韩在线观看| 国产成人精品影视| 波多野结衣黄色网址|