IBM Support

[Db2] Fenced ルーチンを実行していなくても、大量の db2fmp が生成されることがある

Question & Answer


Question

アプリケーションで fenced ルーチンを実行していない、またはほとんど使用していないにもかかわらず、多くの db2fmp プロセスが起動することがあります。 これはなぜでしょうか? また、防ぐ方法はありますか?

Cause

IBM Data Server Driver for JDBC and SQLJ (JCC) ドライバーがサーバーからエラーを受け取った場合、デフォルトでは以下のようなメッセージをアプリケーションに返します。
注: 以下の例では、意図的に存在しない表を照会して SQL0204N を発生させています。
DB2 SQL error: SQLCODE: -204, SQLSTATE: 42704, SQLERRMC: SYSIBM.SYSDUMMY
JCC ドライバーのデータ・ソースまたは接続プロパティの retrieveMessagesFromServerOnGetMessage に true を設定すると、同じエラーで以下のようなメッセージが返ります。
SQL0204N "SYSIBM.SYSDUMMY" は未定義の名前です。
retrieveMessagesFromServerOnGetMessage=true を設定した場合、アプリケーションによる SQLException.getMessage または SQLWarning.getMessage 呼び出しで、JCC はサーバーの SYSIBM.SQLCAMESSAGECCSID プロシージャーを呼び出します。Db2 はこのストアード・プロシージャーを fenced ルーチンとして実装しているため、getMessage() の度に fenced プロセス (db2fmp) が呼び出されます。
また、SYSIBM.SQLCAMESSAGECCSID は THREADSAFE でないため、多くの接続から SQLException.getMessage や SQLWarning.getMessage が呼び出されると、多くの db2fmp プロセスが起動します。

Answer

SYSIBM.SQLCAMESSAGECCSID の呼び出しは追加のトランザクションを開始し、サーバーのメモリーおよび CPU リソースを消費します。
文章による SQL メッセージの取得が必須ではない場合、retrieveMessagesFromServerOnGetMessage を false (デフォルト) に戻すことを検討してください。

WebSphere Application Server で retrieveMessagesFromServerOnGetMessage を false にする例
  1. WAS 管理者で管理コンソールを起動します。
  2. 管理コンソールのパス「リソース」->「JDBC」->「データ・ソース」を展開します。
  3. 使用しているデータ・ソースを選択し、カスタム・プロパティを選択します。
  4. retrieveMessagesFromServerOnGetMessage プロパティの値を false に設定します。

運用上の考慮点
WebSphere Application Server は XA でないデータ・ソースに対して、デフォルトで retrieveMessagesFromServerOnGetMessage=true を設定するのでご注意ください。
retrieveMessagesFromServerOnGetMessage=false にもかかわらず多くの db2fmp が起動し、fenced ルーチンを実行している心当たりがない場合、呼び出された fenced ルーチン名を以下のように判別できます。
  1. インスタンス所有者でサーバーにログインします。
  2. db2pd コマンドで Fenced ルーチンの実行履歴を表示します。
    $ db2pd -fmpe
    $ db2pd -fmpe
    
    FMP Process:
    FmpPid     Bit   Flags      ActiveThrd PooledThrd ForcedThrd Active
     62900      64    0x00000000 0          0          0          Yes
    
       Active Threads:
         EduPid : 17560     ThreadId : 0
            Routine ID     Timestamp
            65696          2016-09-06-09.00.44.019000
  3. 表示されたルーチン ID (Routine ID) から、ルーチン名を判別します。
    $ db2 connect to sample
    $ db2 "select char(routineschema,10), char(routinename,30) from SYSCAT.ROUTINES where routineid = 65696"
    
    1          2
    ---------- ----------------------------
    SYSFUN     GET_DBM_CONFIG
    
      1 レコードが選択されました。
参考: DB2 V9.7 GA までは db2pd の-fmpe オプションが使えませんが、以下のようにトレースで実行履歴をキャプチャーできます。
  1. インスタンス所有者でサーバーにログインします。
  2. マスクを指定した DB2 トレースを有効にします。
    (fenced プロセスの呼び出しを行う単一の関数のみトレースするため、非常に低い負荷で実行されます。)
    $ db2trc on -m sqlerFmpProcessStartReq -f db2trc.dmp
  3. ある程度 db2fmp プロセスが増えた後、トレースを停止してフォーマットします。
    $ db2trc off
    $ db2trc fmt db2trc.dmp db2trc.fmt
  4. フォーマットされたファイルを開き、ルーチン名を確認します。 probe 440 にルーチンの実装名が記録されるので、以下のようにルーチンの実行回数を集計できます。
    $ awk '/3.3.36.46.0.440/{c=6} c && c-- < 2 {print $NF}' db2trc.fmt | sort | uniq -c | sort -rn
     1237 sqlGetServerMsgC
        2 get_dbm_config.
        1 dbm_get_cfg.
    参考: ルーチンの実装名からルーチン名を確認するには、対象データベースに接続して以下のような SQL を実行します。
    以下の例では sample データベースに接続して、実装名に sqlGetServerMsgC を含むルーチンを照会しています。
    $ db2 connect to sample
    $ db2 "select char(routineschema,10), char(routinename,30) from SYSCAT.ROUTINES where implementation like '%sqlGetServerMsgC%'"
    
    1          2
    ---------  -----------------
    SYSIBM     SQLCAMESSAGECCSID
    
      1 レコードが選択されました。
関連情報

お問合せ先
技術的な内容に関して、パスポート・アドバンテージの契約のもと Db2 テクニカル・サポートへお問い合わせください。
Db2 テクニカル・サポート

[{"Type":"MASTER","Line of Business":{"code":"LOB10","label":"Data and AI"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SSEPGG","label":"Db2 for Linux, UNIX and Windows"},"ARM Category":[{"code":"a8m500000008PmhAAE","label":"Routines - Stored Procedures and UDF-\u003Edb2fmp"}],"ARM Case Number":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"All Versions"}]

Document Information

Modified date:
26 October 2023

UID

swg21605299