postgresql で使用されるストレージ アーキテクチャは、実際のデータのストレージ構造と編成形式に影響を与えます。データベースに格納されているデータは、もともとここにあります。

ストレージアーキテクチャ

ここに画像の説明を挿入

コラムの内容:
postgresql カーネル ソース コード分析
手書きデータベース toadb
同時プログラミング
個人ホームページ:私のホームページの
モットー : Tian Xingjian、紳士は自己改善に努めます。

概要

postgresql データベース サービスが実行されているとき、データはどのようにディスクに保存されますか? これにはストレージ アーキテクチャが関係します。
ファイル システムでは、ディレクトリとファイルの形式でストレージ ユニットが表示されます。これが物理ストレージ アーキテクチャです。
これらのディレクトリとファイルには、実際には特定の接続と編成形式があります。たとえば、最も外側のディレクトリはクラスタ データ ディレクトリです。それぞれデータベースには、論理ストレージ アーキテクチャであるディレクトリがあります。

論理ストレージ アーキテクチャは物理ディスク ファイルの組織形式を維持し、物理ストレージ アーキテクチャは特定のディスク ファイルを表現します。

論理ストレージのアーキテクチャ

名前空間

論理的には、データベースには組織管理名前空間の複数の層があります。

ここに画像の説明を挿入

クラスター -> テーブルスペース テーブルスペース -> データベース -> スキーマ。
スキーマはデータベース カーネル内のデータ ディクショナリによって区別されるため、最初の 3 つの項目はすべて、ストレージ アーキテクチャの構成を通じてスペースから物理的に独立しています。
前回のカーネル分析の記事でも触れましたが、テーブルファイルの場所もテーブルスペース/データベース/リレーションの3つのレベルで一意に識別されます。

クラスターの概念については、クラスターは initdb によって作成され、データが保管されるディレクトリーであり、データベースサービスの開始時に指定する必要があり、通常は PGDATA と呼ばれます。

データファイル

ユーザーデータファイル

テーブル、インデックス、および対応する vm ファイルと fsm ファイルがあり、それらはすべてネームスペースの階層ディレクトリに従って保存されます。

取引関連データ

クラスタレベルの空間で管理されており、クラスタディレクトリの下にパブリックディレクトリがあります。

その他の組織文書

テーブルスペースファイル、データディクショナリファイル、テンプレートライブラリ、実行ログなどのファイルはすべてクラスタレベルで管理され、クラスタディレクトリの下に独自のディレクトリがあります。

設定ファイル

  • データベース構成ファイル

postgresql.conf

  • クライアントアクセス制御プロファイル

pg_hba.conf と pg_ident.conf

補助文書

バージョンファイル、実行情報ファイルなどはすべてPGDATAのルートディレクトリにあります

物理ストレージアーキテクチャ

  1. 通常、PGDATA として参照されます (それを定義する環境変数の名前を使用します)。PGD​​ATA の一般的な場所は /var/lib/pgsql/data です。異なるデータベース インスタンスによって管理される複数のクラスターは、同じマシン上に共存できます。
  2. テーブルまたはインデックスが 1GB を超えると、1G サイズのセグメントに分割されます。
    最初のセグメントのファイル名はファイル ノードと同じで、後続のセグメントの名前は filenode.1、filenode.2 などになります。この配置により、ファイル サイズ制限のある一部のプラットフォームでの問題が回避されます (実際には、1 GB は単なるデフォルトのセグメント サイズです。セグメント サイズは、PostgreSQL のコンパイル時に構成オプション --with-segsize を使用して調整できます)。原則として、フリー スペース マップと可視性マップのブランチにも複数のセグメントが必要になる可能性がありますが、実際にはこれが発生することはほとんどありません。
  3. 各データベースには個別のディレクトリがあり、そこにライブラリのテーブル ファイルが保存されます。

クラスターファイル構造

まず新しいデータベース クラスターを初期化し、次にデータベースを初期化して起動します。

# 初始化postgres数据库集簇 
/opt/postgres/bin/initdb -D pgtest -W

# 启动数据库,监听端口指定为 8888 
/opt/postgres/bin/pg_ctl -D pgtest -l logfile -o "-p 8888" start

# 以命令行客户端,登陆数据库,指定端口和数据库
/opt/postgres/bin/psql -p 8888 -d postgres

以下は、initdb が完了し、新しいテーブルスペースが作成された後のクラスターディレクトリ構造です。
その後、いくつかのファイルタイプを確認するために、一時テーブル、ログに記録されないテーブル、およびインデックスが構築されます。
一部のテーブルのファイルリストは、ここでは省略されています。中間、ディレクトリ階層とキーファイルが保持されます。

-- 表空间 
create tablespace tblspc_test location '/mnt/sda1/data/pgdata/pgtblspc';

-- 普通表 
create table tbl_account(id integer, name varchar, address varchar, tel varchar);

-- 临时表 会话退出后就会删除 
create temporary table tmptbl_test(id int, c_id int);

-- unlogged 表,不会记录WAL,恢复时数据全部丢失 
create unlogged table unlogtbl_test(c_id int ,consumer varchar);
create index on unlogtbl_test (c_id);

上記のシーンを構築した後、データベース クラスターの下のファイルとディレクトリの階層を見てみましょう。

[senllang@hatch pgdata]$ tree pgtest
pgtest
├── base
│   ├── 1
│   │   ├── 112
│   │   ├── 113
│   │   ├── 1247
│   │   ├── 1247_fsm
│   │   ├── 1247_vm
│   │   ├── 1249
......
│   │   ├── 827
│   │   ├── 828
│   │   ├── pg_filenode.map
│   │   ├── pg_internal.init
│   │   └── PG_VERSION
│   ├── 4
│   │   ├── 112
│   │   ├── 113
│   │   ├── 1247
│   │   ├── 1247_fsm
│   │   ├── 1247_vm
......
│   │   ├── 6238
│   │   ├── 6239
│   │   ├── 826
│   │   ├── 827
│   │   ├── 828
│   │   ├── pg_filenode.map
│   │   └── PG_VERSION
│   └── 5
│       ├── 112
│       ├── 113
│       ├── 1247
│       ├── 1247_fsm
│       ├── 1247_vm
│       ├── 16403
│       ├── 16403_init
│       ├── 16406
│       ├── 16406_init
│       ├── 16407
│       ├── 16407_init
│       ├── 16408
│       ├── 16408_init
│       ├── t3_16409
│       └── t3_16412
......
│       ├── 827
│       ├── 828
│       ├── pg_filenode.map
│       ├── pg_internal.init
│       └── PG_VERSION
├── global
│   ├── 1213
│   ├── 1213_fsm
│   ├── 1213_vm
│   ├── 1214
│   ├── 1232
│   ├── 1233
│   ├── 1260
│   ├── 1260_fsm
│   ├── 1260_vm
......
│   ├── pg_control
│   ├── pg_filenode.map
│   └── pg_internal.init
├── pg_commit_ts
├── pg_dynshmem
├── pg_hba.conf
├── pg_ident.conf
├── pg_logical
│   ├── mappings
│   ├── replorigin_checkpoint
│   └── snapshots
├── pg_multixact
│   ├── members
│   │   └── 0000
│   └── offsets
│       └── 0000
├── pg_notify
├── pg_replslot
├── pg_serial
├── pg_snapshots
├── pg_stat
├── pg_stat_tmp
├── pg_subtrans
│   └── 0000
├── pg_tblspc
│   └── 16388 -> /mnt/sda1/data/pgdata/pgtblspc
├── pg_twophase
├── PG_VERSION
├── pg_wal
│   ├── 000000010000000000000001
│   └── archive_status
├── pg_xact
│   └── 0000
├── postgresql.auto.conf
├── postgresql.conf
├── postmaster.opts
└── postmaster.pid

詳しい紹介

ファイルディレクトリ 説明
PG_VERSION PostgreSQL のメジャー バージョン番号を含むファイル
ベース 各データベースのサブディレクトリを含むサブディレクトリ
current_logfiles ログコレクターによって現在書き込まれているログファイルを記録するファイル
グローバル pg_database などのクラスター全体のテーブルを含むサブディレクトリ
pg_commit_ts トランザクションコミットタイムスタンプデータを含むサブディレクトリ
pg_dynshmem 動的共有メモリ サブシステムによって使用されるファイルを含むサブディレクトリ
pg_logical 論理レプリケーションの状態データを含むサブディレクトリ
pg_multixact マルチトランザクション状態データを含むサブディレクトリ (共有行ロック用)
pg_notify LISTEN/NOTIFYステータスデータを含むサブディレクトリ
pg_replslot レプリケーション スロット データを含むサブディレクトリ
pg_serial コミットされたシリアル化可能なトランザクション情報を含むサブディレクトリ
pg_snapshots エクスポートされたスナップショットを含むサブディレクトリ
pg_stat 統計サブシステムの永続ファイルを含むサブディレクトリ
pg_stat_tmp 統計サブシステムの一時ファイルを含むサブディレクトリ
pg_subtrans サブトランザクション状態データを含むサブディレクトリ
pg_tblspc 表領域へのシンボリックリンクを含むサブディレクトリ
pg_twophase トランザクション状態ファイルを準備するためのサブディレクトリが含まれています
pg_wal WAL (先行書き込みログ) ファイルを含むサブディレクトリ
pg_xact トランザクションコミットステータスデータを含むサブディレクトリ
postgresql.auto.conf ALTER SYSTEM によって設定された構成パラメータを保存するために使用されるファイル
postmaster.opts サーバーが最後に起動されたときに使用されたコマンドライン引数を記録するファイル
ポストマスター.pid 現在のポストマスター プロセス ID (PID)、クラスター データ ディレクトリ パス、ポストマスター起動タイムスタンプ、ポート番号、Unix ドメイン ソケット ディレクトリ パス (Windows では空)、最初に使用可能な listen_address (IP アドレスまたは *、または空を意味します) を記録するロック ファイルTCP をリッスンしていない) および共有メモリ セグメント ID (サーバーを閉じるとファイルは存在しません)

テーブルスペース

表スペースに一時表、通常表、データベースを作成しました

-- 创建数据库,指定存储的表空间 
create database test tablespace tblspc_test ;

-- 在指定表空间创建临时表 
create temporary table tmptbl_test1(id int, c_id int) tablespace tblspc_test;

-- 在指定表空间创建普通表 
create table tbl_salary(id integer, level float, performance float) tablespace tblspc_test;

物理的構造

テーブルスペースディレクトリ内のファイルを表示します。ディレクトリ階層とファイルリストは次のとおりです。

[senllang@hatch pgdata]$ tree pgtblspc/
pgtblspc/
└── PG_16_202306141
    ├── 16389
    │   ├── 112
    │   ├── 113
    │   ├── 1247
    │   ├── 1247_fsm
    │   ├── 1247_vm
    │   ├── 1249
    │   ├── 1249_fsm
    │   ├── 1249_vm
    ......
    │   ├── 826
    │   ├── 827
    │   ├── 828
    │   ├── pg_filenode.map
    │   └── PG_VERSION
    └── 5
        ├── 16395
        └── t3_16413

表スペースのディレクトリーの下に、ディレクトリー PG_16_202306141 があることがわかります。その名前は PG で始まり、その後にデータベースのバージョンと作成日が続きます。
ユーザー定義の表スペースには、PGDATA/pg_tblspc ディレクトリー内にシンボリック・リンクがあり、物理表スペース・ディレクトリー (つまり、CREATE TABLESPACE コマンドで指定されたディレクトリー) を指します。
シンボリック リンクには、テーブルスペースの OID を使用して名前が付けられます。

原理の説明

物理テーブルスペース ディレクトリには、PG_16_202306141 など、PostgreSQL サーバーのバージョンに応じた名前のサブディレクトリがあります (このサブディレクトリを使用する理由は、データベースの後続のバージョンでは CREATE TABLESPACE を使用して、同じディレクトリの場所を指定できるためです)競合を引き起こします)。

このバージョン固有のサブディレクトリ内には、この表領域内の要素を含む各データベースのサブディレクトリがあり、データベースの OID にちなんで名付けられます。このディレクトリ内のテーブルとインデックスは、ファイル ノードの命名スキームに従います。

クラスタの初期化後、デフォルトのテーブルスペースは pg_default と pg_global の 2 つになりますが、テーブルスペースを指定しない場合、作成したデータベースやテーブル等は pg_default テーブルスペースに格納されます。
pg_default は pg_tblspc 経由でアクセスする必要はありませんが、PGDATA/base に対応します。同様に、pg_global テーブルスペースは pg_tblspc を通じてアクセスされませんが、PGDATA/global に対応します。

データベース

ここに画像の説明を挿入

クラスター内のデータベースごとに、PGDATA/base に対応するサブディレクトリがあり、サブディレクトリの名前は pg_database のデータベースの OID です。
このサブディレクトリはデータベース ファイルのデフォルトの場所であり、特にデータベースのシステム カタログはここに保存されます。

データファイル

pg_relation_filepath() 関数は、任意のリレーションのフル パス (PGDATA に対する相対パス) を表示します。
上記の非常に多くのルールを暗記する代わりに使用できます。

ただし、この関数はリレーションのマスター ブランチの最初のセグメントの名前を与えるだけであることに注意してください。リレーションに関連するすべてのファイルを検索するには、セグメント番号または _fsm、_vm、_init を追加する必要がある場合があります。

テーブルファイルとインデックスファイル

各テーブルとインデックスは別のファイルに保存されます。
通常のテーブルの場合、これらのファイルはテーブルまたはインデックスのファイルノード番号に基づいて名前が付けられます。これは pg_class.relfilenode にあります。

一時テーブル

一時テーブルの場合、ファイル名は tBBB_FFF の形式になります。BBB はファイルを作成したバックエンドのバックエンド ID、FFF はファイル ノード番号です。

フリースペースマップfsm

いずれの場合も、マスター ファイル (別名マスター ブランチ) の外側に、各テーブルとインデックスの空き領域マップがあり、テーブルで利用可能な空き領域に関する情報が保存されます。
空き領域マップは、ノード番号に接尾辞 _fsm が付いた名前のファイルに保存されます。

可視性マップ vm

このテーブルには可視性マップもあり、接尾辞 _vm が付いたノード番号を持つファイルに保存されます。これは、どのページに非デッド タプルが含まれているかを追跡するために使用されます。

ログに記録されていないテーブル

ログに記録されないテーブルとインデックス (つまり、ログが記録されていないテーブル) には 3 番目のブランチである初期化ブランチもあり、ノード番号とサフィックス _init が付いたブランチ ファイルに保存されます。

初期化ブランチは、適切なタイプの空のテーブルまたはインデックスです。
クラッシュによりログに記録されていないテーブルを空にリセットする必要がある場合、初期化ブランチは master ブランチとともにコピーされ、他のブランチは消去されます (必要に応じて自動的に再構築されます)。

トーストテーブル

テーブルの列に非常に大きな項目を格納する可能性がある場合、そのテーブルには TOAST テーブルが関連付けられ、
テーブルの行に保持できないフィールド値のオフライン ストレージに使用されます。

テーブルに TOAST テーブルがある場合、テーブルの pg_class.reltoastrelid はその TOAST テーブルにリンクします。

一時ファイル

一時ファイル (メモリに収まらないデータのソートなどの操作用) は、PGDATA/base/pgsql_tmp に作成されます。一時ファイルが pg_default 以外のテーブルスペースに指定されている場合は、そのテーブルスペースの pgsql_tmp にサブディレクトリに作成されます。一時ファイルの名前は、pgsql_tmpPPP.NNN の形式になります。ここで、PPP は、それが属するバックエンドの PID であり、NNN は、バックエンドのさまざまな一時ファイルを区別するために使用されます。

終わり

応援していただき誠にありがとうございます。閲覧中に貴重なコメントを残すことを忘れないでください。励みになると思われた場合は、「いいね!」とブックマークをしてください。さらに努力します。

著者のメールアドレス:[email protected]
間違いや漏れがあった場合は、ご指摘いただき、お互いに学び合ってください。

注:許可なく転載しないでください。

おすすめ

転載: blog.csdn.net/senllang/article/details/132129065