長時間トランザクションとは、トランザクションの実行時間が一定のしきい値(アプリケーション層で定義)を超え、かつコミットされていない状態を指します。このしきい値は通常、トランザクションのタイムアウト時間(テナントシステム変数 ob_trx_timeout によって制御され、トランザクションの実行時間がこの時間を超えると自動的にロールバックされ、リソースが解放される)よりも短く設定されます。これは、アプリケーション層がトランザクションの過度な長時間化やシステムリソースの占有を防ぐための監視手法です。
長時間トランザクション/ハングトランザクションの弊害:
- アクティブなトランザクションはMemTableへの参照を保持しており、トランザクションが長時間終了しない場合、MemTableがフリーズして解放されず、メモリが満杯になる可能性があります。
- アクティブなトランザクションが行ロックを保持している場合、その行ロックが解放されなくなります。他のトランザクションがその行ロックを待機することで、長時間の待機やトランザクションのタイムアウトによるロールバックが発生する可能性があります。
長時間トランザクション/ハングトランザクションのアラートが検出された場合は、直ちに原因を確認し、迅速にリスクを排除する必要があります。
以下の手順で調査することができます。
長時間トランザクションを捕捉します。
システムテナントの
GV$OB_TRANSACTION_PARTICIPANTSビューをクエリすることで、長時間トランザクションを特定できます。長時間トランザクションが存在する場合、そのトランザクションのトランザクションID(TX_ID)、スケジューラーのノード(SCHEDULER_ADDR)、およびセッションID(SESSION_ID)を取得します。SELECT count(1) FROM GV$OB_TRANSACTION_PARTICIPANTS WHERE CTX_CREATE_TIME < date_sub(now(), INTERVAL 600 SECOND) AND STATE = 'INIT';上記の例での600sはデフォルトのトランザクションタイムアウト時間を表しており、アプリケーション層ではシナリオに応じて調整可能です。
注意
トランザクションの巡回検査を行う前に、システム内にホストレスな状態が存在しないことを確認する必要があります。
そのトランザクションがXAトランザクションかどうかを判断します。トランザクションIDをフィルター条件として
V$OB_GLOBAL_TRANSACTIONビューをクエリし、レコードが存在すればXAトランザクションです。そのトランザクションがXAトランザクションの場合、対応するユーザーテナントで xa rollback を使用してトランザクションをロールバックします。通常のトランザクションの場合は、OBClientを使用して、そのトランザクションのスケジューラーが存在するノード上のシステムテナントに直接接続し、kill session を実行してトランザクションをロールバックします。
運用上の推奨事項:
トランザクションのステートメントタイムアウト時間(テナントシステム変数 ob_query_timeout のデフォルトは10秒)とトランザクションのタイムアウト時間(テナントシステム変数 ob_trx_timeout のデフォルトは100秒)を長く設定しすぎないことを推奨します。これは、トランザクションが長時間終了せずにシステムの安定性に影響を与えるのを避けるためです。