《InnoDB 存儲(chǔ)引擎》學(xué)習(xí)筆記

第1章 MySQL 體系結(jié)構(gòu)和存儲(chǔ)引擎

1.1 定義數(shù)據(jù)庫和實(shí)例

  • MySQL的跨平臺(tái)特性:MySQL可以在多種操作系統(tǒng)上運(yùn)行,如Linux、Solaris、FreeBSD、Mac和Windows。

  • 數(shù)據(jù)庫(database):是物理操作系統(tǒng)文件或其他形式文件類型的集合。在MySQL中,數(shù)據(jù)庫文件可以是frm、MYD、MYI、ibd結(jié)尾的文件。

  • 實(shí)例(instance):MySQL數(shù)據(jù)庫由后臺(tái)線程以及一個(gè)共享內(nèi)存區(qū)組成。實(shí)例與數(shù)據(jù)庫的關(guān)系通常是一對一的,但在集群情況下可能存在一個(gè)數(shù)據(jù)庫被多個(gè)數(shù)據(jù)實(shí)例使用的情況。

  • MySQL實(shí)例啟動(dòng)命令

    ./mysqld_safe
    
  • 查看MySQL進(jìn)程

    ps -ef | grep mysqld
    

1.2 MySQL 體系結(jié)構(gòu)

  • MySQL體系結(jié)構(gòu)組成
    • 連接池組件
    • 管理服務(wù)和工具組件
    • SQL接口組件
    • 查詢分析器組件
    • 優(yōu)化器組件
    • 緩沖(Cache)組件
    • 插件式存儲(chǔ)引擎
    • 物理文件

1.3 MySQL 存儲(chǔ)引擎

1.3.1 InnoDB 存儲(chǔ)引擎
  • 特點(diǎn)
    • 支持事務(wù)、行鎖、MVCC。
    • 從MySQL 5.5.8版本開始,默認(rèn)存儲(chǔ)引擎。
    • 支持?jǐn)?shù)據(jù)和索引的獨(dú)立存儲(chǔ)。
    • 支持插入緩沖、二次寫、自適應(yīng)哈希索引等高級功能。
  • 適用場景:適用于需要事務(wù)支持的OLTP應(yīng)用。
1.3.2 MyISAM 存儲(chǔ)引擎
  • 特點(diǎn)
    • 不支持事務(wù)、表鎖設(shè)計(jì)。
    • 適合OLAP數(shù)據(jù)庫應(yīng)用。
    • 由MYD和MYI組成,MYD存放數(shù)據(jù)文件,MYI存放索引文件。
    • 支持全文索引。
  • 適用場景:適用于讀多寫少的OLAP應(yīng)用。
1.3.3 NDB 存儲(chǔ)引擎
  • 特點(diǎn)
    • 集群存儲(chǔ)引擎,類似于Oracle的RAC。
    • 數(shù)據(jù)全部放在內(nèi)存中,提供高可用性和高性能。
    • 支持share nothing的集群架構(gòu)。
  • 適用場景:適用于需要高可用性和高性能的集群系統(tǒng)。
1.3.4 Memory 存儲(chǔ)引擎
  • 特點(diǎn)
    • 將數(shù)據(jù)存儲(chǔ)在內(nèi)存中,速度快但易丟失。
    • 適合臨時(shí)表和數(shù)據(jù)緩存。
    • 不支持TEXT和BLOB列類型。
  • 適用場景:適用于需要快速訪問的臨時(shí)數(shù)據(jù)。
1.3.5 Archive 存儲(chǔ)引擎
  • 特點(diǎn)
    • 僅支持INSERT和SELECT操作。
    • 使用zlib算法壓縮數(shù)據(jù)。
    • 適合歸檔數(shù)據(jù)。
  • 適用場景:適用于需要高壓縮比的歸檔數(shù)據(jù)。
1.3.6 Federated 存儲(chǔ)引擎
  • 特點(diǎn)
    • 不存儲(chǔ)數(shù)據(jù),指向遠(yuǎn)程MySQL服務(wù)器上的表。
    • 類似于SQL Server的鏈接服務(wù)器和Oracle的透明網(wǎng)關(guān)。
  • 適用場景:適用于需要訪問遠(yuǎn)程MySQL服務(wù)器上的數(shù)據(jù)。
1.3.7 Maria 存儲(chǔ)引擎
  • 特點(diǎn)
    • 由MySQL創(chuàng)始人Michael Widenius開發(fā)。
    • 支持事務(wù)、MVCC、BLOB字符類型。
    • 適用于需要高性能和高可用性的OLTP應(yīng)用。
  • 適用場景:適用于需要高性能和高可用性的OLTP應(yīng)用。

1.4 各存儲(chǔ)引擎之間的比較

特性 MyISAM BDB 內(nèi)存 InnoDB 歸檔 NDB
存儲(chǔ)限制 64TB
事務(wù)(提交、回滾等)
鎖定粒度
MVCC/快照讀取
地理空間支持
B樹索引
哈希索引
全文搜索索引
聚簇索引
數(shù)據(jù)緩存
索引緩存
壓縮數(shù)據(jù)
加密數(shù)據(jù)(通過函數(shù))
存儲(chǔ)成本(空間使用) 不適用 非常低
內(nèi)存成本 中等
批量插入速度 非常低
集群數(shù)據(jù)庫支持
復(fù)制支持
外鍵支持
備份/點(diǎn)時(shí)間恢復(fù)
查詢緩存支持
數(shù)據(jù)字典更新統(tǒng)計(jì)

1.5 連接 MySQL

1.5.1 TCP/IP
  • 連接命令

    mysql -h <host> -u <user> -p
    
1.5.2 命名管道和共享內(nèi)存
  • Windows系統(tǒng)

    • 使用命名管道連接:

      --enable-named-pipe
      
    • 使用共享內(nèi)存連接:

      --shared-memory
      
1.5.3 UNIX 域套接字
  • Linux和UNIX系統(tǒng)

    • 使用UNIX域套接字連接:

      mysql -u <user> -S /tmp/mysql.sock
      

第2章 InnoDB 存儲(chǔ)引擎

2.1 InnoDB 概述

  1. 基本特性
    • ACID 事務(wù)支持:首個(gè)完整支持 ACID 的 MySQL 存儲(chǔ)引擎(BDB 曾支持但已停止開發(fā)),支持行級鎖、MVCC(多版本并發(fā)控制)、外鍵約束。
    • 設(shè)計(jì)目標(biāo):高效利用內(nèi)存和 CPU,適用于 OLTP 場景,自 MySQL 5.5 起成為默認(rèn)存儲(chǔ)引擎。
    • 應(yīng)用場景:大型網(wǎng)站(如 Google、Facebook)、網(wǎng)絡(luò)游戲(如《魔獸世界》)廣泛使用。
  2. 版本演進(jìn)
版本 關(guān)鍵功能
老版本 InnoDB 支持 ACID、行鎖、MVCC
1.0.x(InnoDB Plugin) 新增壓縮頁(compress/dynamic 頁格式)
1.1.x 支持 Linux Native AIO、多回滾段,提升并發(fā)事務(wù)處理能力
1.2.x 支持全文索引、在線索引添加、Page Cleaner Thread 優(yōu)化臟頁刷新

2.2 體系架構(gòu)

  1. 后臺(tái)線程
    • Master Thread:核心線程,負(fù)責(zé)臟頁異步刷新、插入緩沖合并、Undo 頁回收等,版本演進(jìn)中逐步優(yōu)化刷新策略(如 1.0.x 引入innodb_io_capacity控制刷頁數(shù)量)。
    • IO Thread:處理異步 IO 回調(diào),1.0.x 后讀寫線程各增至 4 個(gè),通過innodb_read/write_io_threads配置。
    • Purge Thread:1.1.x 后獨(dú)立線程回收 Undo 頁,1.2.x 支持多 Purge Thread 提升回收效率。
    • Page Cleaner Thread(1.2.x 引入):獨(dú)立處理臟頁刷新,減輕 Master Thread 壓力。
  2. 內(nèi)存結(jié)構(gòu)
    • 緩沖池(innodb_buffer_pool_size):緩存數(shù)據(jù)頁、索引頁、Undo 頁、插入緩沖等,支持多實(shí)例(innodb_buffer_pool_instances)減少資源競爭。
    • LRU 列表優(yōu)化:引入 midpoint 插入策略(innodb_old_blocks_pct控制比例),避免全表掃描污染熱點(diǎn)數(shù)據(jù);通過innodb_old_blocks_time控制頁進(jìn)入熱端的延遲。
    • 重做日志緩沖(innodb_log_buffer_size):默認(rèn) 8MB,每秒刷新或事務(wù)提交時(shí)寫入磁盤,確保持久性。
    • 額外內(nèi)存池:分配數(shù)據(jù)結(jié)構(gòu)內(nèi)存(如緩沖控制塊),需根據(jù)緩沖池大小調(diào)整。

2.3 關(guān)鍵特性

  1. 插入緩沖(Insert Buffer/Change Buffer)
    • 原理:非唯一輔助索引插入時(shí),若目標(biāo)頁不在緩沖池,先緩存到 Insert Buffer,后續(xù)合并以減少隨機(jī) IO。
    • 升級:1.0.x 引入 Change Buffer,支持 INSERT、DELETE、UPDATE 緩沖(需非唯一輔助索引),通過innodb_change_buffer_max_size控制最大內(nèi)存占用(默認(rèn) 25%)。
  2. 兩次寫(Double Write)
    • 作用:防止部分寫失效,臟頁先寫入共享表空間的 doublewrite buffer(2MB),再寫入數(shù)據(jù)文件,提升數(shù)據(jù)可靠性。
  3. 自適應(yīng)哈希索引(AHI)
    • 自動(dòng)優(yōu)化:監(jiān)控索引頁訪問頻率,對熱點(diǎn)頁構(gòu)建哈希索引,加速等值查詢(O (1) 復(fù)雜度)。
  4. 異步 IO(Async IO)
    • 優(yōu)勢:支持 Native AIO(Linux/Windows),合并多個(gè) IO 請求,提升磁盤吞吐量,1.1.x 版本后默認(rèn)啟用。
  5. 刷新鄰接頁(Flush Neighbor Page)
    • 機(jī)制:刷新臟頁時(shí)同步刷新同區(qū)的臟頁,機(jī)械硬盤場景提升效率,固態(tài)硬盤可通過innodb_flush_neighbors關(guān)閉。

2.4 啟動(dòng)與恢復(fù)

  • 參數(shù)影響
    • innodb_fast_shutdown:0(完整清理)、1(默認(rèn),快速關(guān)閉)、2(僅寫日志,啟動(dòng)時(shí)恢復(fù))。
    • innodb_force_recovery:故障時(shí)強(qiáng)制恢復(fù)(1-6 級,跳過部分檢查,需謹(jǐn)慎使用)。

第3章 文件

3.1 MySQL 核心文件類型

  1. 參數(shù)文件(my.cnf)
    • 作用:配置實(shí)例啟動(dòng)參數(shù)(如內(nèi)存大小、日志路徑),分動(dòng)態(tài)(運(yùn)行中修改)和靜態(tài)參數(shù)(需重啟生效)。
    • 查看方式SHOW VARIABLESINFORMATION_SCHEMA.GLOBAL_VARIABLES
  2. 日志文件
日志類型 功能 關(guān)鍵參數(shù)
錯(cuò)誤日志 記錄啟動(dòng)、運(yùn)行、關(guān)閉錯(cuò)誤及警告 log_error(路徑)
慢查詢?nèi)罩?/td> 記錄執(zhí)行時(shí)間超過閾值(long_query_time,默認(rèn) 10 秒)或未使用索引的 SQL log_slow_queries(啟用)、log_queries_not_using_indexes
二進(jìn)制日志(binlog) 記錄數(shù)據(jù)更改操作(不包括 SELECT),用于恢復(fù)和復(fù)制 log_bin(啟用)、binlog_format(STATEMENT/ROW/MIXED)
查詢?nèi)罩?/td> 記錄所有請求(包括失敗操作) log_output(FILE/TABLE)

3.2 InnoDB 存儲(chǔ)引擎文件

  1. 表空間文件
    • 共享表空間:默認(rèn)ibdata1,存儲(chǔ)系統(tǒng)數(shù)據(jù)、回滾段等,可通過innodb_data_file_path配置多文件。
    • 獨(dú)立表空間innodb_file_per_table=ON時(shí),每個(gè)表生成.ibd文件(存儲(chǔ)數(shù)據(jù)、索引),減少共享表空間膨脹。
  2. 重做日志文件
    • 作用:記錄 InnoDB 事務(wù)日志,用于崩潰恢復(fù),默認(rèn)ib_logfile0ib_logfile1,循環(huán)寫入。
    • 關(guān)鍵參數(shù)innodb_log_file_size(單個(gè)文件大小,1.2.x 后最大 512GB)、innodb_log_files_in_group(每組文件數(shù),默認(rèn) 2)。
    • 寫入策略innodb_flush_log_at_trx_commit=1(提交時(shí)同步寫磁盤,保證持久性)。

3.3 其他重要文件

  • 表結(jié)構(gòu)文件(.frm):存儲(chǔ)表定義(包括視圖),文本格式,可直接查看。
  • 套接字文件(socket):UNIX 域套接字連接使用,默認(rèn)/tmp/mysql.sock。
  • PID 文件:記錄實(shí)例進(jìn)程 ID,默認(rèn)位于數(shù)據(jù)目錄。

3.4 總結(jié)

  • InnoDB 優(yōu)勢:通過多線程架構(gòu)、內(nèi)存優(yōu)化(緩沖池 / LRU)、事務(wù)可靠性特性(兩次寫 / 重做日志),成為 OLTP 首選引擎。
  • 文件管理:二進(jìn)制日志和重做日志是恢復(fù)與復(fù)制的核心,需合理配置大小和策略;獨(dú)立表空間便于單表管理,但共享表空間仍存儲(chǔ)系統(tǒng)關(guān)鍵數(shù)據(jù)。
  • 版本差異:不同 InnoDB 版本在功能(如全文索引)和性能(如 AIO 支持)上有顯著差異,需根據(jù)業(yè)務(wù)場景選擇。

第4章 表

4.1 索引組織表

  • InnoDB存儲(chǔ)引擎中的表是基于主鍵順序組織存放的,稱為索引組織表。每張表都有一個(gè)主鍵(Primary Key)。
  • 如果創(chuàng)建表時(shí)沒有顯式定義主鍵,InnoDB存儲(chǔ)引擎會(huì)自動(dòng)創(chuàng)建一個(gè)6字節(jié)大小的指針作為主鍵。
  • 主鍵的選擇基于定義的順序,而不是創(chuàng)建表列的順序。

4.2 InnoDB 邏輯存儲(chǔ)結(jié)構(gòu)

  1. 表空間(Tablespace):所有數(shù)據(jù)都邏輯地存放在一個(gè)空間中。

  2. 段(Segment):表空間由段組成,包括葉節(jié)點(diǎn)段、非葉節(jié)點(diǎn)段和回滾段。

  3. 區(qū)(Extent):段由區(qū)組成,每個(gè)區(qū)包含64個(gè)連續(xù)的頁。

  4. 頁(Page):區(qū)由頁組成,頁是InnoDB磁盤管理的最小單位,默認(rèn)大小為16KB。

    • 數(shù)據(jù)頁(B-tree Node):存儲(chǔ)實(shí)際數(shù)據(jù)的頁。
    • Undo頁(Undo Log Page):用于存儲(chǔ)事務(wù)回滾信息。
    • 系統(tǒng)頁(System Page):存儲(chǔ)系統(tǒng)信息。
    • 事務(wù)數(shù)據(jù)頁(Transaction system Page):存儲(chǔ)事務(wù)信息。
    • 插入緩沖位圖頁(Insert Buffer Bitmap):用于管理插入緩沖區(qū)。
    • 插入緩沖空閑列表頁(Insert Buffer Free List):管理插入緩沖區(qū)的空閑頁。
    • 未壓縮的二進(jìn)制大對象頁(Uncompressed BLOB Page):存儲(chǔ)未壓縮的BLOB數(shù)據(jù)。
    • 壓縮的二進(jìn)制大對象頁(Compressed BLOB Page):存儲(chǔ)壓縮后的BLOB數(shù)據(jù)。
  5. 行(Row):頁中存儲(chǔ)行記錄,每行數(shù)據(jù)包括記錄頭信息和實(shí)際列數(shù)據(jù)。

    • InnoDB存儲(chǔ)引擎是面向行的,每頁最多存放16KB,即1024行記錄。

4.3 InnoDB 行記錄格式

  1. Compact行記錄格式:高效存儲(chǔ)數(shù)據(jù),一個(gè)頁中存放的行數(shù)據(jù)越多,性能越高。

    • 變長字段長度列表:按列逆序存放。
    • NULL標(biāo)志位:用1字節(jié)表示。
    • 記錄頭信息:固定占用5字節(jié)。
    • 列數(shù)據(jù):實(shí)際存儲(chǔ)每個(gè)列的數(shù)據(jù)。
  2. Redundant行記錄格式:兼容之前版本的頁格式。

    • 字段長度偏移列表:按列逆序存放。

    • 記錄頭信息:固定占用6字節(jié)。

  3. 行溢出數(shù)據(jù)

    • 當(dāng)行數(shù)據(jù)超出頁大小時(shí),會(huì)存儲(chǔ)在BLOB頁中。

    • BLOB頁可以存儲(chǔ)大對象數(shù)據(jù),如TEXT、VARCHAR等。

4.4 InnoDB 數(shù)據(jù)頁結(jié)構(gòu)

  1. File Header(文件頭):記錄頁的一些頭信息,共38字節(jié)。
  2. Page Header(頁頭):記錄數(shù)據(jù)頁的狀態(tài)信息,共56字節(jié)。
  3. Infimum和Supremum Records:虛擬行記錄,用于限定記錄的邊界。
  4. User Records(用戶記錄,即行記錄):實(shí)際存儲(chǔ)行記錄的內(nèi)容。
  5. Free Space(空閑空間):頁中未使用的空間。
  6. Page Directory(頁目錄):記錄頁中記錄的相對位置。
  7. File Trailer(文件結(jié)尾信息):用于檢測頁的完整性。

4.5 Named File Formats 機(jī)制

  • InnoDB 1.0.x版本引入了新的文件格式(file format),稱為Barracuda文件格式。

  • 新的文件格式支持Compacted和Dynamic行記錄格式。

  • 參數(shù)innodb_file_format指定文件格式,可以通過以下命令查看當(dāng)前使用的InnoDB存儲(chǔ)引擎的文件格式:

    mysql> SELECT @@version;
    mysql> SHOW VARIABLES LIKE 'innodb_version';
    mysql> SHOW VARIABLES LIKE 'innodb_file_format';
    

4.6 約束

4.6.1 約束類型
  1. 數(shù)據(jù)完整性:關(guān)系數(shù)據(jù)庫通過約束機(jī)制保證數(shù)據(jù)的完整性。

  2. 約束類型:主鍵(Primary Key)、唯一鍵(Unique Key)、外鍵(Foreign Key)、默認(rèn)值(Default)

特性 主鍵(Primary Key) 唯一鍵(Unique Key) 外鍵(Foreign Key)
唯一性 必須唯一,且不能為NULL 必須唯一,但可以為NULL 可以重復(fù),值必須是被引用表中主鍵或唯一鍵的有效值,或者NULL
數(shù)量限制 一個(gè)表只能有一個(gè)主鍵 一個(gè)表可以有多個(gè)唯一鍵 一個(gè)表可以有多個(gè)外鍵
主要作用 唯一標(biāo)識(shí)表中的記錄,方便對數(shù)據(jù)進(jìn)行操作 保證數(shù)據(jù)的唯一性,作為備選鍵 建立表之間的關(guān)聯(lián)關(guān)系,維護(hù)數(shù)據(jù)的完整性
示例 學(xué)生編號(StudentID) 身份證號(IDNumber) 班級編號(ClassID)
4.6.2 約束的創(chuàng)建和查找
  • 可以在創(chuàng)建表時(shí)定義約束;可以使用ALTER TABLE添加約束;可以通過CREATE INDEX創(chuàng)建唯一鍵約束。

  • 使用 information_schema 架構(gòu)下的 TABLE_CONSTRAINTSREFERENTIAL_CONSTRAINTS 表查看約束信息。

    SELECT constraint_name, constraint_type
    FROM information_schema.TABLE_CONSTRAINTS
    WHERE table_schema='mytest' AND table_name='u';
    
4.6.3 約束和索引的區(qū)別
  1. 約束是邏輯概念,保證數(shù)據(jù)完整性。
  2. 索引是數(shù)據(jù)結(jié)構(gòu),提高查詢性能。
4.6.4 對錯(cuò)誤數(shù)據(jù)的約束
  • 通過設(shè)置 sql_mode 參數(shù)來控制錯(cuò)誤數(shù)據(jù)的插入。

    STRICT_TRANS_TABLES:嚴(yán)格檢查約束。

    SET sql_mode = 'STRICT_TRANS_TABLES';
    
4.6.5 ENUM和SET約束
  • ENUM和SET用于限制列的取值范圍。

    CREATE TABLE a (
       id INT,
       sex ENUM('male','female')
     );
    
4.6.6 觸發(fā)器與約束
  • 觸發(fā)器可以在INSERT、UPDATE、DELETE操作之前或之后執(zhí)行。

    CREATE TRIGGER tgr_Orders_insert
    AFTER INSERT ON Orders
    FOR EACH ROW
    BEGIN
       SET @old_price_sum = 0;
       SET @old_amount_sum = 0;
       SET @old_price_avg = 0;
       SET @old_orders_cnt = 0;
       SELECT IFNULL(price_sum, 0), IFNULL(amount_sum, 0), IFNULL(price_avg, 0), IFNULL(orders_cnt, 0)
       FROM Orders_MV
       WHERE product_name = NEW.product_name
       INTO @old_price_sum, @old_amount_sum, @old_price_avg, @old_orders_cnt;
       SET @new_price_sum = @old_price_sum + NEW.price;
       SET @new_amount_sum = @old_amount_sum + NEW.amount;
       SET @new_orders_cnt = @old_orders_cnt + 1;
       SET @new_price_avg = @new_price_sum / @new_orders_cnt;
       REPLACE INTO Orders_MV
       VALUES(NEW.product_name, @new_price_sum, @new_amount_sum, @new_price_avg, @new_orders_cnt);
    END;
    

4.8 分區(qū)表

4.8.1 分區(qū)概述
  • 分區(qū)表將表或索引分解為多個(gè)更小、更易管理的部分。MySQL 5.1 版本開始支持分區(qū)。
  • 分區(qū)表可以提高查詢性能,特別是對于大數(shù)據(jù)量的表。
4.8.2 分區(qū)類型
  1. RANGE 分區(qū)

    • 根據(jù)列的值范圍進(jìn)行分區(qū)。

      CREATE TABLE t (
         id INT) ENGINE=INNDB
      PARTITION BY RANGE (id) (
             PARTITION p0 VALUES LESS THAN (10),
             PARTITION p1 VALUES LESS THAN (20));
      
  2. LIST 分區(qū)

    • 根據(jù)列的離散值進(jìn)行分區(qū)。

      CREATE TABLE t (
          a INT,
          b INT) ENGINE=INNODB
      PARTITION BY LIST(b) (
          PARTITION p0 VALUES IN (1,3,5,7,9),
          PARTITION p1 VALUES IN (0,2,4,6,8));
      
  3. HASH 分區(qū)

    • 根據(jù)列的哈希值進(jìn)行分區(qū)。

      CREATE TABLE t_hash (
          a INT,
          b INT) ENGINE=InnoDB
      PARTITION BY HASH (YEAR(b))
      PARTITIONS 4;
      
  4. KEY 分區(qū)

    • 使用MySQL提供的函數(shù)進(jìn)行分區(qū)。

      CREATE TABLE t_key (
          a INT,
          b DATETIME) ENGINE=InnoDB
      PARTITION BY KEY (b)
      PARTITIONS 4;
      
  5. COLUMNS 分區(qū)

    • 可以對多個(gè)列的值進(jìn)行分區(qū)。

      CREATE TABLE t_columns_range(
          a INT,
          b DATETIME
        ) ENGINE=INODB
       PARTITION BY RANGE COLUMNS (b) (
          PARTITION p0 VALUES LESS THAN ('2009-01-01'),
          PARTITION p1 VALUES LESS THAN ('2010-01-01'));
      
4.8.3 子分區(qū)
  • 子分區(qū)是在分區(qū)分的基礎(chǔ)上再進(jìn)行分區(qū)分。

    CREATE TABLE ts (a INT, b DATE) ENGINE=INODB
     PARTITION BY RANGE (YEAR(b))
      SUBPARTITION BY HASH(TO_DAYS(b))
      SUBPARTITIONS 2 (
          PARTITION p0 VALUES LESS THAN (1990),
          PARTITION p1 VALUES LESS THAN (2000),
          PARTITION p2 VALUES LESS THAN MAXVALUE
      );
    
4.8.4 分區(qū)中的NULL值
  • MySQL分區(qū)分區(qū)總是視NULL值小于任何非NULL值。

    CREATE TABLE t_range (
        a INT,
        b INT) ENGINE=innoDB
     PARTITION BY RANGE (b) (
         PARTITION p0 VALUES LESS THAN (10),
         PARTITION p1 VALUES LESS THAN (20),
         PARTITION p2 VALUES LESS THAN MAXVALUE
     );
    
4.8.5 分區(qū)和性能
  • 分區(qū)可以提高查詢性能,但需要根據(jù)具體情況進(jìn)行設(shè)計(jì)。

    CREATE TABLE Profile (
        id int(11) NOT NULL AUTO_INCREMENT,
        nickname varchar(20) NOT NULL DEFAULT '',
        password varchar(32) NOT NULL DEFAULT '',
        sex char(1) NOT NULL DEFAULT '',
        rdate date NOT NULL DEFAULT '0000-00-00',
        PRIMARY KEY ('id'),
        KEY 'nickname' ('nickname')
    ) ENGINE=InnoDB
     PARTITION BY HASH (id)
     PARTITIONS 10;
    
4.8.6 在表和分區(qū)間交換數(shù)據(jù)
  • 使用 ALTER TABLE ... EXCHANGE PARTITION 語句在表和分區(qū)間交換數(shù)據(jù)。

    CREATE TABLE e (
        id INT NOT NULL,
        fname VARCHAR(30),
        lname VARCHAR(30)
    ) PARTITION BY RANGE (id) (
        PARTITION p0 VALUES LESS THAN (50),
        PARTITION p1 VALUES LESS THAN (100),
        PARTITION p2 VALUES LESS THAN (150),
        PARTITION p3 VALUES LESS THAN (MAXVALUE)
    );
    INSERT INTO e VALUES
    (1669, "Jim", "Smith"),
    (337, "Mary", "Jones"),
    (16, "Frank", "White"),
    (2005, "Linda", "Black");
    CREATE TABLE e2 LIKE e;
    ALTER TABLE e2 REMOVE PARTITIONING;
    ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2;
    

第5章 索引與算法

5.1 InnoDB 存儲(chǔ)引擎索引概述

  • InnoDB 存儲(chǔ)引擎支持的索引類型:B+樹索引、全文索引、哈希索引

5.2 數(shù)據(jù)結(jié)構(gòu)與算法

5.2.1 二分查找法
  • 二分查找法(binary search)用于在有序數(shù)組中查找特定元素。
  • 通過不斷將查找區(qū)間縮小一半,最終找到目標(biāo)元素或確定其不存在。
5.2.2 二叉查找樹和平衡二叉樹
  1. 二叉查找樹(BST):每個(gè)節(jié)點(diǎn)的左子樹鍵值小于根節(jié)點(diǎn),右子樹鍵值大于根節(jié)點(diǎn)。
  2. 平衡二叉樹(AVL樹):任何節(jié)點(diǎn)的兩個(gè)子樹高度最大差為1。插入和刪除操作可能導(dǎo)致樹的不平衡,需要通過旋轉(zhuǎn)操作來維護(hù)平衡。

5.3 B+樹

5.3.1 B+樹的插入操作
  • B+樹的插入操作需要保持節(jié)點(diǎn)的有序性和樹的平衡。
  • 插入操作可能涉及頁的拆分和旋轉(zhuǎn)操作。
5.3.2 B+樹的刪除操作
  • B+樹的刪除操作需要維護(hù)樹的平衡和節(jié)點(diǎn)的有序性。
  • 刪除操作可能涉及頁的合并和索引頁的更新。
5.3.3 B+樹索引的分裂
  • B+樹的分裂操作發(fā)生在頁滿時(shí),需要將記錄分配到兩個(gè)新頁中。
  • 分裂點(diǎn)的選擇基于記錄的插入位置和頁的順序信息。
5.3.4 B+樹索引的管理
  • 索引的創(chuàng)建和刪除可以通過 ALTER TABLECREATE/DROP INDEX 實(shí)現(xiàn)。

5.4 B+樹索引

5.4.1 聚集索引
  • 聚集索引(clustered index)按照每張表的主鍵構(gòu)建 B+樹,葉子節(jié)點(diǎn)存放實(shí)際數(shù)據(jù)。
  • 聚集索引決定了數(shù)據(jù)在表中的物理存儲(chǔ)順序。
5.4.2 輔助索引
  • 輔助索引(secondary index)不包含實(shí)際數(shù)據(jù),葉子節(jié)點(diǎn)包含鍵值和指向?qū)嶋H數(shù)據(jù)的指針。
  • 輔助索引通過書簽到聚集索引,找到對應(yīng)的行數(shù)據(jù)。
5.4.3 輔助索引與聚集索引的關(guān)系
  • 輔助索引的存在不影響數(shù)據(jù)在聚集索引中的組織。
  • 每張表可以有多個(gè)輔助索引,通過葉級別的指針訪問聚集索引。
5.4.4 B+樹索引的管理
  • 索引的管理包括創(chuàng)建、刪除和修改。

5.5 Cardinality 值

5.5.1 什么是 Cardinality
  • Cardinality 值表示索引中不重復(fù)記錄的預(yù)估值。
  • 高選擇性(接近1)的索引通常更有效。
  • 示例:通過 SHOW INDEX 查看表 t 的索引 Cardinality 值。
5.5.2 InnoDB 存儲(chǔ)引擎的 Cardinality 統(tǒng)計(jì)
  • InnoDB 通過采樣方法統(tǒng)計(jì) Cardinality 值。
  • 示例:通過 SHOW INDEXORDER BY 觀察 Cardinality 值的變化。
5.5.3 Cardinality 值的應(yīng)用
  • Cardinality 值用于優(yōu)化查詢執(zhí)行計(jì)劃。

5.6 B+樹索引的使用

5.6.1 不同應(yīng)用中B+樹索引的使用
  • B+樹索引的使用需要根據(jù)具體應(yīng)用場景進(jìn)行判斷。
    1. OLTP(在線事務(wù)處理)應(yīng)用中,查詢操作通常只涉及少量數(shù)據(jù),適合使用索引。
    2. OLAP(在線分析處理)應(yīng)用中,查詢通常涉及大量數(shù)據(jù),索引的選擇和使用需要謹(jǐn)慎。
5.6.2 聯(lián)合索引
  • 聯(lián)合索引是對多個(gè)列進(jìn)行索引,適用于多列聯(lián)合查詢。
  • InnoDB引擎中,聯(lián)合索引使用哈希算法來提高查找效率。
5.6.3 覆蓋索引
  • 覆蓋索引(或稱索引覆蓋)是指索引包含了查詢所需的所有列,減少了對數(shù)據(jù)文件的訪問。
  • InnoDB引擎從1.2版本開始支持全文檢索,使用倒排索引實(shí)現(xiàn)。
5.6.4 優(yōu)化器選擇不使用索引的情況
  • 優(yōu)化器可能會(huì)選擇全表掃描而不是使用索引,特別是在范圍查詢和JOIN操作中。
5.6.5 索引提示
  • 索引提示(INDEX HINT)用于顯式指定優(yōu)化器使用特定索引。
  • 可以使用USE INDEX、FORCE INDEX、IGNORE INDEX等關(guān)鍵字來強(qiáng)制優(yōu)化器使用或忽略索引。
5.6.6 Multi-Range Read優(yōu)化
  • Multi-Range Read(MRR)優(yōu)化用于減少磁盤隨機(jī)訪問,提高順序訪問性能。
  • InnoDB和MyISAM存儲(chǔ)引擎支持MRR優(yōu)化。
5.6.7 Index Condition Pushdown(ICP)優(yōu)化
  • ICP優(yōu)化將WHERE條件的部分過濾操作放在存儲(chǔ)引擎中進(jìn)行,減少上層SQL層的負(fù)擔(dān)。

5.7 哈希算法

  • 哈希算法是一種常見的散列算法,時(shí)間復(fù)雜度為O(1)。
  • InnoDB存儲(chǔ)引擎使用哈希算法來處理字典查找。

5.8 全文檢索

5.8.1 概述
  • 全文檢索是通過索引字段的前綴進(jìn)行查找,適用于博客內(nèi)容等文本數(shù)據(jù)。
  • InnoDB存儲(chǔ)引擎從1.2版本開始支持全文檢索。
5.8.2 倒排索引
  • 倒排索引存儲(chǔ)單詞與文檔的映射關(guān)系,適用于全文檢索。
  • InnoDB全文索引使用full inverted index,包含單詞和文檔ID的對。
5.8.3 InnoDB全文檢索
  • InnoDB使用倒排索引和FTS Index Cache來提高全文檢索性能。
  • 文檔的插入和刪除操作分別記錄在FTS Document IDDELETED表中。
5.8.4 全文檢索的限制
  • 每張表只能有一個(gè)全文檢索索引。
  • 不支持沒有單詞界定符的語言。

第6章 鎖

6.1 什么是鎖

鎖是數(shù)據(jù)庫系統(tǒng)中用于管理對共享資源并發(fā)訪問的關(guān)鍵機(jī)制。鎖機(jī)制確保了數(shù)據(jù)的一致性和完整性,防止多個(gè)事務(wù)同時(shí)修改同一數(shù)據(jù)導(dǎo)致的數(shù)據(jù)不一致問題。

鎖可以分為不同類型,包括:

  1. 行鎖:鎖定數(shù)據(jù)庫中的一行數(shù)據(jù)。
  2. 表鎖:鎖定整個(gè)表。
  3. 意向鎖:表示事務(wù)希望在更細(xì)粒度上加鎖。

鎖的實(shí)現(xiàn)方式類似于Oracle數(shù)據(jù)庫,但I(xiàn)nnoDB提供了更細(xì)粒度的鎖控制,如行級鎖和表級鎖。

6.2 lock與latch

  1. lock:用于保護(hù)數(shù)據(jù)庫內(nèi)容,持續(xù)整個(gè)事務(wù)過程。鎖的類型包括行鎖、表鎖和意向鎖等。
  2. latch:用于保護(hù)內(nèi)存數(shù)據(jù)結(jié)構(gòu),持續(xù)時(shí)間短。latch的類型包括共享鎖、互斥鎖等。

InnoDB存儲(chǔ)引擎中,可以通過命令查看latch和lock的信息:

  • 查看latch:SHOW ENGINE INNODB MUTEX
  • 查看lock:SHOW ENGINE INNODB STATUS

6.3 InnoDB存儲(chǔ)引擎中的鎖

InnoDB存儲(chǔ)引擎實(shí)現(xiàn)了多種鎖機(jī)制,包括:

  • 共享鎖(S Lock):允許多個(gè)事務(wù)讀取一行數(shù)據(jù)。
  • 排他鎖(X Lock):允許事務(wù)刪除或更新一行數(shù)據(jù)。

InnoDB支持多粒度鎖(granular)鎖,允許在行級和表級上加鎖。此外,InnoDB還支持意向鎖(Intention Lock),用于在更細(xì)粒度上進(jìn)行加鎖。

6.4 鎖的算法

InnoDB存儲(chǔ)引擎有3種行鎖算法:

  1. Record Lock:單個(gè)行記錄上的鎖。
  2. Gap Lock:間隙鎖,鎖定一個(gè)范圍,但不包含記錄本身。
  3. Next-Key Lock:結(jié)合了Gap Lock和Record Lock,鎖定一個(gè)范圍,并鎖定記錄本身。

Next-Key Lock是InnoDB默認(rèn)的行鎖算法,旨在解決Phantom Problem(幻讀問題)。

Next-Key Lock通過鎖定記錄和記錄之間的間隙,防止其他事務(wù)插入新的記錄,從而避免了幻讀問題。

6.5 鎖問題

鎖機(jī)制雖然提高了并發(fā)性,但也帶來了一些問題:

  1. 臟讀(Dirty Read):一個(gè)事務(wù)讀取了另一個(gè)未提交事務(wù)的數(shù)據(jù)。
  2. 不可重復(fù)讀(Non-Repeatable Read):一個(gè)事務(wù)多次讀取同一數(shù)據(jù)集合,結(jié)果不一致。
  3. 丟失更新(Lost Update):一個(gè)事務(wù)的更新被另一個(gè)事務(wù)覆蓋。

InnoDB通過Next-Key Lock算法避免了不可重復(fù)讀的問題。臟讀和丟失更新問題可以通過事務(wù)隔離級別和鎖機(jī)制來解決。

6.6 阻塞

阻塞是指一個(gè)事務(wù)中的鎖需要等待另一個(gè)事務(wù)中的鎖釋放,阻塞是確保事務(wù)可以并發(fā)且正常運(yùn)行的必要機(jī)制。

InnoDB通過參數(shù)innodb_lock_wait_timeout控制等待時(shí)間,默認(rèn)為50秒。

6.7 死鎖

死鎖是指兩個(gè)或多個(gè)事務(wù)互相等待對方釋放鎖,導(dǎo)致事務(wù)無法繼續(xù)執(zhí)行。InnoDB通過 超時(shí)機(jī)制wait-for graph算法 檢測死鎖。

wait-for graph是一種主動(dòng)的死鎖檢測方式,通過構(gòu)建事務(wù)等待鏈表和鎖信息鏈表,檢測是否存在回路,從而判斷是否存在死鎖。

6.8 鎖升級

鎖升級是指將當(dāng)前鎖的粒度降低。例如,數(shù)據(jù)庫可以將行鎖升級為頁鎖或表鎖,以提高并發(fā)性能。鎖升級可以減少鎖的開銷,提高系統(tǒng)的整體性能。

第7章 事務(wù)

7.1 認(rèn)識(shí)事務(wù)

  • 事務(wù)(Transaction):數(shù)據(jù)庫區(qū)別于文件系統(tǒng)的重要特性之一。事務(wù)是一組操作的集合,這些操作要么全部成功,要么全部失敗。
  • ACID特性
    1. 原子性(Atomicity):事務(wù)是不可分割的工作單位,要么全部成功,要么全部失敗。
    2. 一致性(Consistency):事務(wù)將數(shù)據(jù)庫從一種一致狀態(tài)轉(zhuǎn)換為另一種一致狀態(tài)。
    3. 隔離性(Isolation):事務(wù)的隔離性要求每個(gè)事務(wù)的對象對其他事務(wù)不可見。
    4. 持久性(Durability):事務(wù)一旦提交,其結(jié)果就是永久性的。

7.2 事務(wù)的實(shí)現(xiàn)

  1. redo log:用于保證事務(wù)的原子性和持久性,記錄的是頁的物理操作。
  2. undo log:用于保證事務(wù)的一致性,記錄的是邏輯日志。
7.2.1 redo
  • 基本概念
    • redo log buffer:內(nèi)存中的重做日志緩沖區(qū)。
    • redo log file:持久化的重做日志文件。
    • log block:重做日志塊,由log block header和log block body組成。
  • redo log的寫入
    • 事務(wù)提交時(shí),必須將該事務(wù)的所有日志寫入到重做日志文件進(jìn)行持久化。
    • 為了保證每次日志都寫入重做日志文件,InnoDB存儲(chǔ)引擎需要調(diào)用一次fsync操作。
7.2.2 undo
  • 基本概念
    • undo log:記錄了事務(wù)的行為,可以進(jìn)行“重做”操作。
    • undo segment:undo log存放在數(shù)據(jù)庫內(nèi)部的一個(gè)特殊段中。
  • undo存儲(chǔ)管理
    • InnoDB存儲(chǔ)引擎對undo的管理采用段的方式。
    • 每個(gè)回滾段記錄了1024個(gè)undo log segment。
7.2.3 purge
  • 基本概念
    • purge:用于最終完成delete和update操作,清理之前的delete和update操作。
  • purge操作
    • 不能在事務(wù)提交時(shí)立即進(jìn)行處理,而是通過purge來進(jìn)行判斷和清理。

7.3 事務(wù)的分類

  1. 扁平事務(wù)(Flat Transactions)
  2. 帶保存點(diǎn)的扁平事務(wù)(Flat Transactions with Savepoints)
  3. 鏈?zhǔn)聞?wù)(Chained Transactions)
  4. 嵌套事務(wù)(Nested Transactions)
  5. 分布式事務(wù)(Distributed Transactions)

7.4 事務(wù)的實(shí)現(xiàn)

  • InnoDB存儲(chǔ)引擎
    • 支持扁平事務(wù)、帶保存點(diǎn)的扁平事務(wù)、鏈?zhǔn)聞?wù)、嵌套事務(wù)和分布式事務(wù)。
    • 通過redo log和undo log來實(shí)現(xiàn)事務(wù)的ACID特性。

具體實(shí)現(xiàn)細(xì)節(jié)

  1. redo log的寫入:事務(wù)提交時(shí),日志寫入重做日志文件,并調(diào)用fsync操作。

  2. undo log的寫入:事務(wù)進(jìn)行中,undo log記錄在undo segment中。

  3. purge操作:清理不再需要的undo log,釋放存儲(chǔ)空間。

  4. 創(chuàng)建表和存儲(chǔ)過程

CREATE TABLE test_load (
  a INT,
  b CHAR(80)
) ENGINE=INNODB;

DELIMITER //
CREATE PROCEDURE p_load(count INT UNSIGNED)
BEGIN
  DECLARE s INT UNSIGNED DEFAULT 1;
  DECLARE c CHAR(80) DEFAULT REPEAT('a', 80);
  WHILE s <= count DO
      INSERT INTO test_load SELECT NULL, c;
      COMMIT;
      SET s = s+1;
  END WHILE;
END //
DELIMITER ;
  1. 查看LSN(Log Sequence Number)
SHOW ENGINE INNODB STATUS\G;
  1. 查看undo信息
SELECT * FROM information_schema.INNODB_TRX_UNDO\G;
  1. 查看rollback segment信息
SELECT segment_id, space, page_no FROM INNODB_TRX_ROLLBACK_SEGMENT\G;

7.5 事務(wù)控制語句

  1. 自動(dòng)提交:在MySQL命令行的默認(rèn)設(shè)置下,事務(wù)都是自動(dòng)提交的,即執(zhí)行SQL語句后會(huì)馬上執(zhí)行COMMIT操作。
  2. 顯式開啟事務(wù):使用命令BEGIN、START TRANSACTION或設(shè)置SET AUTOCOMMIT=0來顯式開啟一個(gè)事務(wù)。
  3. 提交事務(wù):使用COMMIT命令來提交事務(wù),使得已對數(shù)據(jù)庫做的所有修改成為永久性的。
  4. 回滾事務(wù):使用ROLLBACK命令來回滾事務(wù),撤銷正在進(jìn)行的所有未提交的修改。
  5. 保存點(diǎn):使用SAVEPOINT identifier命令在事務(wù)中創(chuàng)建一個(gè)保存點(diǎn),可以通過ROLLBACK TO SAVEPOINT來回滾到某個(gè)保存點(diǎn)。
  6. 刪除保存點(diǎn):使用RELEASE SAVEPOINT identifier命令刪除一個(gè)事務(wù)的保存點(diǎn)。
  7. 設(shè)置事務(wù)隔離級別:使用SET TRANSACTION命令來設(shè)置事務(wù)的隔離級別。

7.6 隱式提交的SQL語句

  1. DDL語句:如ALTER DATABASE、CREATE TABLE等,執(zhí)行這些語句后,會(huì)有一個(gè)隱式的COMMIT操作。
  2. 修改MySQL架構(gòu)的操作:如CREATE USER、DROP USER等,也會(huì)隱式提交。
  3. 管理語句:如ANALYZE TABLE、CHECK TABLE等,同樣會(huì)隱式提交。

7.7 對于事務(wù)操作的統(tǒng)計(jì)

  • 事務(wù)統(tǒng)計(jì):InnoDB存儲(chǔ)引擎支持事務(wù),因此需要關(guān)注每秒事務(wù)處理的能力(TPS)。
  • 統(tǒng)計(jì)方法:計(jì)算TPS的方法是(com_commit+com_rollback)/time。
  • 參數(shù):handler_commithandler_rollback用于統(tǒng)計(jì)事務(wù)操作。

7.8 事務(wù)的隔離級別

  1. SQL標(biāo)準(zhǔn)隔離級別:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE。
  2. InnoDB默認(rèn)隔離級別:REPEATABLE READ,相當(dāng)于SQL標(biāo)準(zhǔn)的SERIALIZABLE。
  3. 設(shè)置隔離級別:可以使用命令SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL來設(shè)置當(dāng)前會(huì)話或全局的事務(wù)隔離級別。

7.9 分布式事務(wù)

  • XA事務(wù):InnoDB存儲(chǔ)引擎提供了對XA事務(wù)的支持,通過XA事務(wù)來支持分布式事務(wù)的實(shí)現(xiàn)。
  • 分布式事務(wù)模型:由一個(gè)或多個(gè)資源管理器、一個(gè)事務(wù)管理器以及一個(gè)應(yīng)用程序組成。
  • XA事務(wù)的SQL語法:XA {START|BEGIN} xid [JOIN|RESUME]等。

第8章 備份與恢復(fù)

8.1 備份分類與核心概念

  1. 備份類型
    • 按操作狀態(tài):熱備(在線備份,如 XtraBackup)、冷備(離線備份,復(fù)制物理文件)、溫備(半在線,加全局讀鎖)。
    • 按內(nèi)容形式:邏輯備份(SQL 語句 / 數(shù)據(jù),如 mysqldump)、物理備份(裸文件復(fù)制,如 ibbackup)。
    • 按范圍:完全備份、增量備份(XtraBackup 支持真正增量)、日志備份(二進(jìn)制日志)。
  2. 一致性備份
    • InnoDB 支持 MVCC,通過--single-transaction選項(xiàng)在事務(wù)中導(dǎo)出數(shù)據(jù),確保一致性。
    • 避免分事務(wù)操作(如扣費(fèi)與道具插入分離),防止備份不一致。

8.2 常用備份方法

  1. 冷備(物理備份)
    • 步驟:停止數(shù)據(jù)庫,復(fù)制.frm、共享表空間(ibdata1)、獨(dú)立表空間(.ibd)、重做日志(ib_logfile*)。
    • 優(yōu)缺點(diǎn):簡單快速,恢復(fù)無需重建索引;文件體積大,跨平臺(tái)需注意格式差異。
  2. 邏輯備份
    • mysqldump:支持--single-transaction(InnoDB 專用)、--master-data(復(fù)制場景)、--where(條件導(dǎo)出),導(dǎo)出內(nèi)容含建表和插入語句。
    • SELECT INTO OUTFILE:導(dǎo)出數(shù)據(jù)為文本,需注意字段分隔符和權(quán)限(FILE權(quán)限),恢復(fù)用LOAD DATA INFILE。
  3. 熱備與增量備份
    • XtraBackup:開源熱備工具,支持增量備份(基于 LSN 比較頁修改),步驟為全備→增量備→應(yīng)用日志→恢復(fù)文件。
    • ibbackup:官方熱備工具(收費(fèi)),原理類似 XtraBackup,復(fù)制表空間并記錄 LSN 區(qū)間。
  4. 快照備份
    • 利用 LVM、ZFS 等文件系統(tǒng)快照功能,對數(shù)據(jù)庫所在分區(qū)創(chuàng)建寫時(shí)復(fù)制(CoW)快照,快速備份且不影響業(yè)務(wù)。

8.3 日志備份與復(fù)制

  1. 二進(jìn)制日志(binlog)
    • 作用:記錄數(shù)據(jù)更改,用于 Point-in-Time 恢復(fù)和復(fù)制,需啟用log-bin、sync_binlog=1、innodb_support_xa保證一致性。
    • 恢復(fù)工具mysqlbinlog解析日志,結(jié)合--start-position/--stop-datetime指定恢復(fù)區(qū)間。
  2. 復(fù)制(Replication)
    • 原理:主庫寫 binlog→從庫 IO 線程復(fù)制到中繼日志→SQL 線程應(yīng)用日志,異步實(shí)時(shí)同步,存在主從延遲。
    • 監(jiān)控:通過SHOW SLAVE STATUS查看Seconds_Behind_Master,啟用從庫read-only防止誤操作。

8.4 最佳實(shí)踐

  • 備份策略:定期全備 + 增量備 + 日志備份,遠(yuǎn)程異地容災(zāi)(如跨機(jī)房備份)。
  • 工具選擇:OLTP 場景首選 XtraBackup(支持增量),邏輯遷移用 mysqldump,復(fù)制結(jié)合快照防止誤操作。

第9章 性能調(diào)優(yōu)

9.1 硬件與架構(gòu)優(yōu)化

  1. CPU 選擇
    • OLTP 特性:事務(wù)短、索引查詢?yōu)橹?,CPU 核心數(shù)影響并發(fā)處理,優(yōu)先 64 位 CPU 支持大內(nèi)存。
    • InnoDB 適配:1.2 + 版本支持多核,調(diào)整innodb_read/write_io_threads充分利用 CPU 多核性能。
  2. 內(nèi)存配置
    • 緩沖池(InnoDB Buffer Pool):直接影響性能,建議大小為活躍數(shù)據(jù)的 1.5-2 倍,通過SHOW GLOBAL STATUS計(jì)算命中率(應(yīng)≥99%)。
    • 參數(shù)參考innodb_buffer_pool_size設(shè)為物理內(nèi)存的 60%-80%,多實(shí)例innodb_buffer_pool_instances減少競爭。
  3. 存儲(chǔ)介質(zhì)
    • 機(jī)械硬盤:RAID10 兼顧速度與冗余,啟用 RAID 卡 Write Back 功能(需 BBU 電池備份)。
    • 固態(tài)硬盤(SSD):隨機(jī)訪問快,禁用innodb_flush_neighbors減少鄰接頁刷新,調(diào)大innodb_io_capacity(如 8000-10000)。

9.2 RAID 與文件系統(tǒng)

  1. RAID 類型對比

    RAID 類型 優(yōu)勢 適用場景
    RAID10 讀寫性能強(qiáng),高可用性 OLTP 核心庫
    RAID5 空間利用率高,中等性能 非核心庫或讀多寫少場景
    RAID0 純性能,無冗余 測試環(huán)境
  2. 文件系統(tǒng)選擇

    • Linux 推薦 EXT4/XFS(穩(wěn)定性優(yōu)先),Solaris 推薦 ZFS(自帶快照),Windows 用 NTFS。
    • 避免過度糾結(jié)文件系統(tǒng)性能差異,關(guān)注mount參數(shù)(如noatime減少元數(shù)據(jù)更新)。

9.3 基準(zhǔn)測試工具

  1. sysbench
    • 功能:測試 CPU、磁盤 IO、OLTP 性能,支持多線程模擬負(fù)載。
    • OLTP 測試:生成大表(如--oltp-table-size=80000000),關(guān)注 TPS(事務(wù) / 秒)和響應(yīng)時(shí)間百分位(如 95% latency)。
  2. mysql-tpcc
    • 標(biāo)準(zhǔn):遵循 TPC-C 規(guī)范,模擬復(fù)雜 OLTP 場景(訂單處理、庫存管理等)。
    • 指標(biāo):tpmC 值(事務(wù)處理能力),重點(diǎn)測試 New Order 事務(wù)占比(≥43%)。

9.4 關(guān)鍵參數(shù)與最佳實(shí)踐

  • 磁盤 IOinnodb_io_capacity=200(機(jī)械盤)→8000(SSD),innodb_flush_neighbors=0(SSD)/1(機(jī)械盤)。
  • 日志策略innodb_flush_log_at_trx_commit=1(強(qiáng)一致性),sync_binlog=1(配合 XA 保證日志與數(shù)據(jù)同步)。
  • 監(jiān)控重點(diǎn):緩沖池命中率、磁盤 IO 利用率(iostat 查看%util)、主從延遲(復(fù)制場景)。

第10章 InnoDB 源代碼編譯與調(diào)試

10.1 源代碼獲取與結(jié)構(gòu)

  1. 獲取方式
    • 從 MySQL 官網(wǎng)下載對應(yīng)版本源代碼(GA 版或開發(fā)版),解壓后storage/innobase為 InnoDB 源碼目錄。
    • MySQL 5.1 需注意innobase(舊版)和innodb_plugin(新版)文件夾,編譯時(shí)需重命名插件版為innobase
  2. 目錄結(jié)構(gòu)
    • 核心模塊btr(B + 樹)、buf(緩沖池)、dict(數(shù)據(jù)字典)、trx(事務(wù))、log(重做日志)。
    • 工具類ut(通用工具)、os(操作系統(tǒng)封裝)、sync(互斥量實(shí)現(xiàn))。

10.2 編譯與調(diào)試環(huán)境

  1. Windows 平臺(tái)(Visual Studio)
    • 工具:CMake 生成工程文件,配置WITH_INNOBASE_STORAGE_ENGINE啟用 InnoDB。
    • 步驟:運(yùn)行win/configure.jsbuild-vsx.bat生成解決方案,設(shè)置mysqld為啟動(dòng)項(xiàng)目,斷點(diǎn)調(diào)試 master thread 等核心邏輯。
  2. Linux 平臺(tái)(Eclipse)
    • 工具鏈:使用BUILD/compile-amd64-debug-max-no-ndb生成 Make 文件,導(dǎo)入 Eclipse 創(chuàng)建 C++ 項(xiàng)目。
    • 調(diào)試:配置調(diào)試參數(shù)(如--datadir),通過 GDB 或 Eclipse 內(nèi)置調(diào)試器設(shè)置斷點(diǎn),追蹤 InnoDB 內(nèi)部函數(shù)(如buf_flush_get_desired_flush_rate)。
  3. 跨平臺(tái)(cmake)
    • 命令cmake .. -GXcode(Mac OSX 生成 Xcode 工程),簡化編譯流程,支持多平臺(tái)快速構(gòu)建。

10.3 調(diào)試重點(diǎn)與擴(kuò)展

  • 核心流程:跟蹤master_thread刷新臟頁、purge_thread回收 Undo 頁、page_cleaner_thread獨(dú)立刷頁邏輯。
  • 擴(kuò)展開發(fā):基于example_storage_engine模板,修改 InnoDB 源碼(如優(yōu)化插入緩沖算法),需注意版本兼容性和測試。

10.4 注意事項(xiàng)

  • 版本匹配:確保編譯環(huán)境與目標(biāo) MySQL 版本一致,開發(fā)版需關(guān)注未穩(wěn)定特性。
  • 調(diào)試安全:在測試環(huán)境進(jìn)行源碼修改,備份原始代碼,通過單元測試驗(yàn)證功能正確性。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容