深入淺出分析 Mysql 的 InnoDB 工作原理,硬核干貨!
一 、上期回顧
上次小編講了一條sql的執行流程,總結如下:
- 解析器(Parser):檢查SQL語法,生成語法樹。
- 優化器(Optimizer):選擇最優執行計劃,確定索引路徑。
- 執行器(Executor):根據優化器計劃,調用存儲引擎執行操作。
- InnoDB存儲引擎
行級鎖:對特定記錄加鎖,避免并發沖突。
數據修改:實際更新記錄,記錄修改到redo log。
事務控制(ACID):事務提交或回滾,確保數據一致性和持久性。
- 返回結果:將執行結果返回給客戶端。
然后小編也說了,InnoDB存儲引擎里面不止做了這幾件事,所以這期小編來聊聊InnoDB存儲引擎做了哪些事情。
二 、innoDB
2.1 一條更新sql語句的執行流程圖
圖片
2.2 buffer pool(innoDB)
Buffer Pool的定義
Buffer Pool 是一塊內存區域,專門用于存儲數據庫的數據頁和索引頁,以便數據庫在查詢或更新數據時,能夠直接從內存讀取而不是從磁盤讀取,極大地提高了查詢性能。
Buffer Pool的作用
- 緩存數據頁:當用戶查詢數據時,InnoDB會首先查看Buffer Pool中是否已經緩存了所需的數據。如果緩存命中,數據直接從內存中讀取,速度快于從磁盤讀取。
- 減少磁盤I/O:由于磁盤I/O操作相對較慢,Buffer Pool能顯著減少數據庫對磁盤的讀取次數,從而提高性能。
- 并發控制:InnoDB會管理對Buffer Pool的訪問,確保在并發情況下對內存的訪問是高效的。
性能調優建議
- 調整大?。汉侠矸峙銪uffer Pool大小可以顯著提高性能。建議分配服務器可用內存的一大部分給Buffer Pool,以減少磁盤訪問。
- 監控和調整:使用命令SHOW ENGINE INNODB STATUS 或者查詢性能視圖來監控Buffer Pool的使用情況,如命中率、讀取次數等,并根據需要調整Buffer Pool的大小。
另外 buffer pool既然是將物理磁盤的數據緩存起來,那么它的數據結構,內存不夠時的淘汰策略等等,小編將新開一篇mysql innoDB的buffer pool單獨講解,有興趣的同學記的關注后續文章。
2.3 undo log(innoDB)
Undo Log的定義
Undo Log 是用于記錄數據在進行修改之前的狀態的日志。當一個事務執行時,任何對數據的修改都會在修改前記錄到Undo Log中。如果事務因為某些原因失敗或被顯式回滾,InnoDB會利用Undo Log將數據恢復到修改前的狀態。
Undo Log的作用
- 事務回滾
如果一個事務在執行過程中出現錯誤或者用戶顯式執行ROLLBACK,InnoDB會利用Undo Log中的記錄將數據恢復到事務開始前的狀態,確保事務的原子性。
- MVCC(多版本并發控制)
- Undo Log幫助實現多版本并發控制(MVCC, Multiversion Concurrency Control)。當一個事務在讀取數據時,可能有其他事務正在修改相同的數據。Undo Log允許未提交的事務看到修改前的數據,而其他事務可以繼續訪問原始版本的記錄,確保事務之間的隔離性。
- 崩潰恢復
- 如果數據庫因意外宕機或崩潰,未完成的事務會被回滾。數據庫在重新啟動時,可以通過分析Undo Log,將未提交的事務的修改回滾,從而確保數據一致性。
Undo Log與Redo Log的區別
- Undo Log:主要用于事務回滾和MVCC。記錄的是數據修改前的舊值,以便在需要時回滾。
- Redo Log:主要用于持久性(Durability)。記錄的是數據的修改操作,以便在系統崩潰后恢復事務的修改。
2.4 redo log(innoDB)
Redo Log的定義
Redo Log 是一種物理日志,記錄的是數據頁的修改操作,而不是具體的數據內容。當一個事務對數據庫中的數據進行修改時,InnoDB會先將這些修改操作記錄到Redo Log中,然后再將這些操作實際寫入到磁盤的數據文件中。
Redo Log的作用
- 數據恢復:
在發生系統崩潰、宕機或硬件故障時,Redo Log能夠用于重做未完成的事務,確保數據庫在恢復時仍然可以反映出所有已提交的事務修改。這是事務的持久性保證。
- 性能優化:
- Redo Log允許數據庫在不必每次修改都立即將數據寫入磁盤的情況下,先把修改記錄到日志中。這極大提高了性能,因為寫入日志通常比隨機寫入磁盤上的數據頁要快。
- 數據修改可以在適當的時候(比如內存不足時或達到一定的時間間隔時)通過后臺進程慢慢刷新到磁盤文件中,而不影響事務的提交速度。
- 支持事務提交:
- 當事務執行COMMIT時,InnoDB首先會將所有相關的修改操作寫入Redo Log,并確保這些日志已經安全地存儲在磁盤上,之后事務才會被認為是成功提交。即使在事務提交后數據庫發生崩潰,事務的修改也可以通過Redo Log來恢復。
Redo Log的工作原理
- 當事務開始修改數據時,InnoDB將修改操作記錄到Redo Log Buffer中。
- 當事務提交時,Redo Log Buffer中的日志會被同步到磁盤上的Redo Log文件(這個過程叫做 刷盤(fsync))。
- 在后臺,InnoDB會根據一定的時間間隔或Buffer Pool中的壓力,將修改的數據頁從內存刷新到磁盤文件中(這稱為 Checkpoint 機制)。
- 如果數據庫崩潰或重啟,InnoDB會讀取Redo Log文件中的日志,并將其中未完成的事務操作重新應用到數據庫中(重做(redo)),從而恢復數據。
Redo Log的性能調優
- 日志文件大小 (innodb_log_file_size):較大的日志文件可以減少Checkpoint的頻率,但會增加崩潰恢復的時間,因為日志文件越大,恢復時需要重做的日志條目也越多。
- Redo Log Buffer大小 (innodb_log_buffer_size):如果事務提交頻率高,可以適當增加Redo Log Buffer的大小,以減少刷盤的頻率。
- 寫入頻率:通過innodb_flush_log_at_trx_commit參數控制事務提交時寫日志到磁盤的策略:
0:事務提交時不強制寫日志到磁盤,日志在后臺刷新。這種配置性能高但風險較大。
1:每次事務提交時,Redo Log會立即刷入磁盤。這是默認的設置,確保了事務的強持久性。
2:事務提交時,日志寫入文件系統緩存中,而不是立即寫入磁盤,崩潰時可能丟失部分數據。
2.5 bin log(mysql)
Binlog的定義
Binlog是MySQL的二進制日志,記錄了所有更改數據庫數據的語句以及與其相關的事務。它與InnoDB存儲引擎的Redo Log不同,Redo Log是用于恢復崩潰后未完成的事務,而Binlog是記錄事務日志,用于備份、恢復和復制。
Binlog的作用
- 數據恢復:
Binlog可以用作增量備份工具。通過定期備份Binlog文件,MySQL管理員可以將數據庫恢復到某一時刻之前的狀態,然后通過應用Binlog中的修改來恢復到崩潰前的最新狀態。與完整備份配合,能夠實現更精細的恢復過程。
如果數據庫因某種原因崩潰,可以通過Point-in-Time Recovery(PITR,時間點恢復),將數據庫恢復到特定的時間點,或恢復到某個已知的穩定狀態。
- 主從復制:
MySQL支持主從復制(Replication),其中主服務器上的數據更改會通過Binlog同步到從服務器。主服務器會將所有更改記錄到Binlog中,然后從服務器讀取并應用這些日志,從而保持與主服務器的數據一致性。
這種機制使得可以創建冗余的從服務器來提高高可用性和讀性能,分擔查詢負載。
三 、總結
InnoDB的Buffer Pool是MySQL用于緩存數據和索引頁的內存區域,減少磁盤I/O,提升讀寫性能。Undo Log記錄事務修改前的數據,用于回滾未提交的事務和實現MVCC。Redo Log則記錄已提交事務的修改操作,確保系統崩潰后能夠恢復事務,保證數據的持久性。Buffer Pool優化了內存使用,Undo Log維護事務一致性,Redo Log確保持久性與數據恢復,三者協同保障InnoDB的高效性與可靠性。