本篇介紹 MySQL 與 PostgreSQL 的 Checkpoint 差異。

Checkpoint:異動資料正確寫入硬碟,或至少在發生災難時可確保邏輯性復原。

一、現代一般資料庫的效能瓶頸天花板 - Disk I/O

現代資料庫的效能瓶頸一般會發生在 Disk I/O,而不是 CPU,即使 SSD 也一樣,除非採用高階 PCI-E Flash Storage。所以效能天花板自然落在資料寫入硬碟的速度。

二、PostgreSQL Checkpoint

PostgreSQL Checkpoing 的演算法非常簡單、高效,原則上圍繞在 checkpoint_segments, checkpoint_timeout, checkpoint_completion_target, commit_delay 四個變數的設定。

每隔 checkpoint_segments 資料量,或每隔 checkpoint_timeout 時間點就執行 Checkpoint。其中 checkpoint_timeout 會再根據 checkpoint_completion_target 調整。

因為演算法簡單,所以算出 Checkpoint 非常高效,可是也因為簡單,所以很可能會令 Checkpoint 陷入泥潭。

例如非常高壓寫入的情境下,不是來不及把髒資料寫入硬碟,就是會觸發集體一次寫入而阻塞其它操作。

更嚴重地,因為來不及處理寫入,所以很多人會把參數調整為更頻繁的 Checkpoint,即把大量 Checkpoint 拆成多個小 Checkpoint,以免阻塞。但帶來的影響是,原則可以把多個 Write 合併為一次 Write 的操作 (減少 Disk I/O),因頻繁 Checkpoint 而失效了。

三、MySQL Checkpoint

MySQL 對於 Checkpoint 做了很多複雜的算法,除了支援類似 checkpoint_segments, checkpoint_timeout 的功能外,相對 PostgreSQL checkpoint_completion_target 死板設定也加入了 Adaptive flushing 機制。

一、可依據髒資料的 age 動態調整;二、可依據 Disk IO Capacity 調整;三、可依據近幾次 Checkpoint 調整下次 Checkpoint。

因為 Adaptive flushing,MySQL 可以因應不同場景自動調整 Checkpoint,相較 PostgreSQL 較簡單且死板的設定,應可在部分高壓寫入場景中更得心應手。