データベースは運用中にさまざまな異常が発生することがあります。例えば、アプリケーションエラー、データベース接続エラー、データベース権限問題、データベースリソース問題、ネットワーク問題などです。これらすべての状況の中で、アプリケーションの接続切断というケースも存在します。
皆様がこのようなシナリオでの問題の根本原因を迅速に特定し、効率的に解決できるよう支援するため、ここでは明確で実用的なアプリケーション接続切断問題のトラブルシューティングプロセスをまとめました。このプロセスは、明確な操作手順を提供し、問題処理の効率を向上させ、業務への影響を最小限に抑えることを目的としており、日常的な運用保守作業を強力にサポートします。
プロセスの紹介
アプリケーションが接続を切断した場合、このプロセスに従って問題のトラブルシューティングを行うことができます。
まず、ユーザーが使用しているアプリケーション開発言語を判断する必要があります。
Java言語
アプリケーション開発言語がJavaであることを確認した場合、Javaアプリケーションのエラーログを確認することで、現在のアプリケーション接続切断の原因を判断できます。方法は以下の通りです。
エラーログに
Communications link failure例外が含まれているかどうかを確認します。Javaアプリケーションのエラーログに
Communications link failure例外が含まれていない場合、そのシナリオを再現してみてください:- 再現できる場合、再現後にプログラムコードデバッグやネットワークパケットキャプチャ分析などの手段を用いて、プログラムコードのエラー原因を分析できます。
- 再現できない場合、既存の情報とプログラム自体のロジックを組み合わせて、エラー原因を推測してみてください。
Javaアプリケーションのエラーログに
Communications link failure例外が含まれている場合、次のステップを実行します。
例外ログの
Caused by部分に対応する情報を確認します。この部分の情報が出力されていない場合、スタックトレースが不完全であり、原因を判断できません。アプリケーションが完全なスタックトレースを出力した後に問題を再現し、さらに分析する必要があります。
この部分の情報が出力されている場合、
Caused by部分の出力情報に基づいて、接続切断の原因を判断できます:内容が
Connection reset"、"can not read response from server. Expected to read 4 bytes,read 0 bytes before connection was unexpectedly lostまたはunexpected end of stream, read XXX bytes from xxx (socket was closed by server)の場合、アプリケーション側の接続が切断されたことを意味します。エラー情報に基づいてさらに原因を判断する必要があります。具体的な判断方法については、本記事のアプリケーション側の接続が切断された場合の内容を参照してください。内容が
read timed out"または"Connection timed out (Read failed)の場合、遅延SQLがアプリケーションで設定されたsocketTimeout時間を引き金として、プログラム側の接続が切断されたことを意味します。この場合、異常SQLが遅延SQLに該当するかどうかを判断する必要があります。遅延SQLに該当する場合は、状況に応じてSQLを最適化できます。現在遅延SQLが存在しない場合は、socketTimeoutの調整を検討できます。具体的な調整方法については、データベース接続プールの設定を参照してください。内容が
connect timed outまたはConnection timed out: connectの場合、TCPハンドシェイクに失敗し、アプリケーションがアクセスしようとしている宛先アドレスと宛先ポートに到達できないことを意味します。これは、ネットワーク不通またはプログラムのIPアドレスやポート設定が誤っている可能性があります。内容が
Connection refusedの場合、接続に失敗したことを意味します。アプリケーションがアクセスしようとしている宛先アドレスと宛先ポートには到達できますが、何らかのシステムまたはネットワーク上の理由により接続が拒否されました。
C言語
アプリケーション開発言語がCであることを確認した場合、C言語のアプリケーションエラーログを確認することで、現在のアプリケーション接続切断の原因を判断できます。
エラー情報が
end-of-file on communication channelまたはLost connection to MySQL server during query例外である場合、アプリケーション側の接続が切断されたことを意味します。エラー情報に基づいてさらに原因を判断する必要があります。具体的な判断方法については、本記事のアプリケーション側の接続が切断された場合の内容を参照してください。エラー情報が
reading initial communication packetまたはreading authorization packet例外である場合、データベースへの接続に失敗したことを意味します。失敗原因はネットワーク問題である可能性もあれば、バックエンドのOceanBaseデータベースサービスの問題である可能性もあります。ログ分析を組み合わせる必要があり、場合によってはパケットキャプチャによる判断も必要です。アプリケーションログに明らかな例外情報がない場合、現在のシナリオを再現してみてください。
- 再現できる場合、プログラムコードデバッグやネットワークパケットキャプチャ分析などの手段を用いて、プログラムコードのエラー原因を分析できます。
- 再現できない場合、既存の情報とプログラム自体のロジックを組み合わせて、エラー原因を推測してみてください。
アプリケーション側での接続が切断された場合
アプリケーション側での接続が切断されたと判断された場合、ログ情報に conn id の識別子が含まれているか、または例外時に実行されたSQLが出力されているかどうかを確認します。いずれもない場合は、重要な情報が不足しているため、アプリケーション側に連絡し、より多くの情報を取得して診断する必要があります。ログ情報に上記のいずれかの情報が出力されている場合は、現在のプログラムで設定されているデータソース情報を明確にし、以下の手順に従って処理します。
データソースに基づいてアクセスチェーンを明確にします。アクセスチェーンには、以下の情報が含まれるアドレスの数が含まれます。
OBProxyの数とアドレス情報
OBServerホストの数とアドレス情報
現在のアクセスチェーンを判断し、アプリケーションがOBProxyを経由しているかどうかを確認します。
アプリケーションがOBProxyを介してデータベースに接続
sshコマンドを使用して、対応するOBProxyノードにログインします。psコマンドを実行して、obproxyプロセスの起動時間を確認します。例外期間中にアプリケーションが再起動したかどうかを判断します。
再起動した場合、これはOBProxyの再起動による例外であることを意味します。
再起動していない場合は、次のステップに進みます。
再起動していない場合は、
cdコマンドを使用して、OBProxyのログディレクトリに移動します。OBProxyのログは、そのインストールディレクトリの/logディレクトリに保存されています。conn_idがあるかどうかを確認します。ない場合は、例外関連のSQLテキストがあるかどうかを確認します。いずれもない場合は、アプリケーション側に連絡して、より多くの情報を取得する必要があります。conn_idがある場合は、conn_idを以下のコマンドに代入して実行し、例外期間中のobproxyログをフィルタリングします。grep "xxxxxx" obproxy.logxxxxxを実際のconn_id情報に置き換える必要があります。例外関連のSQLテキストがある場合は、SQLテキストの一部の文字を以下のコマンドに代入して実行し、例外期間中のobproxyログをフィルタリングします。
grep "エラーテキスト" obproxy.log.xxxx | grep "エラー発生時点"grep "エラーテキスト" obproxy_error.log.xxxx | grep "エラー発生時点"
フィルタリングされたログエントリに基づいて、例外期間中のpbproxyの
trace_idを見つけます。trace_idを以下のコマンドに代入して実行し、例外期間中のobproxyログをフィルタリングします。grep "xxxxxx" obproxy.log.xxxx | grep "エラー発生時点"xxxxxを実際のtrace_id情報に置き換える必要があります。obproxyログの出力に基づいて、接続切断状況を判断します。
obproxyが積極的に接続を切断した場合は、フィルタリングされたログに基づいて切断原因を分析し、必要に応じてobproxyのソースコードと組み合わせて分析します。
接続がobserverによって切断され、アプリケーションの接続が切断された場合は、obproxyログエントリに基づいて、切断時の接続OBServerノードおよびobserverのsession_idを見つけ、以下の アプリケーションがSSHを使用して対応するOBServerノードに直接ログインする の内容を参照して、次の診断分析を行います。
アプリケーションサーバーとobproxyの間のネットワーク機器(例えば、F5、SLB、その他のネットワーク機器など)によって接続が切断された場合は、アプリケーションとobproxyの間のネットワーク機器を調査する必要があります。
アプリケーションがSSHを使用して対応するOBServerノードに直接ログイン
sshコマンドを使用して、対応するOBServerノードにログインします。psコマンドを実行して、observerプロセスの起動時間を確認します。例外期間中にアプリケーションが再起動したかどうかを判断します。
再起動した場合、これはOBServerノードの再起動による例外であることを意味します。
再起動していない場合は、次のステップに進みます。
再起動していない場合は、
cdコマンドを使用して、ログが存在するディレクトリに移動します。以下はOceanBaseデータベースのインストールディレクトリが
/home/admin/oceanbaseである場合の例です。ログの具体的な保存パスは、実際の環境に基づいてください。cd /home/admin/oceanbase/log以下のコマンドを実行して、
session id関連のログをフィルタリングします。grep "observer session id" observer.loggrep "observer session id" observer.log.xxxフィルタリングされたログに基づいて、接続状況を判断します。
- 接続がobserverによって積極的に切断された場合は、フィルタリングされたログに基づいて切断原因を分析し、必要に応じてobserverのソースコードと組み合わせて分析します。
- 接続がobproxyとobserverの間のネットワーク機器によって切断された場合は、obproxyとobserverの間のネットワーク機器の使用状況を調査する必要があります。
よくあるケース
本番環境において、
read time outエラーにより業務トランザクションがタイムアウトする。アイドルタイムアウトが原因で、アプリケーションの接続が定期的に切断される。
ODP-Sharding を使用して OceanBase Database に接続する際、
Server connection execute error: Read timed outエラーが発生する。OceanBase Database でのコミット処理中に、
Transaction resolution unknownエラーが返される。obproxy 経由または OceanBase Database への直接接続時に、
Access denied for user 'xxxx'@'xxxx' (using password: YES)エラーが返される。OceanBase Database の一般テナントに直接接続する際、
ERROR 5150 (HY000): Tenant not in this serverエラーが返される。OceanBase Database V4.x の OBServer ノードに接続する際、
unexpected end of stream, read 0 bytes from 4エラーが稀に発生する。
クライアントが SQL 文を実行した際、
Lost connection to MySQL server during queryエラーが直ちに返される。このエラーは通常、サーバー側の例外によって接続が遮断された場合に発生します。MySQL モードで OceanBase Database に接続している際、接続が切断され
ERROR 2013が返される。