書不是拿來相信的,而是拿來探究的。
— 安伯托·艾可(Umberto Eco),《玫瑰的名字》
這本書寫給誰#
本書寫給那些不願意把資料庫當成黑盒子的人。如果你樂於追根究柢、不習慣把專家建議照單全收、想親自把每件事弄清楚,那麼這本書適合你。
作者假設讀者具備以下條件:
- 已經實際用過 PostgreSQL,對它的運作方式有大致概念
- 不需要教學如何安裝伺服器、輸入 psql 指令或設定組態參數
入門使用者可能會覺得內容偏難。另一方面,若你熟悉其他資料庫系統、正要轉換到 PostgreSQL 並想理解兩者差異,本書同樣適用。作者自陳:幾年前若有這樣一本書,能替他省下大量時間——這正是他最終寫下它的原因。
這本書不提供什麼#
- 不是食譜集:不會給你每種場合的現成解法。但只要理解複雜系統的內部機制,你就能分析、批判性地評估他人經驗,並得出自己的結論。正因如此,作者會解釋一些乍看毫無實用價值的細節。
- 不是教學手冊:對作者本人較感興趣的領域挖得很深,其他領域則可能隻字未提。
- 不是參考文件:作者力求精確,但無意取代官方文件,可能略去他認為不重要的細節。任何不清楚的情況,請查閱文件。
- 不教你開發 PostgreSQL 核心:不預設讀者懂 C 語言,主要對象是資料庫管理者(DBA)與應用程式開發者。但書中提供大量原始碼指引,讓你想挖多深都可以。
這本書提供什麼#
導論章節簡要帶過後續敘事所依賴的主要資料庫概念。作者不期待讀者從中獲得太多新資訊,收錄它是為了讓整體圖像完整,同時也方便從其他資料庫系統遷移過來的讀者。
| 篇章 | 主題 | 涵蓋內容 |
|---|---|---|
| Part I | 隔離與 MVCC | 先從使用者視角談有哪些隔離層級及其影響,再深入內部;涵蓋多版本並行控制(multiversion concurrency control, MVCC)與快照隔離(snapshot isolation)的實作細節,特別著重過期列版本的清理 |
| Part II | 緩衝快取與 WAL | 緩衝快取,以及故障後用來還原資料一致性的預寫式日誌(write-ahead log, WAL) |
| Part III | 鎖 | 各類鎖的結構與用法:WAL 用的輕量鎖、關聯層級的重量鎖、列層級鎖 |
| Part IV | 查詢執行 | 伺服器如何規劃並執行 SQL 查詢;可用的資料存取方法、連接方法,以及統計資訊如何被運用 |
| Part V | 索引類型 | 從已涵蓋的 B-tree 延伸到其他存取方法;說明界定索引系統核心、索引存取方法與資料型別之間邊界的可擴充性原則(並由此帶出運算子類別的概念),再逐一深入各方法 |
PostgreSQL 內建多個「內省」(introspective)擴充模組,日常工作用不到,卻能讓我們窺看伺服器的內部行為。本書大量使用這類擴充——它們除了幫助探索內部機制,在複雜使用情境的問題排查上也很有幫助。
閱讀慣例#
本書力求可以從頭到尾逐頁閱讀,但不可能一次揭露所有真相,因此同一主題會多次回訪。為避免反覆寫「後面會再談」而拉長篇幅,作者改用頁邊頁碼標註交叉引用:向前的頁碼指向後續討論,向後的頁碼指向先前已提及之處。
- 版本標註:本文與所有程式碼範例皆適用於 PostgreSQL 14。某些段落旁的頁邊會標示版本號,表示該資訊從指定版本起才成立——更早的版本要不是沒有該功能,就是採用不同實作。這對尚未升級到最新版本的讀者很有用。
- 參數預設值:頁邊也用來標示所討論參數的預設值。一般參數與儲存參數的名稱以斜體印出,例如
work_mem。 - 側註:可能讓討論岔題、但作者忍不住收錄的內容,會以特殊格式印出,方便略過。
程式碼與範例的呈現方式
程式碼以 => 作為提示符號,必要時附上伺服器回應:
=> SELECT now();
now
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
2023−03−06 14:00:08.008545+03
(1 row)只要在 PostgreSQL 14 上仔細重現書中所有指令,你應該會得到完全相同的結果(連交易 ID 之類的無關細節都一樣)。書中所有程式碼範例都是由包含這些指令的腳本產生的。
需要說明多個交易並行執行時,另一個 session 中執行的程式碼會縮排並以垂直線標示:
=> SHOW server_version;
server_version
−−−−−−−−−−−−−−−−
14.7
(1 row)要試跑這類指令(對自學或任何實驗都很有幫助),開兩個 psql 終端機會很方便。
指令名稱與各種資料庫物件(表格、欄位、函式、擴充等)在文中以無襯線字體標示,例如 pg_class。若某工具是從作業系統呼叫,會以 $ 結尾的提示符號顯示:
postgres$ whoami
postgres作者使用 Linux,但不涉及技術細節,具備基本認識即可。
資訊來源與致謝
資訊來源#
註腳中提供多個資訊來源連結,其中最重要的是:
- PostgreSQL 官方文件(postgresql.org/docs/14/index.html)——知識的泉源。它是專案不可或缺的一部分,由 PostgreSQL 開發者親自維護,永遠保持在最新狀態。
- 原始碼(git.postgresql.org)——毫無疑問是最主要的參考依據。令人驚訝的是,即使不懂 C,光是閱讀註解、瀏覽 README 檔案就能找到許多答案。
- Commitfest 條目(commitfest.postgresql.org)——可追溯所有變更的歷史;若願意翻遍 psql-hackers 郵件列表中成堆的信件,就能理解開發者決策背後的邏輯。
致謝#
一本書不可能獨力完成。作者感謝 Pavel Luzanov 在對的時機提議著手這件真正值得的事;感謝 Postgres Professional 讓他得以在業餘時間之外投入寫作,並特別感謝 Oleg Bartunov 分享想法與無盡的能量、Ivan Panchenko 的全力支持與 LaTeX 協助;感謝教育團隊同事的創作氛圍與討論,那些討論形塑了訓練課程的範圍與形式;感謝 Pavel Tolmachev 對草稿的細緻審閱。
本書許多章節最初發表於 Habr 部落格,讀者的意見與回饋顯示了這項工作的重要性、點出作者知識中的缺口,並幫助他改進文本。作者也感謝 Liudmila Mantrova 為本書語言所下的功夫,以及她將本書翻譯為英文。
書中提及的每一個函式或功能,都需要特定的人投入多年心血。作者欽佩 PostgreSQL 的開發者們,也很高興能有幸稱其中許多人為同事。