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

硬核萬字圖解 MySQL 表空間、Tables、Index、雙寫緩沖、Redo Log、Undo Log 原理

數據庫 MySQL
MySQL 到底是怎么管理和存儲各種各樣的數據呢?比如創建一張表、索引、表中的每一行數據、查詢過程中臨時存儲的數據都存在哪里,又如何管理?

數據最終要持久化到磁盤,其磁盤架構設計融合了復雜的存儲結構和精巧的機制,本文將深入剖析其核心模塊的設計原理,并通過圖片輔助理解。

在數據庫領域,MySQL 的 InnoDB 存儲引擎以其高性能、高可靠性和事務支持著稱。

MySQL 到底是怎么管理和存儲各種各樣的數據呢?比如創建一張表、索引、表中的每一行數據、查詢過程中臨時存儲的數據都存在哪里,又如何管理?

這一切都歸功于 MySQL 的 Tablespaces (表空間)的設計,內容較多,本篇就關于以下類型 Tablespaces (表空間)作用、Tables、Index、Doublewrite Buffer、Redo Log、Undo Log 和實現原理展開:

  • Tablespace(表空間)

系統表空間(System Tablespace)

獨立表空間(File-Per-Table Tablespaces)

通用表空間(General Tablespaces)

撤銷表空間(Undo Tablespaces)

臨時表空間(Temporary Tablespaces)

  • Tables(表)
  • Row Formats 行格式
  • 主鍵
  • 自增主鍵
  • Indexes(索引)
  • Doublewrite Buffer(雙寫緩沖)
  • 為什么需要雙寫緩沖
  • 雙寫緩沖架構設計
  • Redo Log(重做日志)
  • Undo Log(撤銷日志)

Tablespaces (表空間)

表空間可以看做是 InnoDB 存儲引擎邏輯結構的最高層,所有的數據都存放在表空間中,稱之為表空間(tablespace)。

從物理文件的分類來看:

  • 日志文件(Undo Log、Redo Log)。
  • 系統表空間(System Tablespace)文件 ibdata1。
  • Undo tablespace 。
  • 獨立表空間(File-Per-Table Tablespaces)
  • 通用表空間(General Tablespaces)
  • 臨時表空間文件(Temporary Tablespaces)

所以表空間根據不同的場景也分了多種類型,我分別介紹下……

系統表空間(System Tablespace)

默認配置下會有一個初始大小為 10MB,名為 ibdata1 的文件。該文件就是默認的表空間文件(tablespace file)。

系統表空間是 Change Buffer 的存儲區域。

如果表是在系統表空間而非獨立表空間或通用表空間中創建的,它也可能包含表和索引數據。

增加系統表空間大小的最簡單方法是將其配置為自動擴展。

為此,在 innodb_data_file_path 設置中為最后一個數據文件指定 autoextend 屬性,并重啟服務器。

innodb_data_file_path=ibdata1:10M:autoextend

為避免系統表空間過大,可考慮使用獨立表空間或通用表空間存儲數據。

獨立表空間是默認的表空間類型,在創建 InnoDB 表時會隱式使用。

獨立表空間(File-Per-Table Tablespaces)

獨立表空間,顧名思義,就是用戶創建的表空間,如果開啟獨立表空間參數,那么一個表空間會對應磁盤上的一個物理文件,每張表對應一個文件,支持事務獨立管理。

其實表空間文件內部還是組織為更復雜的邏輯結構,自頂向下可分為 segment(段)、extent(區)和 page(頁)。

page 則是表空間數據存儲的基本單位,innodb 將表文件(xxx.ibd)按 page 切分,依類型不同,page 內容也有所區別,最為常見的是存儲數據庫表的行記錄。

表空間下一級稱為 segment。segment 與數據庫中的索引相映射。

Innodb 引擎內,每個索引對應兩個 segment:管理葉子節點的 segment 和管理非葉子節點 segment。

創建索引中很關鍵的步驟便是分配 segment,Innodb 內部使用 INODE 來描述 segment。

segment 的下一級是 extent,extent 代表一組連續的 page,默認為 64 個 page,大小 1MB。

InnoDB 存儲引擎的邏輯存儲結構大致如圖 2 所示。

圖 2圖 2

默認情況下 InnoDB 存儲引擎有一個共享表空間 ibdata1,即所有數據都存放在這個表空間內。

如果用戶啟用了參數innodb_file_per_table,則每張表內的數據可以單獨放到一個表空間內。

如果啟用了innodb_file_per_table的參數,需要注意的是每張表的表空間內存放的只是數據、索引和插入緩沖 Bitmap 頁.

其他類的數據,如回滾(undo)信息,插入緩沖索引頁、系統事務信息,二次寫緩沖(Double write buffer)等還是存放在原來的系統表空間內。

通用表空間(General Tablespaces)

通用表空間是一種共享的 InnoDB 表空間,通過 CREATE TABLESPACE 語法創建。

通用表空間提供以下功能:

  • 類似于系統表空間,通用表空間是一種共享表空間,能夠存儲多張表的數據。
  • 通用表空間在內存占用上可能優于獨立表空間。服務器會在表空間生命周期內將表空間元數據保留在內存中。相較于相同數量的表分散在多個獨立表空間中,更少的通用表空間內存儲多張表能減少表空間元數據的內存消耗。

通用表空間通過 CREATE TABLESPACE 語法創建。

CREATE TABLESPACE tablespace_name
    [ADD DATAFILE 'file_name']
    [FILE_BLOCK_SIZE = value]
        [ENGINE [=] engine_name]

通用表空間有什么不足?

通用表空間限制有以下限制:

  • 現有的表空間無法更改為通用表空間。
  • 不支持創建臨時通用表空間。
  • 通用表空間不支持臨時表。
  • 不支持將表分區放置在通用表空間中。
  • 在復制環境中,如果源和副本位于同一主機上,則不支持使用 ADD DATAFILE 子句,因為這會導致源和副本在同一位置創建同名的表空間,而這是不被支持的。

撤銷表空間(Undo Tablespaces)

MySQL InnoDB 引擎的 Undo Tablespaces(撤銷表空間)是磁盤架構設計中用于管理事務回滾日志(Undo Log)的核心組件。

余彥瑭:InnoDB 引擎的 Undo Tablespaces(撤銷表空間)有啥用?

Undo 日志(Undo Log)主要用于事務異常時的數據回滾,在磁盤上 undo 日志保存在 Undo Tablespaces 中。

  1. 事務回滾與 MVCC 支持Undo 表空間存儲的 Undo Log 記錄了事務對數據的修改前鏡像,用于:

事務回滾時恢復數據原狀;

實現多版本并發控制(MVCC),支持非鎖定一致性讀。

  1. 分離系統表空間負載在 MySQL 5.7 之前,Undo Log 默認存儲在系統表空間(ibdata1)中。隨著事務頻繁操作,ibdata1 文件會無限增長且無法自動回收空間。5.7 及更高版本引入獨立 Undo 表空間,通過物理隔離減輕系統表空間壓力,提升性能。

MySQL 8.0 默認創建 2 個 Undo 表空間文件(undo_001 和 undo_002),每個初始大小為 16MB,通過參數 innodb_undo_tablespaces 可調整數量(范圍 2-127),每個文件初始 16MB,支持自動擴展和截斷回收。

余彥瑭:“Undo 表空間的邏輯層級管理是咋樣的?”

回滾段(Rollback Segments):每個 Undo 表空間包含 128 個回滾段(由 innodb_rollback_segments 控制),每個回滾段管理 1024 個 Undo 段(Undo Segments)。

Undo 頁與日志記錄:Undo 段由多個 16KB 的頁組成,按事務類型分為 Insert Undo 段(僅用于回滾)和 Update Undo 段(用于 MVCC),前者事務提交后立即釋放,后者需等待無活躍讀視圖時清除。

通過多 Undo 表空間與回滾段的分區設計,理論上支持高達數萬級并發事務(例如:128 表空間 × 128 回滾段 × 1024 Undo 段)。

如下圖所示。

圖片圖片

關鍵說明:

  • 每個 Undo 表空間包含 128 個回滾段
  • 每個回滾段管理 1024 個 Undo 段(按事務類型分類)
  • Undo 段由 16KB 頁 組成,存儲具體日志記錄

余彥瑭:說說 Undo Log 與 MVCC 的協作機制

Undo Log 與 MVCC 的協作機制如下圖所示:

圖片圖片

運作原理:

  • 事務修改前將舊數據寫入 Undo Log
  • 讀事務通過 Read View 判斷可見性
  • 多版本數據通過 Undo Log 鏈回溯訪問

余彥瑭:“系統表空間與 Undo 表空間存儲有啥區別?”

特性

Undo 表空間

系統表空間(歷史方案)

存儲內容

僅 Undo Log

數據字典、雙寫緩沖、Undo Log 等混合內容

空間管理

支持自動截斷,避免文件膨脹

無法自動回收,需手動調整或重建

性能影響

減少 I/O 競爭,提升并發處理能力

高頻事務易導致文件過大,性能下降

版本支持

MySQL 5.7+ 默認方案

MySQL 5.6 及更早版本

臨時表空間(Temporary Tablespaces)

InnoDB 臨時表空間分為 會話臨時表空間 和 全局臨時表空間,分別承擔不同角色:

  1. 會話臨時表空間(Session Temporary Tablespaces)
  • 用途:存儲用戶顯式創建的臨時表(CREATE TEMPORARY TABLE)以及優化器生成的內部臨時表(如排序、分組操作)。
  • 生命周期:會話斷開時自動截斷并釋放回池,文件擴展名為 .ibt,默認位于 #innodb_temp 目錄。
  • 分配機制:首次需要創建磁盤臨時表時,從預分配的池中分配(默認池包含 10 個表空間文件),每個會話最多分配 2 個表空間(用戶臨時表與優化器內部臨時表各一)。
  1. 全局臨時表空間(Global Temporary Tablespace):
  • 用途:存儲用戶臨時表的回滾段(Rollback Segments),支持事務回滾操作。
  • 文件配置:默認文件名為 ibtmp1,初始大小 12MB,支持自動擴展,由參數 innodb_temp_data_file_path 控制路徑與屬性。
  • 回收機制:服務器重啟時自動刪除并重建,意外崩潰時需手動清理。

Temporary Tablespaces 物理結構

圖片圖片

圖示說明:

  • 全局臨時表空間:ibtmp1 存儲用戶臨時表的回滾段
  • 會話臨時表空間:#innodb_temp 目錄下預分配 10 個 .ibt 文件池(默認配置)
  • 每個會話最多激活 2 個臨時表空間(用戶臨時表 + 優化器內部臨時表)。

會話級臨時表空間生命周期

圖片圖片

關鍵點:

  1. 首次需要磁盤臨時表時從池中分配
  2. 會話斷開連接后立即歸還空間
  3. 文件物理保留但內容截斷(類似內存池機制)

臨時表空間使用查詢流程

前面說過臨時表空間可存儲用戶顯式創建的臨時表(CREATE TEMPORARY TABLE)以及優化器生成的內部臨時表(如排序、分組操作)。

那它的查詢過程是怎樣的呢?

Tables(表)

余彥瑭:“在 MySQL 如何創建一張表?”

InnoDB 表通過 CREATE TABLE 語句創建;例如:

CREATE TABLE t1 (a INT, b CHAR (20), PRIMARY KEY (a)) ENGINE=InnoDB;

默認情況下, InnoDB 表創建于每表獨立的表空間中。若要在 InnoDB 系統表空間中創建 InnoDB 表,需在創建表前禁用 innodb_file_per_table 變量。

比如,在數據庫 test 中創建一個表 show_index ,在 mysql 的 dataDirectory 目錄下就回出現一個名為 show_index.ibd 的數據文件。

在單個表的數據文件中,數據就是以多個頁的形式進行排列。MySQL 默認配置下,每 16K,即為一個頁。

InnoDB 表以 B+樹 組織數據,每個表對應一個 聚簇索引(Clustered Index),數據行的物理存儲順序與主鍵順序一致。

若未顯式定義主鍵,InnoDB 會隱式生成一個 6 字節的 Row ID 作為主鍵。

Row Formats 行格式

余彥瑭:表中的每一行數據是怎么存儲的?

表的 InnoDB 行格式決定了其行在磁盤上的物理存儲方式。

InnoDB 支持四種行格式,每種格式具有不同的存儲特性。

支持的行格式包括 REDUNDANT 、 COMPACT 、 DYNAMIC 和 COMPRESSED 。其中, DYNAMIC 行格式為默認格式。


余彥瑭:它們有啥區別?

REDUNDANT 和 COMPACT 行格式支持的最大索引鍵前綴長度為 767 字節,而 DYNAMIC 和 COMPRESSED 行格式則支持 3072 字節的索引鍵前綴長度。

在復制環境中,若源服務器上的 innodb_default_row_format 變量設置為 DYNAMIC ,而副本上設置為 COMPACT ,則以下未明確指定行格式的 DDL 語句在源服務器上執行成功,但在副本上會失敗。

Primary Keys 主鍵

建議為創建的每個表定義一個主鍵。在選擇主鍵列時,應選擇具有以下特征的列:

  • 重要的查詢語句使用的列。
  • 列不能為空。
  • 從不包含重復值的列。
  • 一旦插入后極少甚至從不更改值的列。

例如,在包含人員信息的表中,你不會將主鍵設在 (firstname, lastname) 上,因為可能有多個人員擁有相同的姓名,姓名列可能留空,且有時人們會更改姓名。

面對如此多的限制條件,通常沒有明顯的一組列適合作為主鍵,因此你會創建一個帶有數字 ID 的新列,作為主鍵。

最好的方式就是使用趨勢遞增的數字作為主鍵。

你也可以 在 InnoDB 表中使用 AUTO_INCREMENT 的列來定義主鍵自動生成。

AUTO_INCREMENT 實現原理是什么?會鎖全表碼?

自增鎖模式通過 innodb_autoinc_lock_mode 變量在啟動時配置。

自增主鍵鎖

“傳統”鎖模式

innodb_autoinc_lock_mode = 0 (“傳統”鎖模式),所有“INSERT 類”語句在向具有 AUTO_INCREMENT 列的表中插入時都會獲得一個特殊的表級 AUTO-INC 鎖。

此鎖通常保持到語句的末尾(而不是事務的末尾),以確保在給定的 INSERT 語句序列中自動增量值按可預測和可重復的順序分配,并確保任何給定語句分配的自動增量值是連續的。

“連續”鎖模式

innodb_autoinc_lock_mode = 1 (“連續”鎖模式),“批量插入”使用特殊的 AUTO-INC 表級鎖,并保持到語句結束。這適用于所有 INSERT ... SELECT 、 REPLACE ... SELECT 和 LOAD DATA 語句。

這種鎖模式確保,在存在 INSERT 語句且行數未知(并且自增值在語句執行過程中分配)的情況下,任何“ INSERT -類似”語句分配的所有自增值都是連續的,并且操作對基于語句的復制是安全的。

innodb_autoinc_lock_mode = 2 (“交錯”鎖模式)

在這種鎖模式中,沒有“ INSERT -like”語句使用表級 AUTO-INC 鎖,并且多個語句可以同時執行。

這是最快且最可擴展的鎖模式,但在使用基于語句的復制或從二進制日志重放 SQL 語句的恢復場景時是不安全的。

在此鎖定模式下,自動增量值在整個并發執行的“ INSERT -like”語句中保證是唯一的且單調遞增。

然而,由于多個語句可以同時生成數字(即,數字的分配在語句之間交錯進行),任何給定語句插入的行生成的值可能不是連續的。

Indexes(索引)

InnoDB 的索引分為 聚簇索引 和 二級索引(Secondary Index),均采用 B+樹結構:

  • 聚簇索引:也稱 Clustered Index。是指關系表記錄的物理順序與索引的邏輯順序相同。由于一張表只能按照一種物理順序存放,一張表最多也只能存在一個聚集索引。葉子節點直接存儲行數據。
  • 二級索引:也叫 Secondary Index。指的是非葉子節點按照索引的鍵值順序存放,葉子節點存放索引鍵值以及對應的主鍵鍵值。MySQL 里除了 INNODB 表主鍵外,其他的都是二級索引。葉子節點存儲主鍵值,需通過主鍵回表查詢數據。

下圖是一個聚集索引的 B+ Tree 圖。

圖片圖片

1 個 B+ Tree Node,占據一個頁。

  • 在索引頁,頁的主要記錄部分(User Records)存放的Record = record header + index key + page pointer。
  • 在數據頁,則是按表創建時的row_format類型存放完整數據行記錄。 row_format 類型分別有:Compact、Redundant、Compressed和Dynamic。

因此,在聚集索引中,非葉子節點都為索引頁,葉子節點為數據頁;

在輔助索引中,非葉子節點和葉子節點都為索引頁。不同的是,葉子節點里記錄的是聚集索引中的主鍵 ID 值。

INNODB 表的二級索引,如下圖所示,圖片來自「一樹一溪」:

注意,在索引頁的 Record 中的page pointer,指向的是頁,而非具體的記錄行。

并且 Record 的index key,為指向的 page records 的起始鍵值。

如果主鍵較長,二級索引會占用更多空間,因此擁有較短的主鍵是有利的。

在表空間文件的一個頁的結構上,內容布局為:

圖片圖片

在聚集索引中,數據頁內除了按照主鍵大小進行記錄存放以外,在File header中,有兩個字段:fil_page_prev 和fil_page_next, 分別記錄了上一頁/下一頁的偏移量(offset),用以實現數據頁在 B+ Tree 葉子位置的雙向鏈表結構。

數據如何被查找檢索呢?

通過 B+ Tree 結構,可以明顯看到,通過 B+ Tree 查找,可以定位到索引最后指向的數據頁,并不能找到具體的記錄本身。

這時,數據庫會將該頁加載到內存中,然后通過Page Directory進行二分查找。

余彥瑭:“索引使用單調遞增和 UUID 有什么區別嗎?”

這個問題問的好,我們一定要杜絕使用 UUID 生成的數據作為索引。

順序主鍵(如自增 ID)插入時,數據頁填充率高,減少頁分裂。我們根據上文知道,索引是有序排列的一個 B+tree,單調遞增天然有序,這樣才能高效的使用索引查詢數據。

什么是覆蓋索引優化?

-- 示例表結構
CREATETABLEusers (
idINT PRIMARY KEY,
nameVARCHAR(50),
  age INT,
INDEX idx_name_age (name, age)
);

-- 覆蓋索引查詢
SELECTid, name, age FROMusersWHEREname = 'Alice';
  • 原理:查詢字段全部包含在二級索引中時,無需回表。
  • 執行計劃:Extra 列顯示 Using index。

余彥瑭:“排序索引(Sorted Indexes)是什么?”

B+ 樹有序性:所有索引(聚簇/二級)均按索引鍵值排序存儲,支持高效范圍查詢和排序操作。

頁內排序:單個數據頁內的記錄按主鍵順序存儲,頁之間通過雙向鏈表連接。

所以我們么可以使用索引看來優化排序查詢。

-- 利用索引排序
SELECT * FROM users ORDER BY id DESC LIMIT 10;

避免 Filesort:若 ORDER BY 子句與索引順序一致,執行計劃顯示 Using index。

Doublewrite Buffer (雙寫緩沖)

InnoDB 是 MySQL 中一種常用的事務性存儲引擎,它具有很多優秀的特性。

其中,Doublewrite Buffer 是 InnoDB 的一個重要特性之一。

為什么需要 Doublewrite Buffer

InnoDB 頁大小為 16KB,而操作系統(如 Linux)頁大小為 4KB,單次寫入需拆分 4 個 OS 頁。

可以使用如下命令查看 MySQL 的 Page 大小:

SHOW VARIABLES LIKE 'innodb_page_size';

而 MySQL 程序是跑在 Linux 操作系統上的,MySQL 中一頁數據刷到磁盤,要寫 4 個文件系統里的頁。

圖片圖片

需要注意的是,這個操作并非原子操作,比如我操作系統寫到第二個頁的時候,Linux 機器斷電了,這時候就會出現問題了。

造成”頁數據損壞“。并且這種”頁數據損壞“靠 redo 日志是無法修復的。

Redo log 中記錄的是對頁的物理操作,而不是頁面的全量記錄,而如果發生 partial page write(部分頁寫入)問題時,出現問題的是未修改過的數據,此時重做日志(Redo Log)無能為力。

Doublewrite Buffer 的出現就是為了解決上面的這種情況,雖然名字帶了 Buffer,但實際上 Doublewrite Buffer 是內存+磁盤的結構。

Doublewrite Buffer 是一種特殊文件 flush 技術,帶給 InnoDB 存儲引擎的是數據頁的可靠性。

它的作用是,在把頁寫到磁盤數據文件之前,InnoDB 先把它們寫到一個叫 doublewrite buffer(雙寫緩沖區)的共享表空間內,在寫 doublewrite buffer 完成后,InnoDB 才會把頁寫到數據文件的適當的位置。

如果在寫頁的過程中發生意外崩潰,InnoDB 在稍后的恢復過程中在 doublewrite buffer 中找到完好的 page 副本用于恢復。

架構設計

Doublewrite Buffer 采用 內存+磁盤雙層結構,關鍵組件如下:

內存結構

  • 容量固定為 128 個頁(2MB),每個頁 16KB。
  • 數據頁刷盤前,通過 memcpy 拷貝至內存 Doublewrite Buffer。

磁盤結構

  • 位于系統表空間(ibdata),分為 2 個區(extent1/extent2),共 2MB。
  • 數據以 順序寫 方式寫入,避免隨機 I/O 開銷。

工作流程如下圖所示:

圖片圖片

如上圖所示,當有數據修改且頁數據要刷盤時:

  1. 第一步:記錄 Redo log。
  2. 第二步:臟頁從 Buffer Pool 拷貝至內存中的 Doublewrite Buffer。
  3. 第三步:Doublewrite Buffer 的內存里的數據頁,會 fsync 刷到 Doublewrite Buffer 的磁盤上,分兩次寫入磁盤共享表空間中(連續存儲,順序寫,性能很高),每次寫 1MB;
  4. 第四步:Doublewrite Buffer 的內存里的數據頁,再刷到數據磁盤存儲 .ibd 文件上(離散寫);

時序圖如下:

圖片圖片

崩潰恢復

如果第三步前,發生了崩潰,可以通過第一步記錄的 Redo log 來恢復。

如果第三步完成后發生了崩潰, InnoDB 存儲引擎可以從共享表空間中的 Double write 中找到該頁的一個副本,將其復制到獨立表空間文件,再應用 Redo log 恢復。

在正常的情況下,MySQL 寫數據頁時,會寫兩遍到磁盤上,第一遍是寫到 doublewrite buffer,第二遍是寫到真正的數據文件中,這就是“Doublewrite”的由來。

Doublewrite Buffer 通過 兩次寫 機制,在內存和磁盤間構建冗余副本,成為 InnoDB 保障數據完整性的基石。

其架構設計平衡了性能與可靠性,尤其在高并發或異常宕機場景下表現突出。

Redo Log (重做日志)

重新回顧下 MySQL InnoDB 的內存和磁盤架構設計圖。

我們的目光是關注點在于左側內存架構的 Log Buffer 以及右側磁盤架構的 Redo Log 文件。

圖 1圖 1

余彥瑭:Redo Log 有啥用呢?

姐姐你可知道,在數據庫系統中,持久性(Durability) 是事務 ACID 特性的核心要求之一。

其核心問題是:如何確保提交的事務在崩潰后不丟失? 直接修改磁盤數據頁的隨機 I/O 性能低下,且無法保證崩潰瞬間數據的完整性。

InnoDB 的解決方案是引入 Redo Log(重做日志),通過順序寫日志 + 內存緩沖的組合設計實現高性能的持久化保障。


余彥瑭:“說說看 Redo Log 如何保證已提交的事務不丟失”

當數據庫意外崩潰時,如何保證已提交事務不丟失?InnoDB 通過 WAL(Write-Ahead Logging)機制 解決這一核心問題,其實現依賴兩大核心組件:

  1. Log Buffer:內存中的日志緩沖區
  2. Redo Log:磁盤上的順序寫日志文件通過二者的協同,InnoDB 在保證 ACID 持久性的同時,將隨機寫轉換為順序寫,實現性能與可靠性的完美平衡。

圖片圖片

Log Buffer 是一個內存層的環形緩沖區。

圖片圖片

關鍵字段說明:

  • buf:指向環形緩沖區的內存地址
  • write_lsn:原子變量,實現多線程無鎖寫
  • hdr_no:塊序號(用于崩潰恢復時定位日志位置)

余彥瑭:“李老師,當事務生成 Redo 記錄后,關鍵步驟有哪些?”

當事務生成 Redo Record 后:

/* 源碼路徑:storage/innobase/log/log0buf.cc */
void log_buffer_write(log_t& log, byte* record, size_t len) {
    // 1. 獲取互斥鎖(短時鎖)
    mutex_enter(&log.mutex);

    // 2. 分配連續空間(跨塊處理)
    lsn_t start_lsn = log.assign_lsn(len);

    // 3. 復制日志到緩沖區
    memcpy(log.buf + write_offset, record, len);

    // 4. 無鎖更新 write_lsn
    log.update_write_lsn(start_lsn + len);

    // 5. 喚醒刷盤線程
    os_event_set(log.flusher_event);
}

WAL 機制全流程如下圖所示:

圖片圖片

Undo Logs (撤銷日志)

MySQL InnoDB 引擎的事務隔離性由鎖來實現。原子性、一致性、持久性通過數據庫的 redo log 和 undo log 來完成。

余彥瑭:“Undo Log 的本質作用是什么?”

Undo Log 是 InnoDB 實現事務 原子性(Atomicity) 和 多版本并發控制(MVCC) 的核心組件,主要解決兩大關鍵問題:

  1. 事務回滾:允許事務失敗時恢復到修改前的狀態(原子性)
  2. 讀一致性:提供非鎖定讀取(Non-Locking Read)的歷史版本(MVCC)

與 Redo Log 形成鮮明對比:

特性

Redo Log

Undo Log

目的

保證持久性

保證原子性和隔離性

寫入方向

順序寫

隨機寫(回滾段中)

存儲內容

物理日志(頁修改)

邏輯日志(行修改前的值)

生命周期

事務提交后保留到檢查點

事務提交后保留到無讀視圖引用

清理機制

Checkpoint 截斷

Purge 線程異步清理

當事務修改數據時, Undo Log 如何生成呢?

關鍵代碼邏輯(row_upd_rec_in_place函數):

/* 存儲位置:storage/innobase/row/row0upd.cc */
void row_upd_rec_in_place(...) {
    // 1. 創建 Undo Log Record
    trx_undo_report_row_operation(...);

    // 2. 寫入回滾段
    trx_undo_report_update_impl(...);

    // 3. 設置行回滾指針
    row_upd_rec_set_roll_ptr(...);
}

時序圖如下所示:

圖片圖片

余彥瑭:過期 Undo Log 該如何處理呢?

姐姐問得好,Purge 線程負責清理已提交事務的過期 Undo Log。

就這樣,InnoDB 通過三大日志機制構建完整事務系統:

圖片圖片

設計哲學啟示:

  1. 分層解耦
  • Redo 處理物理持久化
  • Undo 處理邏輯回滾
  • Binlog 處理邏輯復制
  1. 空間換時間Undo 保留歷史版本換取無鎖讀能力
  2. 延遲處理藝術Purge 機制避免事務提交時的同步清理開銷

好了,今天就到這。

責任編輯:武曉燕 來源: 碼哥跳動
相關推薦

2025-01-15 13:19:09

MySQL日志事務

2024-06-11 00:00:02

MySQL數據庫系統

2021-01-26 13:47:08

MySQL存儲數據

2020-08-20 12:10:42

MySQL日志數據庫

2024-05-28 00:10:00

JavaMySQL數據庫

2024-05-30 08:03:17

2023-11-23 13:17:39

MySQL?數據庫

2025-06-06 07:02:43

2025-01-20 08:20:00

redo logMySQL數據庫

2025-10-09 02:22:00

MySQLMVCC庫存數量

2024-12-16 00:00:05

MySQL二進制數據

2021-07-28 08:32:03

MySQLRedo存儲

2021-10-04 09:23:30

Redo日志內存

2022-08-26 10:11:26

MySQL數據庫

2021-05-28 11:18:50

MySQLbin logredo log

2024-08-30 10:29:21

2024-12-31 00:00:01

驅動設計應用場景業務邏輯

2020-09-21 10:50:24

Java多線程代碼

2010-01-06 09:30:51

Oracle Redo

2025-04-23 08:31:26

Java并發框架
點贊
收藏

51CTO技術棧公眾號

人人妻人人澡人人爽欧美一区| 亚洲欧美日韩精品一区二区| 国产福利91精品一区二区三区| 亚洲电影第1页| 国产精品视频中文字幕91| 熟女人妻一区二区三区免费看| 黄色电影免费在线看| 岛国精品一区| 亚洲免费在线视频| 国产精品久久久av久久久| 成人性生活免费看| 青青草原av在线| 极品尤物av久久免费看| 国产亚洲欧洲高清一区| 欧美黄网站在线观看| 天天干天天爽天天操| 激情欧美日韩一区| 日韩免费视频线观看| 宅男在线精品国产免费观看| 自拍偷拍福利视频| 成人高清电影网站| 欧美少妇xxx| 日韩欧美三级一区二区| 无码人妻精品一区二区蜜桃色欲| 亚瑟一区二区三区四区| 欧美午夜精品在线| 欧美福利精品| 综合激情网五月| 亚洲精品一级二级三级| 欧美性色xo影院| 日本一区二区免费高清视频| 国产三级漂亮女教师| 亚洲电影影音先锋| 日韩欧美在线一区二区三区| 日本天堂免费a| 国产 欧美 自拍| 9色精品在线| 亚洲欧美中文字幕在线一区| 一区二区三区 日韩| 欧美性天天影视| 国产精品综合二区| 国语自产精品视频在线看| 在线观看日韩精品视频| 视频在线日韩| 亚洲免费观看高清在线观看| 日韩电影在线播放| 日本一卡二卡四卡精品| 日本一区中文字幕| 久久中文字幕在线视频| 天堂www中文在线资源| 久久视频免费| 欧美日韩亚洲精品一区二区三区| 日本最新一区二区三区视频观看| 午夜影院免费视频| 日韩二区三区四区| 免费91在线视频| 久久一区二区电影| 国产福利91精品一区二区| 亚洲女同ⅹxx女同tv| 四虎永久国产精品| 亚洲欧美另类一区| 国产高清不卡一区| 亚洲精品免费一区二区三区| 欧美日韩综合在线观看| 色88久久久久高潮综合影院| 亚洲高清av在线| www国产视频| 日韩有码中文字幕在线| 国产午夜精品久久久| 天堂av手机在线| 女人高潮被爽到呻吟在线观看| 国产女主播在线一区二区| 99在线观看| 日韩欧美一级大片| 久久er精品视频| 91国内产香蕉| 免费在线观看黄色小视频| 国产欧美三级电影| 亚洲国产精品va在线看黑人| 五月婷婷综合在线观看| 国产免费av国片精品草莓男男| 欧美日韩国产精品一区| 男女午夜激情视频| 日韩毛片免费看| 色香蕉成人二区免费| 免费拍拍拍网站| 日本免费中文字幕在线| 国产人成一区二区三区影院| 亚洲 国产 欧美一区| 成人福利在线观看视频| 日本一区二区免费在线| 中文精品视频一区二区在线观看| 在线看女人毛片| 国产精品久久久久国产精品日日| 精品卡一卡二| 亚洲欧美另类综合| 久久伊99综合婷婷久久伊| 国产精品一区视频网站| h狠狠躁死你h高h| 九九**精品视频免费播放| 97se视频在线观看| 国产麻豆精品一区| 97se狠狠狠综合亚洲狠狠| 99久久综合狠狠综合久久止| 欧美性孕妇孕交| 亚洲品质自拍视频| 国产又粗又大又爽的视频| av影片免费在线观看| 国产日产欧美一区二区三区| 欧美黄色直播| 成人无遮挡免费网站视频在线观看| 黄色一区二区三区| 精品久久久久久久久久中文字幕| 国产在线拍揄自揄拍视频| 亚洲午夜精品一区二区三区他趣| av动漫在线免费观看| 欧美一区 二区 三区| 色综合天天在线| wwwww在线观看| 日本精品黄色| 欧洲美女免费图片一区| 波多野结衣 久久| 日韩国产欧美一区二区三区| 国产精品午夜av在线| 免费在线看黄色| 色婷婷久久一区二区三区麻豆| 任你躁av一区二区三区| 精品按摩偷拍| 亚洲国产欧美在线成人app| 国产又粗又长又爽| 中文字幕一区二区三区欧美日韩| 欧美成人第一页| 日本妇乱大交xxxxx| 久久只精品国产| 夜夜添无码一区二区三区| 性欧美xxx69hd高清| 在线视频综合导航| 久热在线视频观看| 在线精品国产亚洲| 亚洲另类xxxx| 天天做夜夜爱爱爱| 免费在线看成人av| 91久久爱成人| 高清免费电影在线观看| 91精品一区二区三区久久久久久| 无码人妻一区二区三区一| 99视频精品全部免费在线视频| 九九九久久国产免费| 日韩欧美不卡视频| 免费一区二区视频| 欧洲高清一区二区| av网站大全在线| 欧美一卡二卡三卡| 蜜桃av免费看| 欧美va天堂在线| 日韩美女免费线视频| 国产又色又爽又黄又免费| 大美女一区二区三区| 日本高清久久一区二区三区| 电影一区二区三| 欧美一区日韩一区| 亚洲欧美卡通动漫| 999在线观看精品免费不卡网站| 国产精品加勒比| 免费在线国产视频| 亚洲精品久久久久久久久久久久久 | 国产日本在线播放| 偷拍亚洲精品| 国产精品青草久久久久福利99| 国产日韩免费视频| 亚洲精品欧美在线| 性欧美丰满熟妇xxxx性久久久| 亚洲伦理精品| 亚洲精品免费网站| 丁香花在线高清完整版视频| 亚洲精品中文字幕av| 中文在线最新版天堂| zzijzzij亚洲日本少妇熟睡| 亚洲一卡二卡| 向日葵视频成人app网址| 日韩专区在线播放| 少妇久久久久久久| 中文字幕在线一区免费| 日本成人在线免费| 久久精品动漫| 久久精品中文字幕一区二区三区 | 一本久道综合色婷婷五月| 试看120秒一区二区三区| 最近2019中文字幕mv免费看 | 久久99精品久久久久久水蜜桃 | 欧美日韩在线亚洲一区蜜芽| 波多野结衣亚洲色图| 蜜桃91丨九色丨蝌蚪91桃色| 亚洲国产精品女人| 日韩欧美在线精品| 国产综合视频在线观看| sese一区| 欧美午夜影院一区| 中文字幕免费在线看线人动作大片| 亚洲黄色视屏| 先锋影音欧美| 豆花视频一区二区| 国产欧美日韩91| 精品三级久久| 精品亚洲一区二区| 国产内射老熟女aaaa∵| 日韩欧美成人精品| 久久久久黄色片| 国产白丝精品91爽爽久久| 97超碰人人爱| 你懂的一区二区三区| 日韩女优人人人人射在线视频| 老司机精品影院| 91精品一区二区三区久久久久久| 在线免费黄色av| 亚洲一级二级三级| 黄色香蕉视频在线观看| 精品综合久久久久久8888| 黄色片视频在线播放| 影音先锋亚洲一区| 日本精品福利视频| 欧美疯狂party性派对| 国产欧美日韩精品在线观看| www.综合| 久久久久久久国产| 五月婷婷免费视频| 日韩欧美高清一区| 一级特黄色大片| 亚洲小说欧美激情另类| 日韩av毛片在线观看| 欧美激情中文不卡| 三上悠亚影音先锋| 久久久精品影视| jizzzz日本| 亚洲视频碰碰| 欧美成人免费在线| 婷婷丁香久久| 国产精品免费一区二区三区都可以 | 国产黄色片av| 日韩欧美一区二区不卡| 99在线观看免费| 91精品国产乱码| av一区二区三| 欧美一级高清片在线观看| 99精品免费观看| 欧美丰满少妇xxxbbb| 久久免费视频精品| 亚洲综合激情另类小说区| 欧美图片一区二区| 久久综合视频网| 久久精品老司机| 久久久久国产精品免费免费搜索| 亚洲 小说 欧美 激情 另类| 国产午夜精品一区二区三区嫩草| 亚洲天堂久久新| 欧美激情一区二区| 国产精品视频看看| 亚洲视频网在线直播| 欧美黑人一级片| 亚洲午夜精品网| 性无码专区无码| 色av一区二区| 破处女黄色一级片| 久久视频一区二区| 日本美女xxx| 91免费视频网址| 三上悠亚 电影| 日本在线不卡视频| 老司机久久精品| 国产高清成人在线| a视频免费观看| 欧美高清在线视频| 国产国语性生话播放| 久久婷婷国产综合精品青草| 黄色国产在线播放| 久久蜜桃一区二区| 免费看一级黄色| 亚洲午夜国产一区99re久久| 国产免费一区二区三区四区五区| 精品视频色一区| 性生交生活影碟片| 666欧美在线视频| 亚洲美女福利视频| 亚洲精品一区二三区不卡| 三区四区在线视频| 97国产一区二区精品久久呦 | 亚洲一区二区视频在线观看| 国产无人区码熟妇毛片多| 911精品产国品一二三产区| 欧美一区二区三区黄片| 日韩欧美国产电影| 日本一级在线观看| 久久亚洲国产精品| 中文字幕乱码中文乱码51精品| 国产精品午夜视频| 国产精品久av福利在线观看| 亚洲不卡一卡2卡三卡4卡5卡精品| 日韩欧美一级| 日韩久久久久久久| 激情欧美一区| 特级黄色片视频| 国产亚洲成aⅴ人片在线观看| 欧美成人免费观看视频| 色婷婷精品久久二区二区蜜臂av | 中文字幕日本视频| 欧美精品一区二区三| 性一交一乱一色一视频麻豆| 亚洲日本成人女熟在线观看 | 亚洲最色的网站| 亚洲精品国产精品国自产网站按摩| 精品美女一区二区三区| 亚洲国产成人精品一区二区三区| 亚洲人成在线电影| 国内高清免费在线视频| 91在线播放国产| 亚洲一区电影| 一本久久a久久精品vr综合| 香蕉精品999视频一区二区| youjizz.com日本| 亚洲三级视频在线观看| 中文字幕一区二区人妻视频| 欧美精品一区二区三区在线播放| 麻豆影院在线观看| 国产精品免费电影| 欧美在线免费看视频| 日韩中文字幕三区| 日韩国产精品久久久久久亚洲| 日韩大尺度视频| 亚洲丝袜制服诱惑| 夜夜嗨aⅴ一区二区三区| 在线不卡中文字幕| 国产69久久| 美乳少妇欧美精品| 久久亚洲精品中文字幕| 99久久99久久| 中文在线播放一区二区| 亚欧美一区二区三区| 不卡欧美aaaaa| 微拍福利一区二区| 一本大道久久a久久综合| 亚洲色图欧美视频| 8090成年在线看片午夜| 欧美一区二区三区久久| 亚洲福利av| 日本欧美大码aⅴ在线播放| 精品人伦一区二区| 欧洲生活片亚洲生活在线观看| 精品999视频| 国产精品丝袜一区二区三区| 久久密一区二区三区| 亚洲国产日韩欧美在线观看| 欧美激情在线一区二区| 91国在线视频| 最新69国产成人精品视频免费| 欧美在线se| 香蕉视频免费版| 成人在线视频一区| 国产三级av片| 在线成人激情视频| 国产传媒在线观看| 久久免费99精品久久久久久| 丝袜亚洲另类欧美| 性生交大片免费看l| 亚洲国产一区二区在线播放| 天天操天天操天天操| 人人爽久久涩噜噜噜网站| 成人免费在线播放| 亚洲第一区第二区第三区| 亚洲一区二区三区四区在线观看| 天天爽夜夜爽夜夜爽| 国产精品18久久久久久首页狼| www.国产精品一区| 亚洲在线欧美| 国产精品一二三四| wwwwww国产| 色偷偷噜噜噜亚洲男人的天堂| 视频一区中文字幕精品| 北条麻妃在线视频观看| 国产精品亚洲专一区二区三区 | 日本三级在线观看网站| 国产精品成人观看视频国产奇米| 四季av一区二区三区免费观看| 久久人人爽人人片| 欧美视频在线观看 亚洲欧| 天堂中文8资源在线8| 国产亚洲福利社区| 亚洲天堂久久| 中国女人特级毛片| 亚洲成人久久久久| 欧美成人xxxx| 日本免费不卡一区二区| 国产精品久久久久aaaa樱花| 成人午夜精品福利免费| 国产精品丝袜高跟| 一本一道久久综合狠狠老精东影业| 日本人亚洲人jjzzjjz| 精品国产亚洲在线| 欧美网站免费| 国产精品第12页| 一区二区久久久久久|