MySQL 存儲(chǔ)引擎InnoDB 架構(gòu)與原理深度解析
索引結(jié)構(gòu)提供了高效的數(shù)據(jù)檢索方式,索引信息與數(shù)據(jù)記錄均存儲(chǔ)于文件系統(tǒng)中,具體而言是存儲(chǔ)在頁結(jié)構(gòu)中。索引的實(shí)現(xiàn)依賴于存儲(chǔ)引擎,MySQL 服務(wù)器通過存儲(chǔ)引擎完成對(duì)表數(shù)據(jù)的讀寫操作。不同存儲(chǔ)引擎的數(shù)據(jù)存儲(chǔ)格式各異,部分存儲(chǔ)引擎(如 MEMORY)甚至不使用磁盤存儲(chǔ)數(shù)據(jù),而是將數(shù)據(jù)保存在內(nèi)存中。
MySQL 支持的存儲(chǔ)引擎類型
通過以下命令可以查看 MySQL 支持的所有存儲(chǔ)引擎:
SHOW ENGINES;
查詢結(jié)果示例:
| 存儲(chǔ)引擎 | 支持狀態(tài) | 說明 | 事務(wù) | 分布式事務(wù) | 保存點(diǎn) |
|---|---|---|---|---|---|
| InnoDB | 默認(rèn) | 支持事務(wù)、行級(jí)鎖和外鍵 | 是 | 是 | 是 |
| MyISAM | 是 | 傳統(tǒng)存儲(chǔ)引擎,不支持事務(wù) | 否 | 否 | 否 |
| MEMORY | 是 | 基于哈希索引,數(shù)據(jù)存儲(chǔ)于內(nèi)存,適用于臨時(shí)表 | 否 | 否 | 否 |
| CSV | 是 | 以 CSV 格式存儲(chǔ)數(shù)據(jù) | 否 | 否 | 否 |
| ARCHIVE | 是 | 高壓縮比的歸檔存儲(chǔ)引擎 | 否 | 否 | 否 |
| BLACKHOLE | 是 | 黑洞存儲(chǔ)引擎,寫入的數(shù)據(jù)不會(huì)被保存 | 否 | 否 | 否 |
| FEDERATED | 否 | 聯(lián)邦存儲(chǔ)引擎,用于訪問遠(yuǎn)程表 | 空 | 空 | 空 |
| MRG_MYISAM | 是 | MyISAM 表的集合 | 否 | 否 | 否 |
| PERFORMANCE_SCHEMA | 是 | 性能監(jiān)控與診斷 | 否 | 否 | 否 |
默認(rèn)存儲(chǔ)引擎的查看與配置
版本差異
MySQL 在不同版本中采用不同的默認(rèn)存儲(chǔ)引擎:
- MySQL 5.5 及以后版本:默認(rèn)存儲(chǔ)引擎為 InnoDB
- MySQL 5.5 之前版本:默認(rèn)存儲(chǔ)引擎為 MyISAM
若在創(chuàng)建表時(shí)未顯式指定存儲(chǔ)引擎,MySQL 將自動(dòng)使用默認(rèn)存儲(chǔ)引擎。
查看當(dāng)前 MySQL 版本
SELECT VERSION();
查看默認(rèn)存儲(chǔ)引擎
SHOW VARIABLES LIKE 'default_storage_engine';
查詢結(jié)果示例(MySQL 5.6.40):
| Variable_name | Value |
|---|---|
| default_storage_engine | InnoDB |
修改默認(rèn)存儲(chǔ)引擎
- 方式一:通過配置文件修改(永久生效)
- 定位 MySQL 配置文件
- Linux 系統(tǒng):
my.cnf - Windows 系統(tǒng):
my.ini
- Linux 系統(tǒng):
- 在配置文件中添加或修改
[mysqld]部分:
[mysqld] default-storage-engine = InnoDB
重啟 MySQL 服務(wù)使配置生效:
systemctl restart mysqld.service
方式二:通過 SQL 命令修改(會(huì)話級(jí)別)
SET default_storage_engine = MyISAM;
主要存儲(chǔ)引擎特性對(duì)比
各存儲(chǔ)引擎核心特性
- InnoDB:支持 ACID 事務(wù)、行級(jí)鎖定、崩潰恢復(fù)、外鍵約束,是 MySQL 的默認(rèn)存儲(chǔ)引擎
- MyISAM:不支持事務(wù)、行級(jí)鎖和外鍵約束,但針對(duì)數(shù)據(jù)統(tǒng)計(jì)操作進(jìn)行了優(yōu)化,
COUNT(*)查詢效率較高 - MEMORY:將表數(shù)據(jù)完全存儲(chǔ)于內(nèi)存中,讀寫速度極快,但數(shù)據(jù)不具備持久性
- ARCHIVE:采用高壓縮比存儲(chǔ),適用于存儲(chǔ)大量歷史數(shù)據(jù),僅支持 INSERT 和 SELECT 操作
- NDB:分布式存儲(chǔ)引擎,支持高可用性和容錯(cuò)性,適用于高并發(fā)寫入場(chǎng)景
核心區(qū)別:InnoDB 與 MyISAM 的三大關(guān)鍵差異在于事務(wù)支持、外鍵約束和行級(jí)鎖定。
功能特性對(duì)比表
| 功能 | MyISAM | MEMORY | InnoDB |
|---|---|---|---|
| 存儲(chǔ)限制 | 258 TB | RAM | 64 TB |
| 事務(wù)支持 | × | × | √ |
| 全文索引支持 | √ | × | √(5.6+) |
| B 樹索引支持 | √ | √ | √ |
| 哈希索引支持 | × | √ | √(自適應(yīng)) |
| 集群索引支持 | × | × | √ |
| 數(shù)據(jù)索引支持 | × | √ | √ |
| 數(shù)據(jù)壓縮支持 | √ | × | × |
| 空間使用率 | 低 | N/A | 高 |
| 外鍵支持 | × | × | √ |
InnoDB 與 MyISAM 存儲(chǔ)引擎對(duì)比分析
InnoDB 存儲(chǔ)引擎
InnoDB 提供了完善的事務(wù)管理、崩潰恢復(fù)能力和并發(fā)控制機(jī)制。其主要優(yōu)勢(shì)在于:
- 事務(wù)完整性:支持 ACID 特性,適用于對(duì)數(shù)據(jù)一致性要求較高的應(yīng)用場(chǎng)景,特別是涉及頻繁更新和刪除操作的業(yè)務(wù)系統(tǒng)
- 并發(fā)性能:支持行級(jí)鎖定,能夠有效處理高并發(fā)訪問場(chǎng)景,避免表級(jí)鎖帶來的性能瓶頸
- 數(shù)據(jù)安全性:提供崩潰恢復(fù)功能,服務(wù)器異常重啟后能夠自動(dòng)恢復(fù)已提交的事務(wù)并回滾未提交的操作
主要劣勢(shì):
- 讀寫效率相對(duì)較低
- 磁盤空間占用較大
MyISAM 存儲(chǔ)引擎
MyISAM 適用于以讀取和插入操作為主、更新和刪除操作較少且對(duì)事務(wù)要求不高的系統(tǒng)。其主要優(yōu)勢(shì)在于:
- 查詢性能:在數(shù)據(jù)量較小的情況下,讀寫效率優(yōu)于 InnoDB
- 存儲(chǔ)效率:磁盤空間占用相對(duì)較少
主要劣勢(shì):
- 不支持事務(wù)和行級(jí)鎖,僅支持表級(jí)鎖
- 在高并發(fā)場(chǎng)景下容易出現(xiàn)鎖表問題,影響系統(tǒng)性能
選型建議
InnoDB 是處理大規(guī)模數(shù)據(jù)的首選存儲(chǔ)引擎。除非存在特殊的業(yè)務(wù)需求,否則應(yīng)優(yōu)先選擇 InnoDB 存儲(chǔ)引擎。
InnoDB 核心優(yōu)勢(shì)
- 崩潰恢復(fù):服務(wù)器崩潰后重啟時(shí),InnoDB 自動(dòng)執(zhí)行崩潰恢復(fù)流程,將已提交的事務(wù)固化到磁盤,回滾未提交的事務(wù),無需人工干預(yù)
- 緩沖池機(jī)制:InnoDB 在主內(nèi)存中維護(hù)緩沖池(Buffer Pool),將高頻訪問的數(shù)據(jù)緩存在內(nèi)存中直接處理,顯著提升數(shù)據(jù)訪問速度。該緩存機(jī)制適用于多種數(shù)據(jù)類型,有效加速數(shù)據(jù)處理過程
- 內(nèi)存配置:在專用數(shù)據(jù)庫服務(wù)器上,建議將物理內(nèi)存的 60%-80% 分配給 InnoDB 緩沖池
- 外鍵約束:支持外鍵約束以維護(hù)數(shù)據(jù)完整性。當(dāng)向子表插入數(shù)據(jù)時(shí),若主表中不存在對(duì)應(yīng)的主鍵記錄,插入操作將被自動(dòng)拒絕。更新或刪除主表數(shù)據(jù)時(shí),相關(guān)聯(lián)的子表數(shù)據(jù)會(huì)自動(dòng)更新或刪除
- 數(shù)據(jù)校驗(yàn):內(nèi)置校驗(yàn)和(Checksum)機(jī)制,在磁盤或內(nèi)存數(shù)據(jù)損壞時(shí)及時(shí)發(fā)出警告,防止使用損壞的數(shù)據(jù)
- 查詢優(yōu)化:當(dāng)表的主鍵設(shè)計(jì)合理時(shí),涉及主鍵的操作會(huì)被自動(dòng)優(yōu)化。插入、更新、刪除操作通過變更緩沖(Change Buffer)機(jī)制自動(dòng)優(yōu)化
- 讀寫并行:InnoDB 不僅支持當(dāng)前讀寫操作,還會(huì)將變更數(shù)據(jù)緩存并異步刷新到磁盤
- 自適應(yīng)哈希索引:當(dāng)同一列被頻繁查詢時(shí),自適應(yīng)哈希索引會(huì)自動(dòng)創(chuàng)建,顯著提升查詢性能
- 表壓縮:支持表和索引的壓縮,在不影響性能和可用性的前提下節(jié)省存儲(chǔ)空間
- 在線 DDL:支持在不影響業(yè)務(wù)的情況下創(chuàng)建或刪除索引
- 大對(duì)象存儲(chǔ):對(duì)于大型文本和 BLOB 數(shù)據(jù),采用動(dòng)態(tài)行格式(Dynamic Row Format),提供更高效的存儲(chǔ)布局
- 監(jiān)控能力:通過查詢 INFORMATION_SCHEMA 數(shù)據(jù)庫中的系統(tǒng)表,可以實(shí)時(shí)監(jiān)控存儲(chǔ)引擎的內(nèi)部運(yùn)行狀態(tài)
- 混合使用:在同一 SQL 語句中,InnoDB 表可以與其他存儲(chǔ)引擎的表混合使用
- 大文件支持:即使操作系統(tǒng)限制單個(gè)文件大小為 2GB,InnoDB 仍然可以處理更大的數(shù)據(jù)量
- CPU 優(yōu)化:在處理大數(shù)據(jù)量時(shí),InnoDB 能夠充分利用 CPU 資源以達(dá)到最優(yōu)性能
表級(jí)存儲(chǔ)引擎操作
| 操作描述 | SQL 語句 |
|---|---|
| 查看表的存儲(chǔ)引擎 | SHOW TABLE STATUS LIKE 表名稱; |
| 創(chuàng)建表時(shí)指定存儲(chǔ)引擎 | CREATE TABLE 表名稱 (…) ENGINE = 存儲(chǔ)引擎名稱; |
| 修改表的存儲(chǔ)引擎 | ALTER TABLE 表名稱 ENGINE = 存儲(chǔ)引擎名稱; |
| 查看數(shù)據(jù)庫所有表的存儲(chǔ)引擎 | SELECT TABLE_NAME, ENGINE FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ‘數(shù)據(jù)庫名稱’; |
| 查看表的創(chuàng)建語句(包括存儲(chǔ)引擎) | SHOW CREATE TABLE 表名稱; |
InnoDB 存儲(chǔ)引擎架構(gòu)
頁:磁盤與內(nèi)存交互的基本單位
InnoDB 將數(shù)據(jù)劃分為若干個(gè)頁(Page),默認(rèn)頁大小為 16KB。頁是磁盤與內(nèi)存之間數(shù)據(jù)交換的基本單位,即每次至少?gòu)拇疟P讀取 16KB 數(shù)據(jù)到內(nèi)存,或?qū)?nèi)存中的 16KB 數(shù)據(jù)刷新到磁盤。
設(shè)計(jì)原理:數(shù)據(jù)庫不以行為單位進(jìn)行讀取,否則每次磁盤 I/O 操作僅能處理一行數(shù)據(jù),效率極低。
在數(shù)據(jù)庫系統(tǒng)中,無論讀取一行還是多行數(shù)據(jù),都會(huì)將這些行所在的整個(gè)頁加載到內(nèi)存。因此,頁是數(shù)據(jù)庫管理存儲(chǔ)空間和執(zhí)行 I/O 操作的最小單位,一個(gè)頁可以存儲(chǔ)多行記錄。
不同數(shù)據(jù)庫系統(tǒng)的頁大小
- MySQL InnoDB:16KB(默認(rèn))
- SQL Server:8KB
- Oracle:2KB、4KB、8KB、16KB、32KB、64KB(稱為"塊")
查看 InnoDB 頁大?。?/p>
SHOW VARIABLES LIKE '%innodb_page_size%';
查詢結(jié)果默認(rèn)為 16384 字節(jié),即 16KB。
頁結(jié)構(gòu)組織方式
頁之間通過雙向鏈表關(guān)聯(lián),無需在物理結(jié)構(gòu)上連續(xù)存儲(chǔ)。每個(gè)數(shù)據(jù)頁內(nèi)部的記錄按主鍵值從小到大組成單向鏈表。為了提高查詢效率,每個(gè)數(shù)據(jù)頁會(huì)為其中的記錄生成頁目錄(Page Directory),通過主鍵查找記錄時(shí),可以在頁目錄中使用二分查找法快速定位到對(duì)應(yīng)的槽(Slot),然后遍歷該槽對(duì)應(yīng)分組中的記錄即可快速找到目標(biāo)記錄。
InnoDB 存儲(chǔ)結(jié)構(gòu)層次
InnoDB 采用分層的存儲(chǔ)結(jié)構(gòu),從小到大依次為:行(Row)、頁(Page)、區(qū)(Extent)、段(Segment)、表空間(Tablespace)。


存儲(chǔ)結(jié)構(gòu)層次關(guān)系
- 行(Row):數(shù)據(jù)庫表中的一條記錄
- 頁(Page):InnoDB 的基本存儲(chǔ)單位,默認(rèn) 16KB,包含多行記錄
- 區(qū)(Extent):由 64 個(gè)連續(xù)的頁組成,大小為 1MB(64 × 16KB)
- 段(Segment):由一個(gè)或多個(gè)區(qū)組成,如數(shù)據(jù)段、索引段、回滾段等
- 表空間(Tablespace):最高層的邏輯容器,包含多個(gè)段
區(qū)(Extent)
區(qū)是比頁更高一級(jí)的存儲(chǔ)結(jié)構(gòu)。在 InnoDB 中,一個(gè)區(qū)包含 64 個(gè)連續(xù)的頁。由于頁的默認(rèn)大小為 16KB,因此一個(gè)區(qū)的大小為 64 × 16KB = 1024KB = 1MB。
段(Segment)
段由一個(gè)或多個(gè)區(qū)組成。區(qū)在文件系統(tǒng)中是連續(xù)分配的空間(在 InnoDB 中為連續(xù)的 64 個(gè)頁),但段中的區(qū)之間無需相鄰。段是數(shù)據(jù)庫的分配單位,不同類型的數(shù)據(jù)庫對(duì)象以不同的段形式存在。創(chuàng)建表時(shí)會(huì)創(chuàng)建表段,創(chuàng)建索引時(shí)會(huì)創(chuàng)建索引段。
根據(jù)存儲(chǔ)內(nèi)容和用途的不同,InnoDB 中的段主要分為以下三種類型:
1. 數(shù)據(jù)段(Data Segment / Leaf Node Segment)
數(shù)據(jù)段用于存儲(chǔ)表的實(shí)際數(shù)據(jù)行,對(duì)應(yīng) B+ 樹索引結(jié)構(gòu)的葉子節(jié)點(diǎn)。
- 存儲(chǔ)位置:B+ 樹的葉子節(jié)點(diǎn)層
- 存儲(chǔ)內(nèi)容:在 InnoDB 的聚簇索引(主鍵索引)中,葉子節(jié)點(diǎn)存儲(chǔ)完整的行數(shù)據(jù),包括所有列的值
- 數(shù)量關(guān)系:每個(gè) InnoDB 表至少有一個(gè)數(shù)據(jù)段,對(duì)應(yīng)主鍵索引的葉子節(jié)點(diǎn)部分
- 訪問特點(diǎn):數(shù)據(jù)段是順序掃描和范圍查詢的主要訪問對(duì)象
2. 索引段(Index Segment / Non-Leaf Node Segment)
索引段用于存儲(chǔ)索引的非葉子節(jié)點(diǎn)數(shù)據(jù),對(duì)應(yīng) B+ 樹索引結(jié)構(gòu)的內(nèi)部節(jié)點(diǎn)。
- 存儲(chǔ)位置:B+ 樹的非葉子節(jié)點(diǎn)層(根節(jié)點(diǎn)和中間節(jié)點(diǎn))
- 存儲(chǔ)內(nèi)容:索引鍵值和指向下一層節(jié)點(diǎn)的指針,用于快速定位數(shù)據(jù)位置
- 適用范圍:
- 主鍵索引的非葉子節(jié)點(diǎn)屬于索引段
- 二級(jí)索引(輔助索引)的所有節(jié)點(diǎn)(包括葉子節(jié)點(diǎn)和非葉子節(jié)點(diǎn))都屬于索引段
- 作用:通過索引段的層次結(jié)構(gòu),實(shí)現(xiàn)高效的數(shù)據(jù)檢索
3. 回滾段(Rollback Segment / Undo Segment)
回滾段用于存儲(chǔ)事務(wù)的回滾信息(Undo Log),是 InnoDB 事務(wù)機(jī)制的核心組件。
- 存儲(chǔ)內(nèi)容:數(shù)據(jù)修改前的舊版本(Undo Log)
- 主要用途:
- 事務(wù)回滾:當(dāng)事務(wù)執(zhí)行失敗或主動(dòng)回滾時(shí),使用 Undo Log 將數(shù)據(jù)恢復(fù)到修改前的狀態(tài)
- MVCC 實(shí)現(xiàn):通過保存數(shù)據(jù)的歷史版本,支持多版本并發(fā)控制(Multi-Version Concurrency Control),使不同事務(wù)能夠讀取到數(shù)據(jù)的不同版本
- 崩潰恢復(fù):系統(tǒng)崩潰后,利用 Undo Log 回滾未提交的事務(wù)
- 事務(wù)保證:回滾段是實(shí)現(xiàn)事務(wù)原子性(Atomicity)和一致性(Consistency)的關(guān)鍵機(jī)制
三種段的協(xié)同工作


段類型對(duì)比表
| 特性 | 數(shù)據(jù)段 | 索引段 | 回滾段 |
|---|---|---|---|
| 存儲(chǔ)內(nèi)容 | 完整的行數(shù)據(jù) | 索引鍵值和指針 | 數(shù)據(jù)修改前的舊版本 |
| 對(duì)應(yīng)結(jié)構(gòu) | B+ 樹葉子節(jié)點(diǎn) | B+ 樹非葉子節(jié)點(diǎn) | Undo Log |
| 主要用途 | 存儲(chǔ)表數(shù)據(jù) | 加速數(shù)據(jù)檢索 | 事務(wù)回滾和 MVCC |
| 創(chuàng)建時(shí)機(jī) | 創(chuàng)建表時(shí) | 創(chuàng)建索引時(shí) | 事務(wù)修改數(shù)據(jù)時(shí) |
| 生命周期 | 與表同生命周期 | 與索引同生命周期 | 事務(wù)提交后可清理 |
| 訪問頻率 | 高(數(shù)據(jù)查詢) | 高(索引查詢) | 中(事務(wù)回滾、MVCC) |
表空間(Tablespace)
表空間是邏輯容器,用于存儲(chǔ)段。一個(gè)表空間可以包含一個(gè)或多個(gè)段,但一個(gè)段只能屬于一個(gè)表空間。數(shù)據(jù)庫由一個(gè)或多個(gè)表空間組成,表空間從管理角度可劃分為系統(tǒng)表空間、用戶表空間、撤銷表空間、臨時(shí)表空間等。
到此這篇關(guān)于MySQL 存儲(chǔ)引擎InnoDB 架構(gòu)與原理深度解析的文章就介紹到這了,更多相關(guān)MySQL 存儲(chǔ)引擎InnoDB內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在MySQL數(shù)據(jù)庫中使用C執(zhí)行SQL語句的方法
與PostgreSQL相似,可使用許多不同的語言來訪問MySQL,包括C、C++、Java和Perl。從Professional Linux Programming中第5章有關(guān)MySQL的下列章節(jié)中,Neil Matthew和Richard Stones使用詳盡的MySQL C接口向我們介紹了如何在MySQL數(shù)據(jù)庫中執(zhí)行SQL語句。2012-10-10
mysql 數(shù)據(jù)插入優(yōu)化方法之concurrent_insert
在MyISAM里讀寫操作是串行的,但當(dāng)對(duì)同一個(gè)表進(jìn)行查詢和插入操作時(shí),為了降低鎖競(jìng)爭(zhēng)的頻率,根據(jù)concurrent_insert的設(shè)置,MyISAM是可以并行處理查詢和插入的2021-07-07
查看MySQL中已經(jīng)創(chuàng)建的存儲(chǔ)過程及其定義
在MySQL中,查看已創(chuàng)建存儲(chǔ)過程的方法包括使用SHOW CREATE PROCEDURE命令查看存儲(chǔ)過程定義,查詢INFORMATION_SCHEMA.Routines表或mysql.proc表獲取存儲(chǔ)過程信息,使用source命令執(zhí)行存儲(chǔ)過程創(chuàng)建腳本,或查看存儲(chǔ)過程的文檔注釋,這些方法有助于了解和管理數(shù)據(jù)庫中的存儲(chǔ)過程2024-11-11
MySQL如何從5.5升級(jí)到8.0(使用命令行升級(jí))
最近為了解決mysql低版本的漏洞,這篇文章主要給大家介紹了關(guān)于MySQL如何從5.5升級(jí)到8.0的相關(guān)資料,主要使用的命令行升級(jí),文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03
IDEA的database插件無法連接mysql的解決辦法(08001錯(cuò)誤)
用navicat鏈接數(shù)據(jù)庫正常,mysql控制臺(tái)操作正常,但是用IDEA的數(shù)據(jù)庫插件鏈接一直報(bào) 08001 錯(cuò)誤,本文就給大家介紹一下IDEA的database插件無法連接mysql報(bào)08001錯(cuò)誤的解決辦法,需要的朋友可以參考下2024-07-07

