my syntax suger

i have an unbeknown dictionary. everything is up to me.

PostgreSQL: process, memory整理

  • 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を起動する

(background) writer process

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

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に出力された状態。
    • PostgreSQLではshared bufferをdisk cacheとして使用している為データ更新はshared buffer上で行われ直ぐにHDDに書き込まれるわけではない。HDDへ未だ書き込んでないpageのことをdirty pageと呼ぶ。

autovacuum launcher & autovacuum worker process

  • autovacuumの制御、実行process。
  • autovacuum用worker process起動をpostgresへ依頼する。
  • workerはtableに対し自動的にvacuumとanalyzeを実行する。
  • 実行前に対象tableに大量にupdateがあったかを統計情報を参照して検査する。

統計情報 collector process

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

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を大きくする必要がある。