# PostgreSQL PostgreSQL は B-Tree をページサイズ 8 KiB(既定でディスクページ 4 KiB を使う伝統的実装より大きい)で実装するリレーショナル DBMS である。セカンダリインデックスの値としてレコードへの直接参照を持つ *heap file* アプローチを採用し、レコードは特定の順序を持たない領域に格納される。削除によって生じた未使用ページを整理するバックグラウンドプロセス(vacuum)を持ち、これによりディスク上のフラグメンテーションに対処する。(Source: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 4 Storage and Retrieval]] "B-Trees", "Storing Values Within the Index", "Disk space usage") 多次元索引としては、PostgreSQL の Generalized Search Tree(GiST)索引機能を用いて地理空間索引を R-Tree として実装する PostGIS がある。全文検索・JSON ドキュメント内索引には GIN(Generalized Inverted Index)索引型を用い、postings list ベースの転置インデックスを提供する。(Source: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 4 Storage and Retrieval]] "Multidimensional and Full-Text Indexes", "Full-Text Search") ## レプリケーション PostgreSQLは単一リーダー(primary-backup)レプリケーションを組み込みで提供する。実装方式は write-ahead log shipping であり、WALをそのままフォロワーへ転送してリーダーと同一のファイルを再構築する。この方式はストレージエンジンに密結合するため、リーダーとフォロワーが異なるバージョンのDB software を実行できず、ゼロダウンタイムのソフトウェアアップグレードが難しいという欠点を持つ。新規フォロワーをセットアップする際、スナップショットと結びつける正確なリーダーのレプリケーションログ上の位置を PostgreSQL は *log sequence number* と呼ぶ(MySQLの binlog coordinates / GTID に相当)。また PostgreSQL は物理WALをデコードして行単位の挿入・更新・削除イベントに変換することで論理レプリケーション(logical replication)も実装しており、CDC(change data capture)の基盤にもなる。WAL-Gはこの WAL アーカイブとスナップショットをオブジェクトストアへ退避するツールとしてPostgreSQL・MySQL・SQL Serverをサポートする。(Source: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 6 Replication]] "Single-Leader Replication", "Setting Up New Followers", "Write-ahead log shipping", "Logical (row-based) log replication") ## トランザクション分離レベルの実装(第8章) - **read committed が既定の分離レベル**。ダーティリード・ダーティライトを、コミット済み値と未コミット値の 2 バージョン保持で防ぐ - **repeatable read = スナップショット分離**: PostgreSQL は SQL 標準の「repeatable read」という名前でスナップショット分離を提供する(MySQL/InnoDB の repeatable read はより弱い保証で、命名が食い違う一因になっている) - **MVCC 実装**: 各行に `inserted_by` / `deleted_by`(トランザクション ID、32bit で約 40 億トランザクションごとにオーバーフローし vacuum が対処)を持たせ、更新は内部的に削除+挿入として扱う。可視性ルールでトランザクション開始時点の一貫したスナップショットを構成する - **serializable レベル = SSI**: 直列化可能スナップショット分離(SSI)を採用し、スナップショット分離とほぼ変わらない性能で完全な直列化可能性を提供する。不要な中断を減らす最適化(読み取りが上書きされたデータでも直列化可能と証明できる場合に許可する)を持つ - **更新のロストの自動検出**: repeatable read レベルで更新のロストを自動検出し中断させる(MySQL/InnoDB の repeatable read はこれを行わない) (Source: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 8 Transactions]] "Implementing read-committed", "Multiversion concurrency control", "Snapshot isolation, repeatable read, and naming confusion", "Automatically detecting lost updates", "Serializable Snapshot Isolation", "Performance of serializable snapshot isolation") ## 1章での位置づけ(詳説 データベース) *詳説 データベース* 第1章は、PostgreSQLをMySQLと並ぶ行指向DBMSの代表例として挙げ、行全体をまとめて格納することで空間的局所性を改善するアプローチの説明に用いる。またプライマリキーという用語がリレーショナルデータベース(MySQL・PostgreSQL)・DynamoベースのNoSQLストア(Cassandra・Riak)・ドキュメントストア(MongoDB)を横断して共通に使われる例としても言及される。(Source: [[@2021__OReillyJapan__詳説 データベース - Chapter 1 基本事項の紹介と概要]] §1.3, §1.4.2) ## ページフォーマット(詳説 データベース 第3章) *詳説 データベース* 第3章は、可変長レコードを格納するための**スロット化ページ**技術を利用する多くのデータベースの1つとしてPostgreSQLを挙げる。ページをスロット(セル)のコレクションとして編成し、ページの両側にある2つの独立した領域にポインタとセルをそれぞれ配置する設計であり、削除領域の回収や動的なレイアウトを可能にする。(Source: [[@2021__OReillyJapan__詳説 データベース - Chapter 3 ファイルフォーマット]] §3.5) ## Bツリーの実装(詳説 データベース 第4章) *詳説 データベース* 第4章は、PostgreSQLをページヘッダとノードハイキーの実装例として挙げる。ページヘッダにはページのサイズとレイアウトのバージョンが格納される。右端のポインタをノードハイキーとともにセルに格納する方式(Blinkツリー)を採用しており、各ノードにキーKN+1を追加してポインタPNが指すサブツリーのキー上限を明示することで、ポインタをペアごとに格納でき右端ポインタの処理が単純化される。また、プライマリインデックスキーが単調増加する場合、挿入されるキーが右端ページ内の最初のキーより確実に大きく、右端ページに十分な領域があるときには通常の探索・バランシングをスキップして挿入する「ファストパス」という最適化を持つ。(Source: [[@2021__OReillyJapan__詳説 データベース - Chapter 4 Bツリーの実装]] §4.1, §4.1.4, §4.5) ## バッファ管理とリカバリ(詳説 データベース 第5章) *詳説 データベース* 第5章は、ダーティページのフラッシュを独立したバックグラウンドプロセスで行う例としてPostgreSQLのバックグラウンドフラッシュライターを挙げ、退避のたびにフラッシュを起動するとパフォーマンスに悪影響が出るためこの方式が採られると説明する。また大規模シーケンシャルスキャンでは循環バッファ(FIFOページ置換ポリシー)を使う。コラム「PostgreSQLとfsync()」では、チェックポイントプロセスがダーティページのフラッシュに`fsync()`を用いるが、LinuxをはじめとするいくつかのOSではI/Oエラーでフラッシュに失敗してもダーティフラグの設定を解除してしまい、エラーがそのとき開いていたファイルディスクリプタにのみ報告されるため、チェックポイント処理がすべてのファイルを常時開いているとは限らずエラー通知を受け取り損ねることがある、という実際の耐久性バグ(CORBET18)が説明される。(Source: [[@2021__OReillyJapan__詳説 データベース - Chapter 5 トランザクション処理とリカバリ]] §5.1.2, §5.1.3, §5.2コラム) ## 分散トランザクション文脈での言及(詳説 データベース 第13章) *詳説 データベース* 第13章は、PostgreSQL を MySQL・MongoDB と並べて「ツーフェーズコミット(2PC)を使用する多くのデータベース」の一例として挙げる(コーディネータの障害時に代替ノードが投票を再収集する必要がある、という 2PC の一般的な弱点の文脈で言及される)。MongoDB については v3.6 時点で 2PC がトランザクションライクな意味合いを提供するに留まる旨の注記がある。(Source: [[@2021__OReillyJapan__詳説 データベース - Chapter 13 分散トランザクション]] §13.2.2) ## 関連 - ソース: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 4 Storage and Retrieval]] / [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 6 Replication]] / [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 8 Transactions]] / [[@2021__OReillyJapan__詳説 データベース - Chapter 3 ファイルフォーマット]] / [[@2021__OReillyJapan__詳説 データベース - Chapter 1 基本事項の紹介と概要]] / [[@2021__OReillyJapan__詳説 データベース - Chapter 4 Bツリーの実装]] / [[@2021__OReillyJapan__詳説 データベース - Chapter 5 トランザクション処理とリカバリ]] / [[@2021__OReillyJapan__詳説 データベース - Chapter 13 分散トランザクション]] - 概念: [[B-Tree]] / [[多次元索引]] / [[転置インデックス]] / [[単一リーダーレプリケーション]] / [[スナップショット分離とMVCC]] / [[ACIDと分離レベル]] / [[直列化可能性]] / [[スロット化ページ]] / [[Write-Ahead Logging (WAL)]] / [[ライトバックキャッシングと同期書き込み]] / [[分散トランザクション]] ## 出典 - [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 4 Storage and Retrieval]](B-Tree ページサイズ、heap file、vacuum、PostGIS の GiST、GIN 索引) - [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 6 Replication]](WAL shippingによる単一リーダーレプリケーション、log sequence number、論理レプリケーション) - [[@2021__OReillyJapan__詳説 データベース - Chapter 3 ファイルフォーマット]](§3.5 スロット化ページの実装例) - [[@2021__OReillyJapan__詳説 データベース - Chapter 1 基本事項の紹介と概要]](§1.3 行指向DBMSの代表例、§1.4.2 プライマリキー用語の共通性) - [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 8 Transactions]](read committed 既定・MVCC 実装・repeatable read = スナップショット分離・serializable = SSI) - [[@2021__OReillyJapan__詳説 データベース - Chapter 4 Bツリーの実装]](§4.1 ページヘッダ、§4.1.4 ノードハイキー/Blinkツリー、§4.5 右側限定の追加のファストパス) - [[@2021__OReillyJapan__詳説 データベース - Chapter 5 トランザクション処理とリカバリ]](§5.1 バックグラウンドフラッシュライター・循環バッファ、§5.2コラム fsync()エラー握りつぶし問題) - [[@2021__OReillyJapan__詳説 データベース - Chapter 13 分散トランザクション]](§13.2.2 2PC 採用データベースの一例としての言及)