データベースの緊急対応プロセスは、一般的にイベント検出、異常情報収集、分析診断、意思決定処理といったいくつかのステップに分かれます。本記事では、いくつかの一般的なシナリオを例に挙げ、ユーザーが迅速に問題の根本原因を特定し判断するための分析・意思決定手法をいくつか紹介します。
イベント認識
緊急事態の認識は通常、アプリケーションシステムのアラート、データベースのアラート、ユーザーからの報告フィードバック、日常点検などによって発見されます。いずれの方法で発見された場合でも、イベント/障害への対応の第一歩として、障害情報の同期(現在の影響範囲および担当者を含む)と異常エラーメッセージの迅速な収集が必要です。これにより、次の分析や緊急対応のための根拠を提供します。
異常情報の収集
一般的に、異常情報は以下の観点から収集・整理する必要があります:
異常の表れ:通常、最初のレベルでは業務関連の情報が含まれます。例えば、ユーザーがログインできない、注文の送信に失敗した、指定されたページを開けないなどです。異常情報収集の最初のステップとして、業務アラートやモニタリング情報からデータベース関連のアラート情報を特定・検出することが求められます。例えば、アプリケーションのDAL層ログ、ミドルウェア、クライアントなどから報告されるデータベース関連の異常情報などです。
異常発生時刻:障害/異常が始まった具体的な時点と、その持続時間を確認します。
異常範囲:異常が単一のアプリケーションで発生しているのか、それともすべてのアプリケーションで発生しているのかを確認します。また、対応するOBクラスタがグローバルに影響を受けているのか、あるいは特定のクラスタやテナントに限定されているのかを判断します。グローバル範囲に及ぶ影響の場合、通常はインフラストラクチャの異常から調査を開始します。局所的な障害や異常の場合は、具体的なクラスタ、テナント、データベース、obproxyの詳細情報を確認する必要があります。
エラー関連ログ:異常がトリガーされた期間に報告されたエラーログ情報を収集します。これは通常、アプリケーションのDAL層ログおよびクライアントログから取得します。
変更/リリースの有無:障害発生時点の前後で業務上のリリースや変更があったかどうかを確認し、あった場合は具体的な情報を収集します。実際のシナリオでは、多くの障害や異常は変更によって引き起こされることが多いです。
関連業務への影響:現在の障害の影響範囲を確認し、その影響が継続する場合、上流または下流の他のシステムにも影響を与える可能性があるかどうかを判断します。この部分はデータベースだけにとどまらず、サイト可用性(SRE)全体の戦略に関わるため、ここでは詳しく説明しません。
分析診断&意思決定ツリー
前述のとおり、緊急事態の発生源は大きく二つに分類されます。一つはアプリケーションから検出される異常であり、もう一つはデータベース自身の巡回点検やアラートからのものです。後者の場合、一般的には具体的なDBイベントを指し、詳細な緊急対応方法については本章の後続のセクションで詳しく分析します。この節では、業務側のエラーや異常に焦点を当て、段階的な分析と判断を通じて、可能な限り迅速に問題を特定するための考え方と手法を紹介します。
クイックベースラインチェック
トラブルシューティングの考え方
まず、OBクラスタのヘルスチェックを迅速に実行します。
いかなる緊急事態のトラブルシューティングを開始する前に、最も基本的な異常状況を早期に排除し、無駄な調査を避けます。OceanBaseの正常な動作に影響を与える主なソフトウェアおよびハードウェアの要素は以下の通りです:
NTP時計が同期されているかどうか
サーバーがダウンしていないかどうか
ログディスクやデータディスクの容量が上限ではないかどうか
データセンターのネットワークにジッターが発生していないかどうか
ロードバランシング機器/コンポーネント(F5/LVSなど)に障害がないかどうか
クラスタの基本的なヘルスチェック項目について、OceanBaseクラウドプラットフォームはすでに迅速なヘルスパトロール機能を提供しています。詳細については、OCPユーザーガイドを参照してください。
異常期間中に業務トラフィックが急増したかどうかを確認します
最も基本的な外部異常を排除した後、次に確認すべきは、異常期間中に外部からの業務リクエスト量が通常よりも明らかに増加したかどうか、つまり通常のトラフィック急増によって引き起こされる各種リソース不足などの異常問題です。
アプリケーション層からデータベース関連のエラーや異常を分析します
上記の2つのケースでは、実際の本番環境において、迅速に確認できる情報は通常一部に限られます(例えば、明確なハードウェアのダウン、ネットワーク切断、ディスク容量上限、業務トラフィックの増加など)。しかし、実際のシナリオでは多くの要因が最初から迅速に確認できない場合もあります(例えば、I/O/ネットワークのジッター、データ分布の変化、あまりヒットしない業務ロジックが集中して発生するなど)。このような場合はさらに分析が必要です。一般的に、アプリケーション層から明らかになるデータベース関連のエラーや異常は、通常以下のいくつかのカテゴリに分類されます:
アプリケーション接続プールが上限
アプリケーションリクエストのタイムアウト
アプリケーション接続の確立失敗
アプリケーション書き込み失敗
アプリケーションロックの競合
以下にいくつかのシナリオをそれぞれ紹介します。
アプリケーション接続プール上限/アプリケーションリクエストタイムアウト
接続プールが上限になることは、アプリケーション側で最も一般的なデータベース異常現象の一つです。多くの異常事象が段階的に伝播し、最終的にはアプリケーション側の接続プールが上限となり、新たな接続を確立できなくなることがあります。接続プールが上限になる直接的な原因は、アプリケーションリクエストのタイムアウトです。実際の状況から見ると、問題を引き起こす要因は発生頻度の高い順に以下のようになります:
データベース内に実行計画が異常なスローSQLが存在し、応答時間が長くなるため、アプリケーション側で接続の再試行が繰り返されます。
この場合の解決策は、スローSQLの実行計画に対して介入するか、直接制限をかけることです。詳細な処理手順については、SQLクエリによる異常を参照してください。
データベース内のSQL応答時間が長い(ただし、明らかな異常な実行計画は見つからない)場合、またはトランザクションが長時間コミットできない場合。この場合、一般的に以下のような状況に分類されます:
実行中のセッションリクエストを確認し、業務情報と組み合わせてトランザクションの実行状況を判断します。この時、よく見られるのはOBserverノードの異常、例えばI/O/メモリ/ネットワークの異常です。まずは疑わしいノードを隔離して回復可能かどうかを観察し、その後具体的な異常に対してダウングレード処理を行います。詳細については、その他のハードウェア・ネットワーク関連の問題を参照してください。
ハードウェアに明確な問題は見つからないものの、ノードのI/O負荷が非常に高い、またはNIC負荷が高すぎるため、SQLリクエストがタイムアウトする場合。この場合の処理方法は、ノードNIC負荷が高すぎるおよびノードI/O負荷が高すぎるを参照してください。
また、SQLクエリ時間が異常になるもう一つのケースとして、LSM-Tree系アーキテクチャのデータベース特有の現象があり、OceanBaseでは「bufferテーブル問題」と呼ばれています。詳細については、bufferテーブルを参照してください。
データベースノードのCPU/メモリ容量が不足している場合、CPU不足によりテナントキューが滞り、メモリが上限になると書き込みに失敗します。これにより、SQLのRTが増加します。
この場合、まずCPU使用率とテナントメモリ使用率を確認し、必要に応じてスケールアップやその他の対応策を講じることを推奨します。詳細については、テナントリクエストキューの滞りおよびテナントメモリの上限を参照してください。
アプリケーションの接続確立失敗
アプリケーションの接続作成に失敗する場合、一般的には2つのケースがあります。1つはobproxyへの接続作成に失敗する場合、もう1つはobserverへの接続作成に失敗する場合です。直接の接続確立失敗よりも、接続タイムアウトの方がより一般的です。
obproxyへの接続作成に失敗する場合
アプリケーションからobproxyへの接続作成に失敗した場合、まずアプリケーションからobproxyへのネットワーク経路の問題を除外する必要があります。次に、obproxyの上位でロードバランシングデバイスやコンポーネントが設定されているかどうか、また障害が存在しないかどうかを調査します。これら2つのケースを除外した後、obproxy自体の障害や、トラフィックの増加によりobproxyのスレッドが使い果たされる(エラーメッセージは
too many sessionsなど)可能性があります。この場合の対処方法については、ODP側の障害およびODPスレッド上限を参照してください。observerへの接続作成に失敗する場合
observerへの接続作成に失敗する問題について、まず迅速に除外すべきものもネットワーク障害、つまりobproxyからobserverへの経路です。インフラが安定している環境では、ネットワーク回線の問題が発生する可能性は実際には低く、明確な指標がネットワーク問題を示していない限り、あまり時間をかけて分析する必要はありません。より一般的なのは、observer自体の接続に問題が発生している場合です。この場合、以下のいくつかの方法で分析と特定を行うことができます:
sysテナントまたはその他の内部テナントにキューの積み残しがないかどうかを確認します。observerログを確認して、SYSキューに積み残しがないかどうかを判断します。OceanBaseクラスタは接続作成を最初にsysテナントで処理するため、問題が発生すると接続失敗につながります。対処方法については、SYSテナント/RSサービスの問題を参照してください。
ノードのCPU/IOが急激に上昇していないかどうかを確認します。observerログを確認して、ユーザーテナントのキューに積み残しがないかどうかを判断します。ユーザーテナントのリソース不足も接続タイムアウトを引き起こす可能性があります。対処方法については、テナントリクエストキューの積み残しを参照してください。
異常なSQLによるリソース占有問題については、調査の考え方の詳細はSQLクエリによる異常を参照してください。
アプリケーションの書き込み失敗
OceanBaseの書き込み関連の問題はいくつかの大きなカテゴリに分類され、その多くがメモリと直接関係しています。実際の本番環境では、発生頻度に基づいて以下の観点から分析・診断することができます:
短時間に大量の書き込み操作(例えば、一括インポート、訂正版、削除操作など)により、ユーザーテナントのメモリが上限になる。
これが最も一般的なケースであり、エラーメッセージは通常
Over tenant memory limitsとして表示されます。OceanBaseはLSM-Tree構造に基づく準メモリデータベースであり、あらゆる書き込み操作にはメモリリソースが消費されます。一定のしきい値に達すると、ダンプ/コンパクションが完了して初めて解放されます。したがって、ダンプ速度がメモリの消費速度に追いつかない場合、最終的にメモリが枯渇し、アプリケーションの書き込みがゼロになることがあります。このような場合の対処方法の詳細については、テナントメモリが上限になるを参照してください。長時間にわたるトランザクションや、一時停止したトランザクションによりダンプがスタックし、メモリが解放されず、結果としてメモリが上限になる。
同じくメモリが上限になるケースとして、コミットされていないトランザクションが存在するため、アクティブなメモリがフリーズされず、ダンプされないことでメモリが爆発的に増加する場合もあります。長時間終了しないステートメントを確認するか、コマンドラインSQLを使用して実行中の長時間トランザクションを判断することができます。
テナント内部の他のモジュールがメモリを過剰に占有し、MemStoreが割り当てられず、結果としてメモリが上限になる。
この場合、書き込み量が多すぎることによるMemStoreのメモリ上限ではなく、他のSQL問題によって引き起こされるテナントの非MemStoreモジュールのメモリ問題です。このときの現象は、テナントのMemStoreメモリ占有率がそれほど高くないにもかかわらず、書き込み時にエラーが発生します。システムメモリ不足/リークを参照してください。
clogログディスクが上限になり、paxosの多数派が同期できず、パーティションに主が存在せず、業務が書き込めない。
clogはOceanBaseのトランザクションログであり、同様にWALメカニズムを採用しています。ディスクが上限になると、書き込みのコミットに失敗します。対処方法については、ノードログディスク容量上限を参照してください。
システムRSモジュールに異常が発生し、コンパクションのフリーズがスタックし、その間書き込みができない。
このようなケースは比較的まれですが、OceanBaseは書き込みダンプが一定のしきい値に達した後、または毎日のコンパクション前に、まず大規模バージョンのフリーズ操作を実行します。これは、アクティブなメモリをフリーズした上で、ダンプ/コンパクションを行うというものです。通常、フリーズ操作は1秒以内に完了しますが、異常時にはより長くなる可能性があり、その間ユーザーは書き込みできません。このような緊急時の対処方法としては、手動でRSを切り替えるか再起動することが挙げられます。SYSテナント/RSサービスの問題を参照してください。
アプリケーションのロック競合
特定の行に対して並行更新が行われるようなシナリオでは、行ロックの競合が容易に発生し、各リクエストの待機時間が長くなる可能性があります。さらに、アプリケーション接続プールの上限という問題にも波及する可能性があります。ロック競合は一般的に以下のような状況で発生します:
ビジネス側のSQL RTが上昇し、行ロックが解放されなくなり、ロック競合がRTの上昇によって引き起こされる。この場合、RTの上昇という根本的な問題を解決する必要があります。詳細については、上記のアプリケーション接続プール上限/アプリケーションリクエストタイムアウトの項を参照してください。
行にコミットされていないトランザクションや、一時停止したトランザクションが存在する。
ホットスポット行の並行処理によるロック競合が発生し、それが逆にRTの上昇を引き起こす。
ホットスポット行の更新はリレーショナルデータベースに共通する問題であり、緊急時には特に有効な対策がない場合が多い(ビジネス形態によるもので、一般的には制限やダウングレードを検討します)。長期的な最適化の観点から見ると、トランザクションロジックの最適化調整(例えばselect for update wait 1のような方法)を検討することができます。OceanBaseはホットスポットの並行処理に関して積極的に取り組んでおり、すでに効果的な最適化策を実装しています。詳細については、OceanBaseデータベースの事前行ロック解除機能を参照してください。これにより、単一行の並行処理性能が向上します。
変更の実施・ロールバックと注意点
前章の分析を通じて、一般的な緊急事態への対処について一定の理解が得られたと思います。残りは対応する緊急措置を実行し、データベースの正常な動作を回復させることです。OceanBaseの緊急時対応においては、特に以下の点に注意が必要です:
発行された各緊急変更操作を明確に記録し、レビューすることで、復旧に失敗した場合のさらなる診断のための参考情報とします。
異常期間中のobserverログやcoreファイルなど、可能な限り現場情報を記録することを推奨します。
本章で説明する緊急復旧操作は、クラスタデータの多数派を破壊せず、データの一貫性を保証することを前提としています。複数レプリカの障害に遭遇し、単一レプリカをアクティブ化したり、複数レプリカのclogを処理したりする必要がある場合は、OceanBaseテクニカルサポートまでご連絡ください。
緊急措置の実行が完了し、業務が止まることなく回復した後は、一部のパラメータ設定の変更をロールバックし、問題や障害について振り返ることを推奨します。緊急時に保持された現場情報に基づき、問題の根本原因の特定作業を開始することができます。