Note: Massimo Dal Zotto氏による寄稿。
data/pg_options というオプションファイルには、 バックエンドがトレースメッセージを制御するための実行時用オプション やその他のバックエンドのチューニング用パラメータを記述します。バッ クエンドは SIGHUP シグナルを受け取ると、このファイルを再読み込みし ます。これにより、Postgres を再起動する ことなく、実行した状態のまま実行時用オプションを変更することができ ます。この事実はこのファイルを興味深いものにしています。このファイ ルでは、トレース用パッケージ( backend/utils/misc/trace.c )で使用されるデバ ッグ用フラグやバックエンドの動作を制御するための数値パラメータとい ったオプションを指定できます。新規のオプションやパラメータは backend/utils/misc/trace.c と backend/include/utils/trace.h 内で定義される必 要があります。
例えば、foo.c ファイルのコードに条件付トレース メッセージと調整用の数値パラメータを追加する場合を考えます。行なわな ければいけないことは、次のように backend/include/utils/trace.h 内に定数 TRACE_FOO と OPT_FOO_PARAM を追加し、
/* trace.h ファイル */ enum pg_option_enum { ... TRACE_FOO, /* foo 関数群のトレース */ OPT_FOO_PARAM, /* foo 調整用パラメータ */ NUM_PG_OPTIONS /* これはenumの項目の最後になければいけません */ };そして、次のように上に相当する行を backend/utils/misc/trace.c に追加することです。
/* trace.c ファイル*/ static char *opt_names[] = { ... "foo", /* foo 関数群のトレース */ "fooparam" /* foo 調整用パラメータ */ };この 2 ファイル内のオプションは正確に同じ順序でなければいけません。 これで foo ソースファイルで、新しいフラグを参照することができるよ うになります。
/* foo.c ファイル */ #include "trace.h" #define foo_param pg_options[OPT_FOO_PARAM] int foo_function(int x, int y) { TPRINTF(TRACE_FOO, "entering foo_function, foo_param=%d", foo_param); if (foo_param > 10) { do_more_foo(x, y); } }
既存の非公式なトレースフラグを使用しているファイルも、次のコードを 単純に追加することで変更できます。
#include "trace.h" /* int my_own_flag = 0; -- この行を削除する */ #define my_own_flag pg_options[OPT_MY_OWN_FLAG]
バックエンドが起動する時、全ての pg_options は 0 に初期化されていま す。異なったデフォルト値を必要とする場合、 PostgresMain の初めに初期化用コードを追加しなけ ればなりません。こうして、以下のように data/pg_options ファイル内に値を書き込むことに よって、foo_param の設定と foo トレースを有効にすることができるよう になります。
# file pg_options ... foo=1 fooparam=17
新しいオプションは、新しくバックエンドが起動した時に読み込まれます。 実行中のバックエンドでオプションの変更を有効にするには、postmaster に対して SIGHUP シグナルを送信する必要があります。そのシグナルは自動 的に全てのバックエンドに対して送信されます。特定のバックエンドに対し てのみに、SIGHUP を直接送信することにより、そのバックエンドに対しての み変更を有効にすることもできます。
pg_options は、Postgres の -T スイッチを以下のように使って指定することもでき ます。
postgres options -T "verbose=2,query,hostlookup-"
エラーやデバッグ用メッセージを表示するために使用される関数は、 syslog(2) 機能を使用するように設定できるよ うになりました。標準出力や標準エラーに表示されるメッセージに時刻 とバックエンドのプロセス番号を前につけた、以下のように形式で出力 されます。
#timestamp #pid #message 980127.17:52:14.173 [29271] StartTransactionCommand 980127.17:52:14.174 [29271] ProcessUtility: drop table t; 980127.17:52:14.186 [29271] SIIncNumEntries: table is 70% full 980127.17:52:14.186 [29286] Async_NotifyHandler 980127.17:52:14.186 [29286] Waking up sleeping backend process 980127.19:52:14.292 [29286] Async_NotifyFrontEnd 980127.19:52:14.413 [29286] Async_NotifyFrontEnd done 980127.19:52:14.466 [29286] Async_NotifyHandler done
この形式はログファイルの可読性を向上させており、どのバックエンドが いつ何をしたのかがユーザに判るようになっています。データベースに 関するエラーや問題の検出を行なう、ログを監視する簡単な awk や perl スクリプトを作成することや、トランザクション時間に関する統計情報の 演算を行なうことがより簡単にできるようになっています。
メッセージを syslog に出力する時には LOG_LOCAL0 ファシリティが使 われます。syslog を使用するかどうかは syslog pg_option で設定でき ます。残念ながら、多くの関数は printf() を直 接使ってメッセージを標準出力や標準エラーに出力していますので、その 出力はsyslogに出力することも時刻情報を付与することもできません。 全ての出力を統一された形で制御できるように、全ての printf の呼び出 しを PRINTF に置換すること、また、もしそれが標準エラーへの出力であ る場合は EPRINTF に置換することですっきりすることはわかっているの ですが(まだ行なわれていません)。
新しい pg_options という仕組みは、次のような理由で、新しいバックエン ドオプションを定義する方法に比べて、より使いやすくなっています。
制御したい事柄それぞれに異なるスイッチを定義する必要がありませ ん。全てのオプションは、data ディレクトリ内にある外部ファイル内 のキーワードとして定義されています。
あるオプションの設定を変更するために Postgres を再起動する必要がありません。 通常、バックエンドオプションは postmaster に対してその起動時に指 定され、各バックエンドに渡されます。この段階でファイルから読み込 まれることになります。
バックエンドが実行中の状態のままでオプションを変更することがで きます。このため、デバッグ用メッセージ出力を問題が発生した時に だけ有効にすることで、問題の究明ができるようになります。また、 調整用パラメータに対しても異なる値を試すこともできます。
# コメント オプション=整数値 # オプション に値を設定します。 オプション # オプション を 1 に設定します。 オプション+ # オプション を 1 に設定します。 オプション- # オプション を 0 に設定します。keyword は、 backend/utils/misc/trace.cで定義されたオプ ション名の省略形にもなることに注意して下さい。
現時点でサポートしている全オプションの一覧については、 管理者ガイド の実行時オプションの章を参照 して下さい。
非公式な変数とオプションを使っていた既存のコード、主に postgres.c 内にあったものは、pg_options 機能 を使うように変更されています。既存の全てのコードをこの方法を使うよ うに変更したいと思っています。そうすれば、 Postgres のコマンドラインスイッチから多 くを取り除くことも、オプションの値を設定する一意な場所を持つ調整用 オプションをもっと多く持つこともできるようになります。