詳解 PostgreSQL[10/11対応]―現場で役立つ新機能と実践知識

第2章 PostgreSQLの内部構造―プロセスやメモリの流れ,特徴的な機能のしくみ

この記事を読むのに必要な時間:およそ 6 分

PostgreSQLの内部構造

第2章ではPostgreSQLの内部構造を紐解きながら,基礎的な部分にフォーカスしていきます。

PostgreSQLの内部構造を知ることで,次章以降の事前知識にもなりますし,PostgreSQLの新機能がいかにして成長してきたかも見えてきます。

PostgreSQLのソースコードの場所

PostgreSQLのソースコードは全部で120万行以上(2018月11月27日現在)あります。これをすべて把握するのは難しいので,本章では重要なワードとその概要を押さえながら話を進めていきます。

もっと詳しく知りたいと思った人は,そのワードで公式ドキュメントを検索してください。それよりもさらに深く知りたいと思った人は,ソースコードリーディングをお勧めします。PostgreSQLのコードは,統率されたきれいなコードとなっています。C言語の初心者でも読みやすく,ミドルウェアのコードとしても学びが多いです。

プロセスの構造と役割

まずはプロセスについて説明します。

PostgreSQLは,マルチプロセスタイプのアーキテクチャです。よく比較対象に挙がるMySQLは,マルチスレッドタイプのアーキテクチャです。MySQLはコネクションが生成された場合,メインプロセスがスレッドを生成します。それに対してPostgreSQLはプロセスを生成します。

Linuxアーキテクチャに詳しい人からすると,PostgreSQLは無駄な実装に感じるかもしれません。たしかにスレッドとプロセスの生成ではスレッドのほうが軽量です。ですがRDBMSの性能はそこだけで決まるほど簡単なものではなく,たとえばロックの待ち時間に比べれば誤差と言えるでしょう。

このようにPostgreSQLはマルチプロセスですから,それぞれのプロセスを知ることは重要です。主なプロセスは表1のとおりで,それらプロセスの流れは図1のとおりです。図1に登場していない表1のプロセスは,スタートアッププロセスのように常駐しないものや,アーカイバやWALセンダのように設定した場合のみ登場するものです。

表1 主なプロセス

プロセス内容
マスタプロセス最初に起動される親プロセス
ライタ共有バッファの内容をデータファイルに書き出す
WALライタWALバッファの内容をWALファイルに書き出す
チェックポインタすべてのダーティページをデータファイルに書き出す
自動VACUUMランチャ設定にしたがって自動VACUUMワーカを起動する
自動VACUUMワーカ自動VACUUMを実行する。複数起動することがある
統計情報コレクタデータベースの活動状況に関する統計情報を収集する
バックエンドプロセスクライアントの接続要求ごとに起動し,要求に対して処理する
スタートアッププロセスPostgreSQLの起動時などにクラッシュリカバリ処理を行う
ロガーPostgreSQLのログをファイルへ書き出す
アーカイバWALログをアーカイブする
WALセンダレプリケーション時にWALをスレーブサーバに転送する
WALレシーバレプリケーション時にWALをマスタプロセスから受信する
バッググランドワーカ汎用的なワーカ。バックグランドワーカをユーザーが定義した場合も起動する
ロジカルレプリケーションランチャロジカルレプリケーション時に受信側で1プロセスのみ起動するバックグランドワーカ
ロジカルレプリケーションワーカロジカルレプリケーション時に受信側で複数起動するバックグランドワーカ
パラレルワーカパラレルスキャンを実行時に起動するバックグランドワーカ

図1 主なプロセスの流れ

図1 主なプロセスの流れ

PostgreSQLは,ライタがデータファイルやインデックスファイルをディスクに更新しています。ただし,その更新は,コミットに合わせてリアルタイムで行われているわけではありません。性能向上のため,チェックポイントと呼ばれる更新タイミングが発生するまでは,更新があっても共有バッファにデータを貯めておきます。この貯められたデータをダーティページと呼びます。そしてチェックポイントのタイミングで,チェックポインタがダーティページをディスクに書き込みます。

そのため,共有バッファに更新情報を貯めている間に障害が起きると,ダーティーページを失う可能性があります。それを防ぐために,共有バッファ中のデータに対してどのような更新を行ったかの情報を保存しているのがWALです。WALはコミットのタイミングでWALライタが記録しています。クラッシュリカバリが必要になったときは,WALの中にある記録を使用してデータ消失を防ぎます。共有バッファなどのメモリについては次節で説明します。

このようにPostgreSQLは,さまざまプロセスが役割分担をしながら処理しています。

著者プロフィール

曽根壮大(そねたけとも)

株式会社オミカレ副社長兼CTO。数々の業務システム,Webサービスなどの開発・運用を担当し,2017年に株式会社はてなでサービス監視サービス「Mackerel」のCRE(Customer Reliability Engineer)を経て現職。 コミュニティでは,Microsoft MVPをはじめ,日本PostgreSQLユーザ会の理事として勉強会の開催を担当し,各地で登壇している。 builderscon 2017,YAPC::Kansaiなどのイベントでベストスピーカーを受賞し,分かりやすく実践的な内容のトークに定評がある。 他に,岡山Python勉強会を主催し,オープンラボ備後にも所属。著書に『Software Design』誌で,データベースに関する連載「RDBアンチパターン」をまとめた『失敗から学ぶRDBの正しい歩き方』を執筆。

@soudai1025
はてなid:Soudai

著書