増加した読み取りおよび書き込み遅延のトラブルシューティング
このドキュメントでは、読み取りと書き込みのレイテンシーとジッターの考えられる原因と、これらの問題のトラブルシューティング方法を紹介します。
一般的な原因
TiDB 実行計画が正しくない
クエリの実行計画は不安定であり、不適切なインデックスを選択する可能性があり、これによりレイテンシーが高くなります。
現象
- クエリ実行プランがスローログに出力されている場合は、プランを直接表示できます。
select tidb_decode_plan('xxx...')
ステートメントを実行して、詳細な実行計画を解析します。 - モニター内のスキャンされたキーの数が異常に増加します。スローログでは
Scan Keys
の数が多い。 - TiDB での SQL 実行時間は、MySQL などの他のデータベースとは大きく異なります。他のデータベースの実行計画を比較できます (たとえば、
Join Order
が異なるかどうか)。
考えられる理由
統計は不正確です。
トラブルシューティング方法
- 統計情報の更新
analyze table
手動で実行し、analyze
crontab
コマンドで定期的に実行して、統計を正確に保ちます。auto analyze
を自動的に実行します。analyze ratio
のしきい値を下げ、情報収集の頻度を増やし、実行の開始時刻と終了時刻を設定します。次の例を参照してください。set global tidb_auto_analyze_ratio=0.2;
set global tidb_auto_analyze_start_time='00:00 +0800';
set global tidb_auto_analyze_end_time='06:00 +0800';
- 実行計画をバインドする
- アプリケーション SQL ステートメントを変更し、
use index
を実行して、列のインデックスを一貫して使用します。 - バージョン 3.0 では、アプリケーション SQL ステートメントを変更する必要はありません。
create global binding
を使用して、force index
のバインディング SQL ステートメントを作成します。 - バージョン 4.0 では、不安定な実行計画によるパフォーマンスの低下を回避するSQL計画管理がサポートされています。
- アプリケーション SQL ステートメントを変更し、
PD異常
現象
PD TSO のwait duration
メトリックの異常な増加があります。このメトリクスは、PD がリクエストを返すまでの待機時間を表します。
考えられる理由
ディスクの問題。 PD ノードが配置されているディスクの I/O 負荷が最大になっています。 I/O 要求が高く、ディスクの状態が良好な他のコンポーネントと共に PD が展開されているかどうかを調査します。 Grafana -> disk performance -> レイテンシー / loadでモニター メトリックを表示することで、原因を確認できます。必要に応じて、FIO ツールを使用してディスクのチェックを実行することもできます。
PD ピア間のネットワークの問題。 PD ログには
lost the TCP streaming connection
が表示されます。 PD ノード間のネットワークに問題があるかどうかを確認し、モニターGrafana -> PD -> etcdでround trip
表示して原因を確認する必要があります。サーバーの負荷が高い。ログには
server is likely overloaded
表示されます。PD がLeaderを選出できない: PD ログは
lease is not expired
を示します。 v3.0.x と v2.1.19 でこの問題が修正されました。リーダーの選挙は遅いです。リージョンの読み込み時間が長い。 PD ログで
grep "regions cost"
を実行すると、この問題を確認できます。結果がload 460927 regions cost 11.77099s
などの秒単位の場合、リージョンの読み込みが遅いことを意味します。use-region-storage
をtrue
に設定することで v3.0 のregion storage
機能を有効にできます。これにより、リージョンの読み込み時間が大幅に短縮されます。TiDB と PD 間のネットワークの問題。モニターGrafana -> blackbox_exporter -> ping レイテンシーにアクセスして、TiDB から PDLeaderへのネットワークが正常に動作しているかどうかを確認します。
PD は
FATAL
エラーを報告し、ログにはrange failed to find revision pair
が表示されます。この問題は v3.0.8 ( #2040 ) で修正されています。/api/v1/regions
インターフェイスを使用する場合、リージョンが多すぎると PD OOM が発生する可能性があります。この問題は v3.0.8 で修正されています ( #1986 )。ローリング アップグレード中の PD OOM。 gRPC メッセージのサイズは制限されておらず、モニターは
TCP InSegs
が比較的大きいことを示しています。この問題は v3.0.6 で修正されています ( #1952 )。PDパニック。 バグを報告 .
その他の原因。
curl http://127.0.0.1:2379/debug/pprof/goroutine?debug=2
とバグを報告を実行してゴルーチンを取得します。
TiKVの異常
現象
モニターのKV Cmd Duration
メトリックが異常に増加します。このメトリクスは、TiDB が TiKV にリクエストを送信してから TiDB がレスポンスを受信するまでの時間を表します。
考えられる理由
gRPC duration
メトリックを確認します。このメトリクスは、TiKV での gRPC リクエストの合計時間を表します。 TiKV のgRPC duration
TiDB のKV duration
を比較することで、潜在的なネットワークの問題を見つけることができます。たとえば、gRPC 期間は短いが、TiDB の KV 期間が長い場合、TiDB と TiKV の間のネットワークレイテンシーが高い可能性があるか、TiDB と TiKV の間の NIC 帯域幅が完全に占有されている可能性があることを示しています。TiKV再始動のため再選。
- TiKV がパニックした後、
systemd
でプルアップされ、正常に実行されます。panicが発生したかどうかは、TiKV ログを表示することで確認できます。この問題は予期しないものであるため、発生した場合はバグを報告 。 - TiKV は第三者によって停止または強制終了され、その後
systemd
によって引き上げられました。dmesg
と TiKV ログを参照して原因を確認してください。 - TiKV は OOM であり、再起動を引き起こします。
THP
(Transparent Hugepage) を動的に調整するため、TiKV がハングします。
- TiKV がパニックした後、
チェック モニター: TiKV RocksDB で書き込みストールが発生し、再選択されます。モニターGrafana -> TiKV-details -> errors が
server is busy
示しているかどうかを確認できます。ネットワーク分離による再選。
block-cache
構成が大きすぎると、TiKV OOM が発生する可能性があります。問題の原因を確認するには、モニターGrafana -> TiKV-detailsで該当するインスタンスを選択して、RocksDB のblock cache size
を確認します。その間、パラメータ[storage.block-cache] capacity = # "1GB"
が正しく設定されているかどうかを確認します。デフォルトでは、TiKV のblock-cache
マシンの合計メモリの45%
に設定されています。 TiKV はコンテナーのメモリ制限を超える可能性がある物理マシンのメモリを取得するため、コンテナーに TiKV をデプロイするときに、このパラメーターを明示的に指定する必要があります。コプロセッサー は多数の大きなクエリを受け取り、大量のデータを返します。 gRPC は、コプロセッサがデータを返すのと同じ速さでデータを送信できず、OOM が発生します。原因を確認するには、モニターGrafana -> TiKV-details -> coprocessor overviewを表示して、
response size
network outbound
トラフィックを超えているかどうかを確認できます。
シングル TiKV スレッドのボトルネック
TiKV には、ボトルネックになる可能性のあるシングル スレッドがいくつかあります。
- TiKV インスタンス内のリージョンが多すぎると、単一の gRPC スレッドがボトルネックになります ( Grafana -> TiKV-details -> Thread CPU/gRPC CPU Per Threadメトリックを確認してください)。 v3.x 以降のバージョンでは、
Hibernate Region
有効にして問題を解決できます。 - v3.0 より前のバージョンでは、raftstore スレッドまたは適用スレッドがボトルネックになる場合 ( Grafana -> TiKV-details -> Thread CPU/raft store CPUおよびAsync apply CPUメトリクスが
80%
を超える)、TiKV (v2 .x) インスタンスまたはマルチスレッドで v3.x にアップグレードします。
CPU 負荷が増加する
現象
CPU リソースの使用量がボトルネックになります。
考えられる理由
- ホットスポットの問題
- 全体的な負荷が高い。 TiDB の遅いクエリと高価なクエリを確認します。インデックスを追加するか、バッチでクエリを実行することにより、実行中のクエリを最適化します。もう 1 つの解決策は、クラスターをスケールアウトすることです。
その他の原因
クラスタのメンテナンス
各オンライン クラスタのほとんどには、3 つまたは 5 つのノードがあります。保守対象のマシンに PDコンポーネントがある場合、ノードがリーダーかフォロワーかを判断する必要があります。フォロワーを無効にしても、クラスターの操作には影響しません。リーダーを無効にする前に、リーダーを切り替える必要があります。リーダー交代中は、約3秒のパフォーマンスの揺れが発生します。
少数のレプリカがオフライン
デフォルトでは、各 TiDB クラスターには 3 つのレプリカがあるため、各リージョンにはクラスター内に 3 つのレプリカがあります。これらのリージョンはリーダーを選出し、 Raftプロトコルを介してデータをレプリケートします。 Raftプロトコルは、ノード (レプリカの半分未満) が故障したり分離されたりした場合でも、TiDB がデータ損失なしでサービスを提供できることを保証します。 3 つのレプリカを持つクラスターの場合、1 つのノードの障害によってパフォーマンスのジッターが発生する可能性がありますが、理論上の使いやすさと正確性には影響しません。
新しいインデックス
インデックスを作成すると、TiDB がテーブルをスキャンしてインデックスをバックフィルするときに、大量のリソースが消費されます。インデックスの作成は、頻繁に更新されるフィールドと競合することさえあり、アプリケーションに影響を与えます。大規模なテーブルでのインデックスの作成には時間がかかることが多いため、インデックスの作成時間とクラスターのパフォーマンスのバランスを取るようにする必要があります (たとえば、オフピーク時にインデックスを作成するなど)。
パラメータ調整:
現在、 tidb_ddl_reorg_worker_cnt
とtidb_ddl_reorg_batch_size
を使用して、インデックス作成の速度を動的に調整できます。通常、値が小さいほど、システムへの影響は小さくなりますが、実行時間は長くなります。
一般的なケースでは、最初にデフォルト値 ( 4
および256
) を維持し、クラスターのリソース使用率と応答速度を観察してから、値tidb_ddl_reorg_worker_cnt
を増やして同時実行性を高めることができます。モニターに明らかなジッターが見られない場合は、値tidb_ddl_reorg_batch_size
を増やします。インデックスの作成に関係する列が頻繁に更新される場合、多くの競合が発生するため、インデックスの作成が失敗し、再試行されます。
さらに、 tidb_ddl_reorg_priority
~ PRIORITY_HIGH
の値を設定して、インデックスの作成を優先し、プロセスを高速化することもできます。ただし、一般的な OLTP システムでは、デフォルト値を維持することをお勧めします。
高 GC 圧力
TiDB のトランザクションは、Multi-Version Concurrency Control (MVCC) メカニズムを採用しています。新しく書き込まれたデータが古いデータを上書きする場合、古いデータは置き換えられず、両方のバージョンのデータが保存されます。タイムスタンプは、異なるバージョンをマークするために使用されます。 GC のタスクは、古いデータを消去することです。
- Resolve Locks のフェーズでは、大量の
scan_lock
リクエストが TiKV で作成されます。これは gRPC 関連のメトリックで確認できます。これらscan_lock
リクエストは、すべてのリージョンを呼び出します。 - 範囲の削除のフェーズでは、いくつかの (またはまったくない)
unsafe_destroy_range
リクエストが TiKV に送信されます。これは、gRPC 関連のメトリックとGC タスクパネルで確認できます。 - Do GC のフェーズでは、デフォルトで各 TiKV がマシン上のリーダー リージョンをスキャンし、各リーダーに対して GC を実行します。これはGC タスクパネルで確認できます。