このトピックでは、Hologres のメトリックに関するよくある質問への回答を提供します。
Connections メトリックの値が大きい場合、接続を表示して閉じるにはどうすればよいですか?
Connections メトリックは、アクティブ状態とアイドル状態の PostgreSQL データベースへの Java Database Connectivity(JDBC)接続を含む、Hologres インスタンスへの SQL 接続の総数を示します。インスタンスへの接続数は、インスタンスタイプによって異なります。インスタンスへの接続数が多い場合、またはインスタンスに許可されている最大接続数を超えている場合、あるいは次のいずれかのエラーが報告された場合は、接続リークが発生しているかどうかを確認する必要があります。
FATAL: sorry, too many clients already connection limit exceeded for superusers
FATAL: remaining connection slots are reserved for non-replication superuser connections
これらのエラーは、インスタンスへの接続数が上限に達していることを示しています。HoloWeb コンソールで、または SQL ステートメントを実行することで、現在の接続に関する情報を取得できます。詳細については、「接続の管理」をご参照ください。スーパーユーザーアカウントを使用して、予期しない接続またはアイドル状態の接続を閉じることができます。
クエリのレイテンシが高いです。問題のトラブルシューティングを行うにはどうすればよいですか?
クエリのレイテンシが高い原因として、次のことが考えられます。スロークエリログをクエリすることで、対応する遅い SQL クエリを見つけることができます。詳細については、「スロークエリログのクエリと分析」をご参照ください。
原因 1:1 秒あたりのクエリ数(QPS)は少ないが、SQL ステートメントが複雑である。
解決策:SQL ステートメントを最適化し、適切なインデックスを設定してクエリのパフォーマンスを向上させます。詳細については、「クエリのパフォーマンスの最適化」および「Hologres での MaxCompute テーブルのクエリのパフォーマンスの最適化」をご参照ください。
原因 2:QPS が高い。
解決策:SQL ステートメントを最適化した後、より高い QPS とより低いレイテンシが必要な場合は、インスタンスをスケールアウトしてパフォーマンスを向上させます。詳細については、「インスタンスのアップグレード」をご参照ください。
原因 3:クエリ中に大量のデータが書き込まれる。
解決策:
オフピーク時にデータを書き込んで、クエリへの影響を軽減します。
同時書き込み操作の数を減らして、クエリの効率を向上させます。外部テーブルを使用してデータを書き込む場合は、次のステートメントを実行して同時実行性を低下させることができます。
-- MaxCompute で一度に実行するクエリの最大数を設定します。デフォルト値:128。1 つのクエリが他のクエリに影響を与えたり、システムが使用できなくなったりするのを防ぐため、このパラメーターを小さい値に設定することをお勧めします。 set hg_experimental_foreign_table_executor_max_dop = 32; -- 並列性を下げるため、このパラメーターを小さい値に設定することをお勧めします。 -- MaxCompute テーブルから一度に読み取るデータエントリの数を設定します。デフォルト値:8192。 set hg_experimental_query_batch_size = 1024; -- ORC テーブルからデータを読み取ります。 set hg_experimental_enable_access_odps_orc_via_holo = on; -- MaxCompute テーブルの各シャードのサイズを設定します。デフォルト値:64。単位:MB。シャードサイズは並列性に影響します。テーブルのサイズが大きい場合は、このパラメーターの値を増やして、過剰なシャードがクエリのパフォーマンスを低下させるのを防ぐことができます。 set hg_experimental_foreign_table_split_size = 512MB;
メモリ使用量が多い原因は何ですか?問題のトラブルシューティングを行うにはどうすればよいですか?
Memory Usage メトリックは、インスタンスのメモリ使用量を示します。Hologres では、メモリリソースはバックエンドプロセスによって予約されます。クエリが進行中でなくても、データテーブルのメタデータ、インデックス、データキャッシュはメモリにロードされ、データの検索と計算が高速化されます。そのため、メモリ使用量はゼロではありません。クエリが進行中でない場合、メモリ使用率が 30% から 40% であるのは正常です。
場合によっては、メモリ使用量が上昇し続け、80% に近づくことさえあります。メモリ使用量が多い問題の原因として、次のことが考えられます。
テーブルの数とデータの合計サイズが増え続けるにつれて、インスタンスの計算能力が限界に達します。メタデータのサイズとインデックスの数に比例してメモリ使用量が増加します。テーブルとインデックスの数、およびデータサイズが増加するにつれて、メモリ使用量が増加します。
インデックス設定が適切ではありません。たとえば、多数のビットマップインデックスが作成されているか、TEXT データ型の多数の列を含むテーブルで辞書エンコーディングが有効になっています。この場合、テーブルのビットマップインデックスまたは辞書エンコーディングプロパティを変更できます。詳細については、「ALTER TABLE」をご参照ください。
メモリ使用量が上昇し続け、80% に近い状態が続く場合、メモリリソースがインスタンスのボトルネックになり、インスタンスの安定性またはパフォーマンスに影響を与える可能性があります。たとえば、大量のメタデータがクエリに使用可能なメモリ領域を占有している場合、SERVER_INTERNAL_ERROR
、ERPC_ERROR_CONNECTION_CLOSED
、Total memory used by all existing queries exceeded memory limitation
などのエラーがクエリ中に発生する可能性があります。大量のメタデータがクエリに使用可能なキャッシュ領域を占有している場合、キャッシュヒットが減少し、クエリレイテンシが増加します。
メモリ使用率が 80% に近い状態が続く場合は、次の操作を実行することをお勧めします。
クエリされなくなったデータを削除して、メタデータなどのデータによって占有されているメモリ領域を解放します。
適切なインデックスを設定します。特定のビジネスシナリオでは、不要なビットマップインデックスを削除したり、辞書エンコーディングを無効にしたりできます。
インスタンスの仕様をアップグレードして、インスタンスの計算リソースとストレージリソースを増やします。特定のシナリオに基づいてインスタンスをアップグレードすることをお勧めします。
特定のレイテンシでディスクデータを読み取ることができ、応答時間(RT)が厳しくないシナリオでは、データサイズに基づいて適切なインスタンスタイプを選択することをお勧めします。1 つの CPU コアと 4 GB のメモリを含む 1 つの計算ユニット(CU)は、50 GB から 100 GB のデータストレージをサポートできます。
短い RT が必要なサービスシナリオでは、すべてのホットデータをメモリにキャッシュすることをお勧めします。デフォルトでは、キャッシュは合計メモリの 30% を占めます。このようなシナリオでは、1 CU のうち 1.3 GB のメモリがデータのキャッシュに使用され、テーブルのメタデータはキャッシュに保存されます。たとえば、短い RT が必要なシナリオでは、100 GB のホットデータをメモリにキャッシュする必要があります。データの読み取りと解凍後、100 GB を超えるメモリが使用されます。この場合、少なくとも 320 GB のメモリが必要であり、これは少なくとも 96 CU に相当します。
1 つのクエリしか進行中でなくても CPU 使用率が 100% になるのはなぜですか?
CPU Utilization メトリックは、インスタンスの CPU 使用率を示します。Hologres はマルチコア並列計算をサポートしています。ほとんどの場合、単一クエリ中の CPU 使用率は 100% に増加する可能性があります。これは、計算リソースが完全に活用されていることを示しています。CPU 使用率が高いことは問題ではありません。CPU 使用率が高く、データのクエリと書き込みが遅い場合は、問題です。問題を包括的に分析する必要があります。
書き込みが遅い問題のトラブルシューティングを行うにはどうすればよいですか?
INSERT
、INSERT ON CONFLICT
、または UPDATE
ステートメントの実行に時間がかかる場合、書き込みパフォーマンスが低下します。一般に、この問題は、固定プランが SQL ステートメントの実行に使用されておらず、テーブルがロックされているために発生します。クエリが同時に実行されると、ロック待機が発生します。その結果、実行に時間がかかります。Real-time Import (RPS)
メトリックは、INSERT
ステートメントを使用してインポートまたは更新されたレコードの 1 秒あたりのレコード数(RPS)を示します。クエリの機能を確認し、固定プランを使用してクエリで実行される SQL ステートメントを最適化できます。この場合、Real-time Import (RPS) メトリックは、SDK
を使用してインポートまたは更新されたレコードの RPS を示します。これは、書き込みパフォーマンスの向上に役立ちます。詳細については、「固定プランを使用した SQL ステートメントの実行の高速化」をご参照ください。
CPU 使用率が 100% に近い状態が続く場合はどうすればよいですか?
Hologres インスタンスの CPU 使用率が 100% に近い状態が続く場合、インスタンスは高負荷状態にあります。たとえば、CPU 使用率が 3 時間連続で 100% の状態が続くか、12 時間連続で 90% を超える状態が続きます。この場合、CPU リソースがインスタンスのボトルネックになります。特定のビジネスシナリオとデータクエリステートメントを分析して、CPU 使用率が高い原因を特定する必要があります。次の考えられる原因に基づいて、この問題のトラブルシューティングを行うことができます。
原因 1:QPS または RPS が大幅に増加する。
CPU 使用率が高い問題が発生する前後の QPS メトリックと RPS メトリックを比較します。QPS または RPS が大幅に増加している場合、これが CPU 使用率が高い原因です。
解決策:
データクエリ用の SELECT ステートメントの実行が CPU 使用率が高い問題の原因である場合は、スロークエリログをクエリすることで対応する遅いクエリを表示し、それに応じてクエリを最適化できます。
INSERT
、UPDATE
、またはDELETE
ステートメントの実行が CPU 使用率が高い問題の原因である場合は、次のステートメントを実行してスロークエリログをクエリし、INSERT、UPDATE、または DELETE ステートメントが固定プランを使用しているかどうかを確認することをお勧めします。固定プランを使用してINSERT
、UPDATE
、またはDELETE
ステートメントを実行しない場合、テーブルはロックされます。クエリが同時に実行されると、ロック待機が発生します。テーブルロックを防ぎ、CPU 使用率を下げるには、ビジネス要件に基づいて、固定プランを使用して SQL ステートメントを最適化できるかどうかを確認できます。-- 例:過去 1 時間に固定プランを使用して実行されなかった INSERT、UPDATE、または DELETE ステートメントをクエリします。 select * from hologres.hg_query_log where query_start >= now() - interval '3 h' and command_tag in ('INSERT','UPDATE','DELETE') and 'HQE'=ANY(engine_type) order by query_start desc limit 500;
SQL ステートメントが最適化されていても CPU 使用率が依然として高い場合は、インスタンスリソースがボトルネックに達しています。インスタンスをスケールアウトするか、複数のインスタンスに共有ストレージをデプロイして読み取り/書き込み分割を有効にすることができます。詳細については、「インスタンスのアップグレード」または「プライマリインスタンスとセカンダリインスタンス(共有ストレージ)の読み取り/書き込み分割の構成」をご参照ください。
原因 2:QPS または RPS は大幅に増加しないが、長時間実行されるクエリが存在する。
メトリックデータは、QPS または RPS が大幅に増加していないことを示しています。ただし、CPU 使用率が突然増加し、CPU 使用率が高い問題が一定期間持続します。
Ongoing Query Duration
メトリックを表示して、長時間実行されるクエリを確認できます。メトリックデータが 30 分以上または 1 時間以上続くクエリが存在することを示している場合、これらのクエリが CPU 使用率が高い問題の原因となっています。次のステートメントを実行して、アクティブなクエリをクエリすることで長時間実行されるクエリを表示し、クエリを終了できます。これにより、CPU 使用率が低下します。-- 長時間実行されるクエリをクエリします。 SELECT current_timestamp - query_start as runtime, datname::text, usename, query, pid::text FROM pg_stat_activity WHERE state != 'idle' order by 1 desc; -- 長時間実行されるクエリを終了します。 select pg_cancel_backend(<pid>);
原因 3:多数の CPU リソースを消費するクエリが存在する。
メトリックデータは、QPS または RPS が大幅に増加していないことを示しています。ただし、CPU 使用率が突然増加し、CPU 使用率が高い問題が一定期間持続します。次のステートメントを実行して、スロークエリログをクエリすることで CPU 使用率が高いクエリを表示し、データクエリに使用される SQL ステートメントを最適化できます。
-- 過去 3 時間に多数の CPU リソースを消費した遅いクエリをクエリします。 select status as "Status", duration as "Time consumed (ms)", query_start as "Started at", (read_bytes/1048576)::text || ' MB' as "Bytes", (memory_bytes/1048576)::text || ' MB' as "Memory", (shuffle_bytes/1048576)::text || ' MB' as "Shuffle", (cpu_time_ms/1000)::text || ' s' as "CPU time", physical_reads as "Physical reads", query_id as "QueryID", query from hologres.hg_query_log where query_start > current_timestamp - interval'3 h' and command_tag in ('SELECT','INSERT','UPDATE','DELETE') and duration > 1000 order by duration desc, read_bytes desc, shuffle_bytes desc, memory_bytes desc, cpu_time_ms desc, physical_reads desc limit 500;
原因 4:PostgreSQL Query Engine(PQE)で実行される SQL ステートメントが原因で CPU 使用率が 100% に増加する。
メトリックデータが QPS または RPS が大幅に増加していないことを示している場合は、次の SQL ステートメントを実行して、スロークエリログをクエリすることで、PQE で新しい SQL ステートメントが実行されているかどうかを確認できます。SQL ステートメントが PQE で実行されている場合、これらのステートメントが CPU 使用率が高い問題の原因となっています。SQL ステートメントが PQE で実行されている場合は、PQE で実行される SQL 演算子を最適化する必要があります。詳細については、「クエリのパフォーマンスの最適化」をご参照ください。
-- 過去 3 時間に PQE で実行されたクエリをクエリします。 select * from hologres.hg_query_log where query_start > current_timestamp - interval'3 h' and 'PQE'=ANY(engine_type) order by query_start desc limit 500;
原因 5:テーブルのビットマップインデックスまたは辞書エンコーディングプロパティが変更される。
テーブルのビットマップインデックスまたは辞書エンコーディングプロパティが変更されると、バックエンドで非同期にコンパクション操作が実行されます。この場合、CPU リソースが消費され、インスタンスのストレージ容量が増加してから減少する可能性があります。次の SQL ステートメントを実行して、スロークエリログをクエリすることで、テーブルのビットマップインデックスまたは辞書エンコーディングプロパティが変更されたかどうかを確認できます。
-- 過去 3 時間にビットマップインデックスまたは辞書エンコーディングプロパティが変更されたレコードをクエリします。 select * from hologres.hg_query_log where query_start >= now() - interval '3 h' and command_tag in ('CALL') order by query_start desc limit 500;
長時間実行されるクエリのトラブルシューティングを行うにはどうすればよいですか?
Ongoing Query Duration メトリックは、長時間続く進行中のクエリの期間を示します。たとえば、進行中のクエリが 1 時間以上続く場合、そのクエリは長時間実行されるクエリと見なされます。長時間実行されるクエリが存在する場合は、[アクティブなクエリ] ページでクエリを表示できます。詳細については、「クエリの管理」をご参照ください。長時間実行されるクエリは、次の原因により発生する可能性があります。
原因 1:長時間実行される書き込み操作が存在する。
解決策:Real-time Import (RPS) メトリックを監視して、長時間実行される書き込み操作が存在するかどうかを確認します。
原因 2:一部のクエリがトランザクション内でアイドル状態になっている。
クライアントがトランザクションを開始したが、データ定義言語(DDL)ステートメントの実行後にトランザクションをコミットしない場合、対応するクエリは
idle in transaction
状態になります。次の SQL ステートメントを実行して、idle in transaction 状態であり、長時間実行されているアクティブなクエリをクエリできます。ロック待機が原因でクエリが長時間実行されている。
解決策:次の SQL ステートメントの例を実行して、長時間実行されるクエリを表示します。長時間実行されるクエリが
idle in transaction
状態の場合は、クライアントでトランザクションを終了するか、アイドル状態のトランザクションに適切なタイムアウト期間を設定できます。詳細については、「アイドル状態のクエリのタイムアウト期間の変更」をご参照ください。原因 3:PQE で実行される複雑な SQL ステートメントを含むクエリがある。
解決策:次の SQL ステートメントを実行して、長時間実行されているアクティブなクエリをクエリします。次に、EXPLAIN ステートメントを実行して、クエリの実行プランを確認します。実行プランに
External SQL (Postgres)
が含まれている場合、クエリには PQE で実行される SQL ステートメントが含まれています。-- 長時間実行されるクエリをクエリします。 SELECT current_timestamp - query_start as runtime, datname::text, usename, query, pid::text FROM pg_stat_activity WHERE state != 'idle' order by 1 desc; -- クエリの実行プランをクエリします。 explain sql
スーパーユーザーアカウントを使用して、長時間実行されるクエリを終了します。
PQE で実行される SQL 演算子を最適化します。詳細については、「クエリのパフォーマンスの最適化」をご参照ください。
原因 4:同時 DDL 操作が原因でロックの競合が発生する。
複数の DDL ステートメントが同時に実行されると、テーブルがロックされます。その結果、ロックの競合が発生し、DDL ステートメントはロックが使用可能になるまでキューで待機する必要があります。
解決策:
次の SQL ステートメントを実行して、DDL ステートメントが実行されているかどうかを確認します。実行中の DDL ステートメントを終了して、ロックを解放します。
SELECT datname::text,usename,query,pid::text,state FROM pg_stat_activity WHERE state != 'idle' ;
DDL ステートメントを 1 つずつ実行します。
失敗したクエリのトラブルシューティングを行うにはどうすればよいですか?
Failed Queries per Second メトリックは、1 秒あたりの失敗したクエリの平均数を示します。秒単位で測定された期間における失敗したクエリの総数は、Failed Queries per Second メトリックの値に期間を掛けて計算されます。Failed Queries per Second メトリックのみに基づいて失敗したクエリの総数を判断しないことをお勧めします。スロークエリログをクエリすることで、失敗したクエリの総数と失敗の原因を確認できます。次に、エラーメッセージに基づいて問題を解決できます。詳細については、「スロークエリログのクエリと分析」をご参照ください。
ワーカー間で CPU 負荷が不均衡な問題のトラブルシューティングを行うにはどうすればよいですか?
Hologres では、データはシャードに分散されます。ワーカーは、計算中に 1 つ以上のシャードのデータにアクセスする場合があります。各インスタンスでは、シャードには一度に 1 つのワーカーしかアクセスできません。各ワーカーがアクセスするシャードの総数が異なる場合、ワーカーの負荷が不均衡になる可能性があります。この問題は、次の原因により発生する可能性があります。
原因 1:データの偏りが存在する。
深刻なデータの偏りが発生した場合、ワーカーは固定のシャードにアクセスします。これにより、ワーカー間で CPU 負荷が不均衡になります。
解決策:次の SQL ステートメントを実行して、データの偏りが存在するかどうかを確認します。次のサンプル結果では、あるシャードの count 値が他のシャードの count 値よりもはるかに大きくなっています。これは、データの偏りが存在することを示しています。データの偏りが存在する場合は、不均一に分散されたデータを処理するか、ビジネス要件に基づいて適切な分散キーを設定できます。詳細については、「クエリのパフォーマンスの最適化」をご参照ください。
select hg_shard_id,count(1) from <table_name> group by hg_shard_id; -- サンプル結果:シャード 39 の count 値が他のシャードの count 値よりも大きくなっています。これは、データの偏りが存在することを示しています。 hg_shard_id | count -------------+-------- 53 | 29130 65 | 28628 66 | 26970 70 | 28767 77 | 28753 24 | 30310 15 | 29550 39 | 164983
原因 2:シャード数がインスタンス内のワーカー数の倍数ではない。
テーブルグループのシャード数がワーカー数の倍数ではない場合、各ワーカーに割り当てられるシャード数が異なります。これにより、ワーカー間で負荷の不均衡が発生します。
解決策:インスタンスタイプに基づいてシャード数を設定します。詳細については、「テーブルグループとシャード数のユーザーガイド」をご参照ください。ほとんどの場合、このエラーは 256 個を超える CPU コアを持つインスタンスで発生します。仕様が小さいインスタンスの場合は、デフォルトのシャード数を使用できます。
原因 3:ワーカーのフェイルオーバー後に、シャードがワーカーに不均一に割り当てられる。
メモリ不足(OOM)などの理由でワーカーが終了した場合、システムは対応するシャードを他のワーカーに割り当ててクエリを回復します。終了したワーカーが回復すると、システムはこのワーカーにいくつかのシャードを割り当てます。これにより、ワーカー間でシャードの割り当てが不均一になります。
解決策:インスタンスの負荷が低い場合は、負荷の不均衡の問題を無視します。インスタンスの負荷が高い場合は、インスタンスを再起動してシャードを均等に再割り当てします。