1. ホーム
  2. データベース
  3. デービーツー

DB2アクティビティログフルの原因を分析し、DB2ログフルの方法と回避策を解決します。

2022-01-19 08:06:28

ログ使用状況

以下の図は、同時実行トランザクションの下でのログの使用状況を模式的に表したものである。

画像

3つの同時進行プログラム プロセス1、プロセス2、プロセス3がある。各プログラムには2つのトランザクションがある。青いブロックはSQL文、赤いブロックはコミット操作、緑のブロックはロールバック操作を表しています。各下向き矢印は、ログバッファのデータがログディスクにフラッシュされることを表しています(デフォルトでは、すべてのコミット操作によってログバッファがディスクにフラッシュされます)。

T1時点では、トランザクションAがコミットされ、ログバッファがディスクにフラッシュされる。
T2 の時点で、トランザクション B がコミットし、ログバッファがディスクにフラッシュされる。この時点でログXは使い切られますが、XのトランザクションCはコミットされていないため、この時点ではまだXがアクティブなログです。

上図において、トランザクションCが操作をコミットしない場合、ログXは常に最初のアクティブログ(最も古いトランザクションログ)となり、それ以降のログもアクティブログとなり、他のアプリケーションによって最終的にログが満杯になることになります。

アクティブログ

ログは、コミットされていないトランザクションを含む場合、アクティブです(すべてのトランザクションがコミットされているが、対応する変更がディスクに永続化されていない場合など、他のケースもあります)。

最初のアクティブログ

最初のアクティブログ、最初のアクティブログ以降のログ(つまり最初のアクティブログより大きな番号を持つログ)はすべてアクティブログであり、データベーススナップショットを通じて最初のアクティブログ、現在のアクティブログ、最後のアクティブログとして表示することが可能です。

$ db2 get snapshot for db on sample | grep -i "File number"
File number of first active log = 0
File number of last active log = 2
File number of current active log = 0
File number of log being archived = Not applicable

フルログ化の理由

DB2には有効なログ容量の合計に制限があり、制限に達するとフルログの問題が発生し、(LOGPRIMARY + LOGSECOND) * LOGFILSIZ * 4KBに制限されます。

ログが満杯になる理由は2つだけです。

1.) 小さなトランザクションが最初のアクティビティログを保持し、決してコミットしないため、最初のアクティビティログがアクティブなまま解放されない。これは交通渋滞に似ていて、1台の車がエンジントラブルで交差点を塞ぎ(最初のアクティビティログを占有)、その後ろの車がすべて問題なくても(その後のトランザクションはきちんとコミットされる)、交差点を通り抜けることができずに溜まっていき、ついには道路全体が車で塞がれてしまう(ログフル)ようなものである。

2.) 1つのトランザクションが非常に大きく、すぐにすべてのログを使い切ってしまう。

ログフルパフォーマンス :

まず、アプリケーションはSQL0964Cエラーを報告します。

$ db2 "insert into test select * from test"
DB21034E The command was processed as an SQL statement because it was not a
During SQL processing it returned:
SQL0964C The transaction log for the database is full. SQLSTATE=57011

次に、db2diag.logに次のようなエラーが報告されます。

2017-03-09-17.24.50.315000+480 E3234873F644 LEVEL: Error
PID : 8532 TID : 13028 PROC : db2syscs.exe
INSTANCE: DB2INST1 NODE : 000 DB : SAMPLE
APPHDL : 0-453 APPID: *LOCAL.DB2INST1.170309092321
AUTHID : MIAOQINGSONG HOSTNAME: ADMINIB-PR7US3I
EDUID : 13028 EDUNAME: db2agent (SAMPLE)
FUNCTION: DB2 UDB, data protection services, sqlpgResSpace, probe:2860
MESSAGE : ADM1823E The active log is full and is held by application handle
     "0-441". Terminate this application by COMMIT, ROLLBACK or FORCE
     APPLICATION.

フルログの一時的な取り扱い。

1. LOGSECONDを追加することで一時的に利用可能なログサイズを増やすことができます(修正時にIMMEDIATEオプションを追加してすぐに反映させる必要があります)。LOGPRIMARYを追加しても、反映させるにはデータベースの再起動が必要なので、役に立ちません。

2.最初のアクティブなログを保持しているアプリケーションを強制終了する。強制する前に、スナップショットを取得して、アプリケーションの状態を確認することができます。

{{コード

<<--トランザクションには複数のSQLが存在する場合があります。これは現在実行されている、または最後に実行されたSQLを示すだけで、このSQLが原因でログがいっぱいになっていることを示すわけではありません。

{{コード

ログ完全回避。

1.) キャプチャしたアプリケーションのスナップショットをもとに、なぜコミットしないのか、アプリケーション開発者を探し出すことが、問題の再発を防ぐための基本的な方法です。
2.) DB2 管理レベルから、データベース設定パラメータ max_log と num_log_span を設定することができる
3.) データベースのスナップショットで最も古いトランザクションを保持しているAppl idを一定間隔で取得し、それが長期間(例えば2日間)変更されない場合は強制的にオフにするスクリプトを書くことができます。

補足説明

各アプリケーションが使用するログのサイズを表示する。

{{コード

また、db2pd -db で使用中の各ログの状態を確認することができます。 {データベース名 -トランザクション

注目すべきは、そのパラメータです。

ApplHandl
トランザクションのアプリケーションハンドルです。
スペースリザーブド
/
トランザクションのために予約されているログスペースの量です。
ログスペース {
トランザクションに必要なログ領域の合計で、使用領域と補償ログレコードの予約領域を含みます。

DB2活動ログが満杯になる原因を分析することで、この問題の解決策を見つけ、再発を回避することができます