内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 ch2

OSS-DBPostgreSQL勉強メモ

出典: 


メモリ管理

共有メモリ域

  • 共有メモリ域

    • サーバプロセス全体

共有バッファ(shared_buffers)

  • PostgreSQL起動時にLinuxのカーネルパラメータshmmaxと比較

docker exec -it -u postgres b612ca6e cat /proc/sys/kernel/shmmax
  • でかい
18446744073692774399
  • shared_buffers設定の確認
postgres=# SELECT name,setting,unit,context FROM pg_settings WHERE name='shared_buffers';
      name      | setting | unit |  context   
----------------+---------+------+------------
 shared_buffers | 16384   | 8kB  | postmaster
(1 row)

WALバッファ(wal_buffers)

postgres=# SELECT name,setting,unit,context FROM pg_settings WHERE name='wal_buffers';
    name     | setting | unit |  context   
-------------+---------+------+------------
 wal_buffers | 512     | 8kB  | postmaster
(1 row)
  • ディスクに書き込まれていないトランザクションログ(WAL: Write Ahead Logging)をキャッシュする領域

空き領域マップ(Free Space Map)

  • 公式
  • リレーション上の利用可能な領域を追跡する領域

    • ハッシュインデックス以外
/docker:b612ca6e:/var/lib/postgresql/data $ ls base/1/
112        2601_fsm  2663      3080      3607
113        2601_vm   2664      3081      3608
1247       2602      2665      3085      3609
1247_fsm   2602_fsm  2666      3118      3712
  • この_fsmサフィックス付きのファイルがそれ
  • pg_freespacemapモジュールでFSMの情報を確認できる

可視性マップ

  • バキュームの高速化用

    • 処理が必要な処理か否かを可視性マップで判断
  • インデックスオンリースキャン、カヴァリングインデックス
  • heap

    • テーブルのメインのデータ領域
  • 普通のインデックススキャンは、indexにアクセスしたあとheapにもアクセスする

    • indexとheapを行き来してheapにランダムアクセスするので遅い
  • PostgreSQLはindex only scanをサポートしている(9.2~)

    • indexに必要な情報が全部あればheapアクセスしない
  • 使用条件

    • インデックスから元のデータを得られること

      • B-tree, GiSTはOK
      • ほかのはだめ
    • クエリがインデックス中のカラムだけを参照していること
  • さらに、取得される各行がMVCCスナップショットから見えていること

    • 可視性情報はindexには保持されておらず、heapにのみ保持されている
    • ではheapをいちいち見ないといけないか、というとそんなことはない
    • heapを見に行く代わりに「可視性マップ」のビットを見る

      • ビットが立っていたらインデックスのデータをそのまま返す
      • ビットが立っていなければ、heapを見に行く
      • 可視性マップはheapよりも容量が4桁くらい小さいのでI/Oが少なくて済む
  • _vmってやつ
112        2601_fsm  2663      3080      3607
113        2601_vm   2664      3081      3608
1247       2602      2665      3085      3609
1247_fsm   2602_fsm  2666      3118      3712

プロセスメモリ

  • バックエンドプロセスで確保
  • = クライアントとの接続ごと
  • なので、contextはuser

    • 一般ユーザのSET文で設定変更できる

作業メモリ(work_mem)

postgres=# SELECT name,setting,unit,context FROM pg_settings WHERE name='work_mem';
   name   | setting | unit | context 
----------+---------+------+---------
 work_mem | 4096    | kB   | user
(1 row)
  • 1クエリにつきこれだけ、ではない
  • 1クエリの中で作業メモリを使うような処理が複数あれば、処理ごとに設定した領域が確保される

    • サブクエリとか
  • ソート、ハッシュテーブル操作で使用

    • 暗黙のソートが走るDISTINCT
    • merge join, hash joinとか
  • システム全体のメモリ圧迫に注意する

メンテナンス用作業メモリ(maintenanceworkmem)

postgres=# SELECT name,setting,unit,context FROM pg_settings WHERE name='maintenance_work_mem';
         name         | setting | unit | context 
----------------------+---------+------+---------
 maintenance_work_mem | 65536   | kB   | user
(1 row)
  • メンテナンス作業とは

    • VACUUM
    • CREATE INDEX
    • ALTER TABLE ADD FOREIGN KEY
  • 同時にたくさん実行する代物ではないのでwork_memより大きくても大丈夫
  • autovacuum使用時はこの値 × autovacuum_max_workersが確保されるので注意

    • autovacuum_work_memautovacuumワーカプロセスごとのメモリ量を上書きできる

      • デフォルト-1だとmaintenace_work_memが代わりに使用される
postgres=# SELECT name,setting,unit,context FROM pg_settings WHERE name='autovacuum_work_mem';
        name         | setting | unit | context 
---------------------+---------+------+---------
 autovacuum_work_mem | -1      | kB   | sighup
(1 row)

一時バッファ(temp_buffers)

postgres=# SELECT name,setting,unit,context FROM pg_settings WHERE name='temp_buffers';
     name     | setting | unit | context 
--------------+---------+------+---------
 temp_buffers | 1024    | 8kB  | user
(1 row)
  • 一時テーブルにアクセスするときに用いられるメモリ領域
  • そのセッションで一時テーブルを利用する前なら、一般ユーザのSET文で設定変更できる

    • ひとたび一時テーブルにアクセスすると以降は効果なし

ファイル

  • initdbで700で生成される

主なディレクトリ

base/

  • oidを示す数字のディレクトリが作成される
  • 格納されるファイル

    • テーブル
    • インデックス
    • TOAST
    • Free Space Map
    • Visibility Map

global/

  • データベース横断的なもの格納
  • pg_databaseシステムカタログとか

    • \lとだいたい同じなやつ

pg_wal/

  • WALを格納するディレクトリ

pg_xact/

  • トランザクションのコミット状態を管理するファイルが格納されている

pg_tblspc/

  • テーブルスペース

    • base/以外にもデータベースオブジェクトを格納できる
postgres=# CREATE TABLESPACE mytablespace LOCATION '/var/lib/postgresql/mytablespace';
CREATE TABLESPACE
  • 格納先ディレクトリへのsymlinkが格納される
/docker:b612ca6e:/var/lib/postgresql/data $ ls -lA pg_tblspc/
total 0
lrwxrwxrwx   1 postgres       postgres 32 2020-01-30 02:00 16387 -> /var/lib/postgresql/mytablespace

主なファイル

PG_VERSION

cat PG_VERSION
12
  • メジャーバージョン違いでデータベースクラスタに互換性がないのでそのチェック用

テーブルファイル

ls -lA base/1/
total 7801
-rw-------   1 postgres       postgres   8192 2020-01-30 00:02 112
-rw-------   1 postgres       postgres   8192 2020-01-30 00:02 113
-rw-------   1 postgres       postgres  81920 2020-01-30 00:02 1247
-rw-------   1 postgres       postgres  24576 2020-01-30 00:02 1247_fsm
-rw-------   1 postgres       postgres   8192 2020-01-30 00:02 1247_vm
...
  • 8kB単位のページにより構成

インデックスファイル

  • 8kB単位のページにより構成

TOASTファイル

  • 長大な行をテーブルに格納するとデータベースディレクトリ配下に生えるディレクトリ
  • 公式
  • TOAST: The Oversized-Attribute Storage Technique
  • 1ページ8kBというサイズ上限をオーバーした属性を格納するための技術
  • 2ビットをTOASTに使用するので30ビット = 1GBまで

    • textや長さ指定していないvarcharとかは1GB

Free Space Mapファイル

  • _fsm

Visibility Mapファイル

  • _vm

WALファイル

  • 16MB固定
/docker:b612ca6e:/var/lib/postgresql/data $ ls -lA pg_wal/
total 16388
-rw-------   1 postgres       postgres 16777216 2020-01-30 00:52 000000010000000000000001
drwx------   2 postgres       postgres     4096 2020-01-30 00:02 archive_status
  • max_wal_sizeで設定したサイズまで生成される
postgres=# SELECT name,setting,unit,context FROM pg_settings WHERE name='max_wal_size';
     name     | setting | unit | context 
--------------+---------+------+---------
 max_wal_size | 1024    | MB   | sighup
(1 row)
  • 64個まで

postmaster.pid

cat postmaster.pid
1
/var/lib/postgresql/data
1580310138
5432
/var/run/postgresql
*
  5432001    163840
ready   
  • 多重起動とか防止用
  • プロセスID
1
  • データベースクラスタディレクトリパス
/var/lib/postgresql/data
  • サーバ起動時刻(unix timestamp)
1580310138
  • ポート番号
5432
  • Unixドメインソケットディレクトリパス
/var/run/postgresql
  • listen_address

    • TCP接続をリッスンしていなければ空
*
  • 共有メモリセグメントID?
  5432001    163840