無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

第 45章Background Worker Processes

PostgreSQLは別々のプロセスでユーザ提供のコードが実行されるように、拡張することができます。 これらのプロセスは postgres によって起動、終了、監視され、サーバの状況に密接に関係している生存期間を持たせます。 これらのプロセスは PostgreSQL の共有メモリ領域に割り当てられたり、内部的にデータベースに接続するオプションを持っています。これらのプロセスはまた、まさにクライアントが接続された実際のサーバプロセスのように別々に複数のトランザクションを実行することができます。また、 libpq と連携することによって、これらはサーバに接続可能となり、実際のクライアントアプリケーションのように振る舞うことが出来ます。

警告

バックグラウンドワーカーを使うにあたっては、堅牢性とセキュリティリスクを考慮しなくてはなりません。なぜならば、 C 言語で書かれており、データへのアクセスが制限されていないためです。バックグラウンドワーカープロセスを有効にしたいと思っている管理者は厳重に注意して実践すべきです。注意深く検査されたモジュールだけが、バックグラウンドワーカープロセスの実行を許されるべきです。

shared_preload_libraries に記されたモジュールのみバックグラウンドワーカーを実行できます。バックグラウンドを実行したいモジュールは _PG_init() から RegisterBackgroundWorker( BackgroundWorker *worker ) を呼び出すことによって、登録する必要があります。 その構造、 BackgroundWorker は以下のように定義されます。

typedef void (*bgworker_main_type)(void *main_arg);
typedef struct BackgroundWorker
{
    char        bgw_name[BGW_MAXLEN];
    int         bgw_flags;
    BgWorkerStartTime bgw_start_time;
    int         bgw_restart_time;       /* 秒単位、もしくは、BGW_NEVER_RESTART */
    bgworker_main_type bgw_main;
    Datum       bgw_main_arg;
} BackgroundWorker;

bgw_name は、ログメッセージ、プロセス一覧、類似した機能で使用される文字列です。

bgw_flags は、モジュールが要求する機能を示すビット値もしくはビットマスクです。可能な値は BGWORKER_SHMEM_ACCESS (共有メモリへのアクセスを要求します)と BGWORKER_BACKEND_DATABASE_CONNECTION (データベース接続を確立し、その後、トランザクションやクエリの実行ができます)です。データベースに接続するために BGWORKER_BACKEND_DATABASE_CONNECTION を使っているバックグラウンドワーカーもまた、 BGWORKER_SHMEM_ACCESS を使って共有メモリに接続します、もしくはワーカーの起動に失敗します。

bgw_start_time は、 postgres がプロセスを起動すべきときのサーバの状態です。その状態は、 BgWorkerStart_PostmasterStart ( postgres 自身が初期化を終えるとすぐに起動します。これを要求するプロセスはデータベース接続に望ましいものではありません。)、 BgWorkerStart_ConsistentState (ホットスタンバイにおいて一貫性のある状態に到達すると、つまり、プロセスがデータベースに接続し、参照のみのクエリを実行するのを許可する状態になると起動します。)、 BgWorkerStart_RecoveryFinished (システムが参照/更新クエリを実行すると起動します。)のうちの一つです。この設定はいつプロセスが起動されるかを示すだけであることに注意してください。これらのプロセスは、違う状態になったときに停止するわけではありません。

bgw_restart_time は、プロセスがクラッシュした場合に postgres がそのプロセスを再起動するために待つべき間隔を秒単位で指定するものです。あらゆる正の数、もしくはクラッシュした場合に再起動させないことを示す BGW_NEVER_RESTART を指定できます。

bgw_main は、プロセスが起動されたときに実行される関数へのポインタである。この関数は void * 型の引数を一つとり、 void を返さなければなりません。 bgw_main_arg はその唯一の引数として、渡されます。グローバル変数である MyBgworkerEntry は、登録時に渡される BackgroundWorker 構造体のコピーを指すことに注意してください。

ひとたび実行すると、このプロセスは BackgroundWorkerInitializeConnection( char *dbname , char *username ) を呼び出すことによって、データベースへ接続できます。 これはプロセスに SPI を使用してのトランザクションとクエリの実行を許します。もし、 dbname がNULLであった場合、そのセッションは特定のデータベースに接続しません。しかし、共有カタログにはアクセスできます。もし、 username がNULLの場合、そのプロセスは initdb 時に作成されたスーパーユーザーとして実行されます。 BackgroundWorkerInitializeConnectionは、バックグラウンドワーカーごとに一度のみ呼ぶことができ、これはデータベースを切り替えることができません。

制御が bgw_main 関数に達したとき、シグナルはまずブロックされます。このブロックは解除されなければなりません。このことは、必要があれば、プロセスにそのシグナルハンドラを変更することができることを意味します。シグナルは新しいプロセスで BackgroundWorkerUnblockSignals を呼び出すことにより、解除でき、 BackgroundWorkerBlockSignals を呼び出すことでブロックできます。

バックグラウンドワーカーは継続的に実行されていることが期待されています。もしバックグラウンドワーカーが正常に終了した場合、 postgres はそれらをすぐに再実行します。 バックグラウンドワーカーが何もすることがないときは、割り込み可能な休止状態にすることを考慮しないといけません。これは WaitLatch() を呼び出すことによって可能になります。 この関数を呼んだときに、 WL_POSTMASTER_DEATH フラグが設定され、 postgres 自身が終了する緊急事態には、リターンコードを確認するようにしてください。

バックグラウンドワーカーの例として、 worker_spi というオプションモジュールがあります。これはいくつかの有用な技術を示します。


powered by SEO.CUG.NET