tail -f /dev/null

If you haven't had any obstacles lately, you're not challenging. be the worst.

PostgreSQL: process, memory周り整理

Env

  • PostgreSQL 9.6

client, server間の接続〜問い合わせ処理

  • PostgreSQLへuser/passでのrequestを受信し、pg_hba.confで接続可否を判断
  • (認証処理)
  • 認証成功
  • backend process生成
  • clientがserverとの接続を確立

client側で発行したqueryがpostgres processへ渡る際に以下の手続きが発生する。

process architecture

  • client request -> postgres process生成, fork -> processがSQL文を解析, 処理
  • その他, background processがshared_buffer(PostgreSQL全体で利用する共有memory cache), WAL bufferの変更をHDDに書き込んだり, vacuum処理を行っている。

master server process (parent process)

  • clientからの接続を受け, 対応するprocessをforkして起動する。

(background) writer process

  • shared_bufferの更新pageをHDDのdata fileのblockに同期的に書き出す。

WAL (Write Ahead Logging) writer process

  • WAL bufferの確認を行い, 未書き込みのWALをHDDに同期的に書き出す。

Checkpointer process

  • checkpointを行い, shared_bufferの変更をHDDに同期的に書き込む。
    • checkpointとは, 全てのdirty pageをdata fileへ書き出し, checkpoint recordがlog fileに出力された状態。
    • checkpoint処理は全dirty pageをdiskに書き込む為、I/O負荷が高い傾向にある。
      • checkpoint処理が頻発すると性能劣化にも繋がるが、recovery速度もその分早くなる。適切な設定をされたい。
    • PostgreSQLではshared bufferをdisk cacheとして使用している為データ更新はshared buffer上で行われ直ぐにHDDに書き込まれるわけではない。
    • HDDへ未だ書き込んでないpageのことをdirty pageと呼ぶ。
  • PostgreSQL clash時にrecovery処理の起点を示すポイント。

Autovacuum launcher & Autovacuum worker process

  • autovacuumの制御, 実行process。
  • autovacuum用worker process起動をpostgresへ依頼する。
  • workerはtableに対し自動的にvacuumとanalyzeを実行する。
    • vacuumは更新や削除で発生したdata file, index内の不要領域を再利用可能にする。
  • 実行前に対象tableに大量にupdateがあったかを統計情報を参照して検査 (analyze) する。
    • pg_statistic system catalogを更新する。

統計情報 collector process

  • DBの稼働統計情報(pg_stat_activity[database, all_tables])の収集を一定間隔で行う。
  • 収集された情報はautovacuum worker等で利用される。

backend process

  • clientからのrequestを受け付けた際に生成される。
  • query, 結果の送受信を本processとclientでやり取りする。
  • queryは本processで実行される。

parallel worker process

  • parallel queryの実行時にbackend processから生成される.

後は, log writerとかarchiver等.


Memory architecture

  • PostgreSQLでは, PostgreSQL server process全体で共有するshared_memoryとbackend processが確保するprocess memoryに大別される.
  • PostgreSQL起動時, postgres process毎に work_mem , temp_buffers , maintenence_work_mem の領域を確保する.
  • shared memoryは shared_buffers , WAL buffer , C(ommit)LOG,free space map,visibility map,system catalog(postgres processにもコピーを保持)` の領域を確保する.
  • postgres process memory <-> shared memory <-> database cluster

shared_memory

shared_memoryはbackground processとbackend process全てから参照, 更新される領域.サーバ起動時にOSのsystem callから予約済となる.

PostgreSQL起動時にshared_bufferとLinuxのkernel parameterであるshmmaxを比較しshared_bufferが大きい場合エラーとなる.

shared_memoryは以下の領域に分割されている.

  • shared buffers
    • tableやindexデータを読み込みcacheし, CRUD操作を行う領域.
  • WAL(Write Ahead Logging) buffer
    • diskに未書き込みのtransaction log: WAL log(transaction log)のcache(buffering用)領域.
  • C(ommit)Log
    • transactionの状態を保存.
  • Free Space Map (FSM)
    • table上の空き領域(block毎の空き領域)情報.
    • VACUUM処理の度transactionから非参照の行を探し空き領域としてdatabase clusterに保存され, 再起動時に読み込まれる.追加, 更新時に空き領域mapを確認, 再利用可能な領域に新しい行を挿入する.
      • Visibility Map (VM)
    • VACUUM処理高速化(処理が必要なpageか本mapで判断)やindex only scan(高速な検索方式)で利用される.
    • tableのblock毎に全transactionから可視かどうかを保持している(1page/1bit).
    • Visibility map書き換えタイミングは各種更新処理, VACUUM処理時.

process memory

  • backend process毎の作業用領域.

work_mem

  • Query実行時のsort, table join, hash table操作に利用される領域.
  • sort, table join, hash table操作は作業メモリを適切に設定すると性能向上 (高速化) が期待出来る.
  • session毎に設定が可能.
  • memoryを要するsessionで, 都度大きな値を設定することが望ましい.
  • 1つのqueryの中で上記操作が複数回実行される場合, 処理毎に設定領域が確保される.
    • 例えば1つのquery (1回の問い合わせ) あたりではなく, Query中のsort処理のたびにwork_memの値のmemoryを消費する.
    • その為, たくさんのbackend processが起動中にwork_memの値が大きいとシステム全体のmemoryが逼迫する.
    • 1つのqueryで多数のtableをjoinする場合, work_memにx sort処理の回数分のmemoryが1queryで必要となる.
  • sort処理は order by, distinct, merge 結合で行われる.
  • 最大でwork_mem*max_connections+α消費する

maintenance_work_mem

  • DB maintenanceの (保守) 操作で使われるmemoryの最大容量.
    • vacuum
    • create index
    • alter table add foreign key
  • work_mem < maintenance_work_mem とすることでmaintenance時間の短縮に繋がる.

catalog cache

postgres processへ頻繁にアクセスするsystem catalog(RDBMSがスキーマメタデータや内部的な情報を格納するtable)は, shared_bufferと合わせpostgres processにもコピーを保存している.これをcatalog cacheと言う.

temp_buffer

  • 一時tableへのアクセスで利用される, backend process毎に生成されるmemory領域.
    • 一時tableはcreatetemplate文で作成可能.
  • applicationのパフォーマンスが悪くなる原因に temp_data write (write temporary table) が発生している場合がある.
    • その場合は (work_memを超えたらtemp tableを使うようになる為) query実行前にwork_memを大きくする必要がある.