ODPは、パフォーマンスボトルネックを特定するために豊富な内部テーブルとシステムログを提供しており、主に監査ログ、スロークエリログ、統計ログを通じてODPの動作を分析します。
ODP側でよく見られる問題は、主に以下のカテゴリに分類されます:

その中で:
接続失敗
アプリケーションシステムがOBServerへの接続に失敗したことを示します。これは、バックエンドのデータベースシステムがリクエストによってパンクし、接続の確立に失敗したことによる場合もあれば、アプリケーションシステム自体の問題(例えば、fullgcが発生した場合、アプリケーションサーバーのNIC異常、アプリケーション層のデータベース設定エラーなど)、またはアプリケーションサーバーとOBServer間のネットワーク異常などによって引き起こされる場合もあります。この種のエラーメッセージは、アプリケーション側、ODP側、OBServer側のいずれでも発生する可能性があります。
SQL実行の問題
エラー返却:バックエンドのデータベースシステムが明確なエラーコードを返したことを示します。OBServer側で調査する必要があります。
実行遅延:まず、時間消費がどのコンポーネントにかかっているかを特定し、さらに詳しく調査する必要があります。
接続切断:まず、どのコンポーネントが積極的に接続を切断したかを特定し、さらに詳しく調査する必要があります。
ODPは、問題の調査に使用できる豊富なログを提供しています。
エラーログ
ファイル名は
obproxy_error.logで、エラーログには実行エラーのリクエストが記録されます。これには、ODP自身のエラーとOBServerからのエラーが含まれます。監査ログ
ファイル名は
obproxy_digest.logで、監査ログには実行時間がパラメータquery_digest_time_thresholdのしきい値(デフォルトは100ms)を超えるリクエストとエラー応答リクエストが記録されます。説明
query_digest_time_thresholdはリクエスト実行時間のしきい値を設定するために使用され、しきい値を超えるとobproxy_digest.logファイルにログが出力されます。値の範囲は [0s, 30d] です。スロークエリログ
ファイル名は
obproxy_slow.logで、スロークエリログには実行時間がslow_query_time_thresholdのしきい値(デフォルトは500ms)を超えるリクエストが記録されます。説明
slow_query_time_thresholdスロークエリの実行時間しきい値です。しきい値を超えるとobproxy_slow.logファイルにログが出力されます。値の範囲は [0s, 30d] です。統計ログ
ファイル名は
obproxy_stat.logで、統計ログはデフォルトで毎分(monitor_stat_dump_intervalパラメータで制御)出力されます。このログを通じて、ODPの1分間のSQLの実行状況を確認できます。メインログ
ファイル名は
obproxy.logで、DEBUG、TRACE、INFO、ERRORの4つのレベルがあり、syslog_levelパラメータで制御されます。さらに問題の原因を調査する必要がある場合、trace_idフィールドを使用して、あるセッション上のすべてのログをフィルタリングできます。
メインログに記録される情報は非常に詳細であり、スローSQLに関するキーワードはSlow Queryです。メインログには、各サブステージの時間消費が記録されています。例えば:
[2022-07-11 14:32:51.758195] WARN [PROXY.SM] update_cmd_stats (ob_mysql_sm.cpp:8425) [74744][Y0-7F4B1CEA13A0] [lt=7] [dc=0] Slow Query: ((
client_ip={127.0.0.1:50422}, // SQLを送信するクライアントのアドレス
server_ip={xx.xx.xx.xx:33041}, // SQLがルーティングされるターゲットOBServer
obproxy_client_port={xx.xx.xx.xx:52052}, // OBServerに接続するローカルアドレス
server_trace_id=Y81100B7C0535-0005E3460FBBE3CD-0-0, // ターゲットOBServer内での実行プロセス中のtrace id
route_type=ROUTE_TYPE_NONPARTITION_UNMERGE_LOCAL, // SQLが使用するルーティングポリシー
user_name=root, // ユーザー名
tenant_name=sys, // テナント名
cluster_name=ob9988.zhixin.lm.100.xx.xx.xx, // クラスタ名
logic_database_name=, // ロジックデータベース名
logic_tenant_name=, // ロジックテナント名
ob_proxy_protocol=0, // プロトコルタイプ
cs_id=14, // client login時に表示されるconnection id、proxyが割り当てる
proxy_sessid=7230691598940700681, // clientがOBServerにアクセスする際の内部記録connection id
ss_id=21,
server_sessid=3221588238, // SQLがターゲットOBServer内のconnection id、OBServerが割り当てる
sm_id=14,
cmd_size_stats={
client_request_bytes:20, // clientがproxyに送信するリクエストパケットのサイズ
server_request_bytes:38, // ODPがターゲットOBServerに送信するリクエストパケットのサイズ
server_response_bytes:0, // ターゲットOBServerがproxyに送信する応答パケットのサイズ
client_response_bytes:71}, // ODPがclientに送信する応答パケットのサイズ
cmd_time_stats={
client_transaction_idle_time_us=0, // トランザクション内でこのSQLと前のSQLの実行終了間の間隔時間、すなわちclientトランザクション間隔時間
client_request_read_time_us=97, // ODPがclientソケットからリクエストパケットを読み取る時間消費
client_request_analyze_time_us=95, // ODPがclientのSQLを分析する時間消費
cluster_resource_create_time_us=0, // ODPがクラスタリソースを作成する時間消費(クラスタへの初回アクセス時のみ必要)
pl_lookup_time_us=0, // SQLに基づいてルーティングテーブルに関連する時間消費
pl_process_time_us=0, // ルーティングテーブルに関連するものをフィルタリング・ソートする時間消費
congestion_control_time_us=21, // SQLに基づいてブラックリスト情報に関連する時間消費
congestion_process_time_us=3, // ブラックリストに関連するものをチェック・フィルタリングする時間消費
do_observer_open_time_us=55, // ターゲットOBServerから利用可能な接続を取得する時間消費、connect_timeを含む
server_connect_time_us=0, // ターゲットOBServerで接続を作成する時間消費
server_sync_session_variable_time_us=0, // 選択したターゲット接続を初期化する時間消費、saved_login、db同期、システム変数同期、last_insert_id同期、start_trans同期を含む
server_send_saved_login_time_us=0, // 選択したターゲット接続でsaved loginにかかる時間消費
server_send_use_database_time_us=0, // 選択したターゲット接続でdb同期にかかる時間消費
server_send_session_variable_time_us=0, // 選択したターゲット接続で変更されたシステム変数を同期する時間消費
server_send_all_session_variable_time_us=0, // 選択したターゲット接続ですべてのシステムを同期する時間消費
server_send_last_insert_id_time_us=0, // 選択したターゲット接続でlast_insert_idを同期する時間消費
server_send_start_trans_time_us=0, // 選択したターゲット接続でstart_trans/beginを同期する時間消費
build_server_request_time_us=23, // ターゲットserverに対するリクエストパケットを構築する時間消費
plugin_compress_request_time_us=0, // リクエストパケットを圧縮する時間消費
prepare_send_request_to_server_time_us=409, // ODPがクライアントリクエストを受信してからOBServerに転送して実行するまでの合計時間、通常は前述のすべての時間の合計であるはず
server_request_write_time_us=32, // ODPがターゲットserverソケットにリクエストパケットを送信する時間消費
server_process_request_time_us=3039883, // ターゲットserverがこのSQLを実行する時間消費
server_response_read_time_us=67, // ODPがターゲットserverソケットから応答パケットを読み取る時間消費
plugin_decompress_response_time_us=59, // 応答パケットを解凍する時間消費
server_response_analyze_time_us=70, // 応答パケットを分析する時間消費
ok_packet_trim_time_us=0, // 応答パケットから最後のokパケットをトリムする時間消費
client_response_write_time_us=185, // ODPがclientソケットに応答パケットを送信する時間消費
request_total_time_us=3041116}, // ODPがこのリクエストを処理する合計時間、前述のすべての時間消費の合計に等しい
sql=select sleep(3) //clientのリクエストSQL
)
ここで、request_total_time_us はODPがこのリクエストを処理するための合計時間を記録し、server_process_request_time_us はODPがOBServerに送信するリクエストの時間消費を記録します。これには、ネットワーク時間とOBServer処理時間が含まれます。このログを通じて、スローSQLの各ステージの時間消費を特定できるため、スローSQLの問題をより容易に特定できます。