2021-01-05:mysql的自增id的實現邏輯是什么樣子的?

      網友投稿 856 2025-03-31

      福哥答案2021-01-05:


      答案來自這個鏈接:[ 每日一面 - Mysql 的自增 id 的實現邏輯是什么樣子的?](https://zhanghaoxin.blog.csdn.net/article/details/112223230)

      Key TakeAways

      1.InnoDB 引擎中 有三種 AutoIncrement 鎖模式:

      innodb_autoinc_lock_mode=0(traditional lock mode):獲取表鎖,語句執行結束后釋放。

      innodb_autoinc_lock_mode=1(consecutive lock mode,Mysql 8.0 之前默認 ):對于不確定插入數量的語句(例如INSERT ... SELECT, REPLACE ... SELECT和LOAD DATA)和 innodb_autoinc_lock_mode=0 一樣,其他的確定數量的語句在執行前先批量獲取 id,之后再執行語句。

      innodb_autoinc_lock_mode=2(interleaved lock mode,MySQL 8.0+ 默認 ):采用樂觀鎖, CAS 更新計數器獲取。

      2.AutoIncrement 計數器在 MySQL 8.0 之前,存儲在內存中,在 MySQL 8.0 之后,持久化存儲到磁盤。通過每次更新寫入 Redo Log,并在檢查點刷入 innodb 引擎表中記錄下來。

      3.AutoIncrement 的 id 可以讓新數據聚集在一起,利于大部分 OLTP 業務(訪問頻率在最近一天,一周,或者幾個月內比較活躍,而超過一段時間內的數據很少訪問)。如果是這類業務推薦使用自增主鍵,將業務主鍵(UUID)作為二級的唯一索引使用。

      4.如果考慮分布式性能以及避免 AutoIncrement 帶來的鎖性能問題,可以考慮使用 ID 生成器生成:全局趨勢增長的主鍵。

      為何主鍵要 Auto Increment 而不是 UUID

      ySQL InnoDB 引擎默認主鍵索引是 B+ 樹索引,也是聚集索引,為何叫聚集索引呢?

      以 InnoDB 作為存儲引擎的表,表中的數據都會有一個主鍵,即使你不創建主鍵,系統也會幫你創建一個隱式的主鍵。這是因為 InnoDB 是把數據存放在 B+ 樹中的,而 B+ 樹的鍵值就是主鍵,在 B+ 樹的葉子節點中,存儲了表中所有的數據。這種以主鍵作為 B+ 樹索引的鍵值而構建的 B+ 樹索引,我們稱之為聚集索引。

      存儲中,聚集索引的數據,會根據索引的值,對應的數據也會聚集存儲在一起。

      AutoIncrement 原理

      我們這里只關心 InnoDB 引擎的。

      AutoIncrement 最大值

      AutoIncrement 最大值,和列類型相關。最大可以設置列類型為 UNSIGNED BIGINT,這樣最大值就是 18446744073709551615。 超過這個值繼續生成則還是 18446744073709551615。不會再增加。

      AutoIncrement 鎖模式

      獲取 AutoIncrement 最新值,需要涉及到鎖。目前有三種鎖模式,對應 innodb_autoinc_lock_mode 的值, 0 ,1,2. MySQL 8.0 之后,默認為 2, 在這之前,默認為 1

      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)

      這種情況下,針對未知數量批量插入(例如INSERT ... SELECT, REPLACE ... SELECT和LOAD DATA)才會采用AUTO-INC鎖這種方式,而針對已知數量的普通插入,則采用了一種新的輕量級的互斥鎖來分配auto_increment列的值。這種鎖,只會持續到獲取一定數量的 id,不會等待語句執行結束在釋放。也就是拿輕量級鎖提前分配好所需數量的 id 之后釋放鎖,再執行語句。當然,如果其他事務已經持有了AUTO-INC鎖,則simple inserts需要等待。當然,這種情況下,可能產生的間隙更多。

      2021-01-05:mysql的自增id的實現邏輯是什么樣子的?

      3.innodb_autoinc_lock_mode=2(interleaved lock mode)

      這種模式下任何類型的inserts都不會采用AUTO-INC鎖,性能最好,但是在同一條語句內部產生auto_increment值間隙。其實這個就是所有語句對于同一個值進行 Compare-And-Set 更新,類似于樂觀鎖。這個鎖模式對statement-based replication的主從同步都有一定問題。因為同步傳輸的是語句,而不是行值,語句執行后的差異導致主從可能主鍵不一致。

      AutoIncrement 存儲

      AutoIncrement 計數器在 MySQL 8.0 之前,存儲在內存中,每次啟動時通過以下語句初始化:

      SELECT MAX(ai_col) FROM table_name FOR UPDATE;

      在 MySQL 8.0 之后,持久化存儲到磁盤。通過每次更新寫入 Redo Log,并在檢查點刷入 innodb 引擎表中記錄下來。

      所以,在MySQL 8.0 之前,如果 rollback 導致某些值沒有使用,重啟后,這些值還是會使用。但是在 MySQL 8.0 之后就不會了。

      ***

      [每日一面 - mysql 的自增 id 的實現邏輯是什么樣子的?](https://zhanghaoxin.blog.csdn.net/article/details/112223230)

      [2021-01-05:mysql的自增id的實現邏輯是什么樣子的?](http://bbs.xiangxueketang.cn/question/1007)

      [評論](https://user.qzone.qq.com/3182319461/blog/1609801219)

      MySQL

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何在Excel自動為列編號?
      下一篇:圖片轉鏈接生成器在線(圖片轉鏈接生成器在線制作
      相關文章
      亚洲啪啪免费视频| 亚洲欧洲日产国码av系列天堂 | 亚洲日产无码中文字幕| 麻豆亚洲AV成人无码久久精品| 亚洲VA中文字幕无码一二三区| 亚洲AV成人一区二区三区在线看| 亚洲av永久无码精品网站 | 亚洲成AV人片高潮喷水| 久久亚洲高清观看| 国产精品国产亚洲精品看不卡| 亚洲一区二区三区无码影院| 亚洲 另类 无码 在线| 亚洲日韩国产一区二区三区在线| 亚洲国产精品线观看不卡| 亚洲另类古典武侠| 亚洲一级毛片免费在线观看| 亚洲伊人久久精品| 亚洲乱码中文字幕小综合| 亚洲自偷精品视频自拍| 亚洲国产片在线观看| 亚洲AV日韩精品久久久久久| 亚洲AV中文无码乱人伦下载 | 亚洲成a人片在线观看播放| 精品亚洲成a人片在线观看少妇| 中文字幕亚洲综合久久菠萝蜜 | 日本亚洲中午字幕乱码| 亚洲乱色熟女一区二区三区蜜臀| 亚洲在成人网在线看| 91情国产l精品国产亚洲区| 亚洲国产精品VA在线观看麻豆| 亚洲精品视频免费| 亚洲综合色自拍一区| 国产啪亚洲国产精品无码 | 亚洲精品无码久久久影院相关影片| 亚洲成AV人片在线观看| 亚洲一级免费视频| 亚洲人成电影网站免费| 国产成人综合亚洲亚洲国产第一页| 亚洲午夜久久久影院伊人| 亚洲精品色在线网站| 亚洲AV无码精品国产成人|