52.1. データベースファイルのレイアウト

本節ではファイルとディレクトリというレベルで格納書式について説明します。

データベースクラスタで必要となる全てのデータは、クラスタのデータディレクトリ内に格納され、通常PGDATAとして参照されます (そのディレクトリを定義するために使用できる環境変数名です)。 通常のPGDATAの位置は/var/lib/pgsql/dataです。 複数のクラスタは異なったサーバによって管理され、同一のマシン上に存在できます。

表52-1で示されているようにPGDATAディレクトリには数個のサブディレクトリと制御ファイルがあります。 これら必要な項目に加え、クラスタの設定ファイルであるpostgresql.confpg_hba.confおよびpg_ident.confが従来通りPGDATA内に格納されます (PostgreSQL 8.0 以降では他の場所にも保存できます)。

表 52-1. PGDATAの内容

項目記述
PG_VERSIONPostgreSQLの主バージョン番号を保有するファイル
baseデータベースごとのサブディレクトリを保有するサブディレクトリ
globalpg_databaseのようなクラスタで共有するテーブルを保有するサブディレクトリ
pg_clogトランザクションのコミット状態のデータを保有するサブディレクトリ
pg_multixactマルチトランザクション状態のデータを保有するサブディレクトリ(共有行ロックで使用されます)
pg_subtransサブトランザクションの状態のデータを保有するサブディレクトリ
pg_tblspcテーブル空間へのシンボリックリンクを保有するサブディレクトリ
pg_twophase準備されたトランザクション用の状態ファイルを保有するサブディレクトリ
pg_xlog WAL(ログ先行書き込み)ファイルを保有するサブディレクトリ
postmaster.opts最後にサーバを起動したコマンドラインのオプションを記録するファイル
postmaster.pid実行中のサーバのPIDおよび共有メモリのセグメントIDを記録するロックファイル(サーバが停止した後は存在しません)

クラスタ内の各データベースに対して、PGDATA/base内にサブディレクトリが存在し、サブディレクトリ名はpg_database内のデータベースOIDとなります。 このサブディレクトリはデータベースファイルのデフォルトの位置であり、特にシステムカタログがそこに格納されます。

各テーブルおよびインデックスは別個のファイルに格納され、ファイル名はテーブルまたはインデックスのファイルノード番号となり、pg_class.relfilenode内で検索できます。

注意

テーブルにおけるファイルノード番号とOIDは多くの場合一致しますが、常に一致するとは限らないことに注意してください。 TRUNCATEREINDEXCLUSTER等のいくつかの操作、およびALTER TABLEにおけるいくつかの形式は、OIDを保持したままファイルノード番号を変更できます。 ファイルノード番号とテーブルOIDが同一であると仮定しないでください。

テーブルまたはインデックスが1ギガバイトを超えると、ギガバイト単位のセグメントに分割されます。 最初のセグメントのファイル名はファイルノード番号と同一であり、それ以降は、filenode.1、filenode.2等の名称になります。 この配置法によってファイル容量に制限のあるプラットフォームにおける問題を回避します。 テーブルおよびインデックスの内容は、項52.3においてさらに考察されています。

エントリが大きくなりそうな列を持ったテーブルは、連携したTOASTテーブルを保有する可能性があります。 TOASTテーブルは、元のテーブルの行の中には大き過ぎて保持できないフィールド値を格納するために使用されます。 pg_class.reltoastrelidTOASTテーブルが存在する時、元のテーブルから参照します。

テーブル空間は状況をさらに複雑にします。 ユーザが定義したテーブル空間は、PGDATA/pg_tblspcディレクトリ内部へのシンボリックリンクを保有し、 (CREATE TABLESPACEコマンドで指定された)物理的テーブル空間ディレクトリを参照します。 シンボリックリンクの名称はテーブル空間のOIDとなります。 物理的テーブル空間ディレクトリ内部では、テーブル空間に要素を持つ各データベースに対してサブディレクトリが存在し、サブディレクトリ名はデータベースOIDとなります。 そのディレクトリ内のテーブルは、ファイルノードの命名の規定に従います。 pg_defaultテーブル空間は pg_tblspcからアクセスされるのではなく、PGDATA/baseと連携します。 同様に、pg_globalテーブル空間はpg_tblspcからアクセスされるのではなく、PGDATA/globalと連携します。