メモリ不足 (OOM) エラーは、クエリが Hologres で利用可能なメモリを超過した場合に発生します。このトピックでは、メモリ使用量を監視し、OOM エラーを特定して解決する方法について説明します。
メモリ消費量の分析
-
メモリ消費量の表示
-
総消費量: Hologres コンソールには、全ノードの集計メモリ消費量が表示されます。詳細については、「モニタリングメトリクス」をご参照ください。
-
クエリごとの消費量:
memory_bytesフィールドは、クエリごとのメモリ消費量の概算値です。この値は不正確な場合があります。詳細については、「低速クエリログの取得と分析」をご参照ください。
-
-
高いメモリ使用率への対応
Hologres コンソールで全体的なメモリ使用量を監視します (「モニタリングメトリクス」をご参照ください)。80% を超える使用率が持続する場合、高い状態と見なされます。Hologres はメタデータとキャッシュのためにメモリを事前割り当てするため、30%~50% のアイドル時使用率は正常です。100% に近い使用率は、安定性とパフォーマンスを低下させます。
-
原因
-
メタデータによる高いメモリ消費量
メタデータのメモリはテーブル数とともに増加し、タスクが実行されていない場合でも高い使用率を引き起こす可能性があります。各テーブルグループを 10,000 テーブル (パーティションを含み、外部テーブルを除く) 未満に維持してください。テーブルグループ内のシャードが多すぎると、断片化とメタデータのオーバーヘッドが増加します。
-
計算による高いメモリ消費量
クエリのメモリ使用量が高いのは、通常、大量のデータスキャン、または複数の
COUNT DISTINCT関数、複雑なJOIN操作、複数列に対するGROUP BY、あるいはウィンドウ関数といった複雑な操作が原因です。 -
Other モジュールでの高いメモリ使用率
メモリ監視で Other モジュールのメモリ使用量が急激に増加し、全体的なメモリ使用率も高い場合、原因は実験的なパラメーター
hg_experimental_enable_hash_partitioned_sort_v2である可能性があります。このパラメーターは、ウィンドウ行番号をフィルタリングするためのハッシュパーティションソートアルゴリズムを有効にします。このアルゴリズムには既知のリソース消費の問題があり、Other モジュールカテゴリに未分類のメモリが蓄積される原因となります。解決策
次の SQL 文を実行して、実験的パラメータを無効にしてください:
SET hg_experimental_enable_hash_partitioned_sort_v2 = off;このパラメータを無効にした後、インスタンスのメモリ使用量を監視します。Other モジュールに起因するメモリは、通常のレベルまで減少するはずです。
-
-
主な影響
-
安定性
特にメタデータに起因する過剰なメモリ消費は、クエリで使用できるメモリを減少させ、
SERVER_INTERNAL_ERROR、ERPC_ERROR_CONNECTION_CLOSED、またはTotal memory used by all existing queries exceeded memory limitationなどの散発的なエラーを引き起こす可能性があります。 -
パフォーマンス
過剰なメタデータによる高いメモリ使用率は、キャッシュスペースを枯渇させ、キャッシュヒット率を低下させ、クエリレイテンシーを増加させます。
-
-
解決策
-
過剰なメタデータが原因でメモリ使用量が多くなっている場合は、
hg_table_infoテーブルを使用してテーブルを管理します。詳細については、「テーブル統計のクエリと分析」をご参照ください。不要なデータまたはテーブルを削除し、不要なパーティションを削減してメモリを解放します。 -
高いメモリ使用率が計算によって引き起こされている場合:書き込みとクエリのユースケースに応じて SQL を個別に最適化してください。詳細については、「クエリ中のOOMエラーの解決」および「データインポート/エクスポート中のOOMエラーの解決」をご参照ください。
-
一般的な解決策:コンピューティングリソースとストレージリソースをスケールアップしてください。「インスタンスリスト」をご参照ください。
-
-
OOM エラーの特定
OOM エラーは、計算メモリが割り当てられた制限 (例:20 GB 以上) を超えると発生します。典型的なエラーメッセージは次のとおりです:
Total memory used by all existing queries exceeded memory limitation.
memory usage for existing queries=(2031xxxx,184yy)(2021yyyy,85yy)(1021121xxxx,6yy)(2021xxx,18yy)(202xxxx,14yy); Used/Limit: xy1/xy2 quota/sum_quota: zz/100
エラーメッセージは次のように解釈します:
-
queries=(query_id, memory_used_by_query)queries=(2031xxxx,184yy)などの各エントリは、クエリごとのメモリ消費量を示します。 たとえば、queries=(2031xxxx,18441803528)は、クエリquery_id=2031xxxxが単一ノードで約 18 GB を消費したことを意味します。 メモリを大量に消費する上位 5 件のクエリがリストされます。 詳細については、「低速クエリログの取得と分析」をご参照ください。 -
使用量/上限: xy1/xy2compute_memory_used_on_node/compute_memory_limit_on_nodeをバイト単位で示します。Usedは、そのノードで実行中のすべてのクエリによって消費されるコンピューティングメモリの合計です。たとえば、Used/Limit: 33288093696/33114697728は、クエリが 33.1 GB の制限を超えて 33.2 GB を使用し、OOM が発生したことを意味します。 -
quota/sum_quota: zz/100zzは、リソースグループに割り当てられた総インスタンスリソースの割合を表します。たとえば、quota/sum_quota: 50/100は、リソースグループが総インスタンスリソースの 50% を使用することを意味します。
OOM エラーの基本的な原因
Hologres は、クエリ効率を最適化するためにインメモリでの計算を優先します。メモリが不足した場合にディスクへのスピルを行うシステムとは異なり、Hologres はクエリが利用可能なメモリを超過すると直接 OOM エラーを発生させます。
メモリ割り当てと制限
Hologres インスタンスは、複数のノードで構成される分散システムとして動作し、そのノード数はインスタンスの仕様によって異なります。詳細については、「インスタンス管理」をご参照ください。
各ノードは通常、16 vCPU と 64 GB のメモリを備えています。いずれか 1 つのノードがメモリを使い果たすと、OOM エラーが発生します。64 GB は、クエリ計算、バックエンドプロセス、キャッシュ、メタデータ用にパーティション分割されます。V1.1.24 より前では、計算メモリは 20 GB に制限されていました。V1.1.24 以降では、メタデータの消費量が少ない場合に、利用可能なメモリがクエリに動的に割り当てられます。
クエリ中の OOM エラーの解決
-
原因
-
不正確な実行計画:不正確な統計情報、不適切な結合順序、またはその他の最適化の問題が原因である可能性があります。
-
高いクエリ同時実行性:多くのクエリが同時に大量のメモリを消費している状態です。
-
複雑なクエリ:本質的に複雑なクエリ、または大量のデータをスキャンするクエリです。
-
UNION ALL操作:UNION ALLを含むクエリは、エグゼキューターの並列度を高め、メモリ使用量の増加につながることがあります。 -
不十分なリソースグループの割り当て:リソースグループが設定されているものの、割り当てられたリソースが不十分な状態です。
-
データスキューまたはシャードプルーニング:これらは、不均衡な負荷と特定のノードでの高いメモリプレッシャーを引き起こす可能性があります。
-
-
分析と解決策:
-
原因:不十分なリソースグループの割り当て
解決策:サーバーレスコンピューティング機能を使用して、インスタンスの専用リソースを追加の計算能力で補ってください。概要と使用方法については、「サーバーレスコンピューティング」および「サーバーレスコンピューティングの操作」をご参照ください。
Hologres V3.0 以降では、クエリキューが OOM クエリをサーバーレスコンピューティングリソースで自動的に再実行します。「大規模なクエリの制御」をご参照ください。
-
原因:不正確な実行計画
-
タイプ 1:不正確な統計情報
EXPLAIN <SQL>を実行して実行計画を表示します。 次の図に示すように、rows=1000は統計情報が欠落しているか不正確であることを示しており、その結果、実行計画が非効率になってリソースを過剰に消費し、OOM エラーがトリガーされます。
解決策は次のとおりです:
-
テーブルの統計情報を更新するには、
ANALYZE <tablename>コマンドを実行します。 -
自動分析を有効にして、統計情報を自動的に更新してください。詳細については、「ANALYZEとAUTO ANALYZE」をご参照ください。
-
-
タイプ 2:不適切な結合順序
ハッシュ結合では、小さい方のテーブルをビルド側にする必要があります。実行計画を確認するには、
EXPLAIN <SQL>を使用します。大きい方のテーブルがハッシュテーブルを構築する場合、結合順序は非効率になり、OOM が発生する可能性があります。一般的な理由:-
古いテーブルの統計情報。たとえば、以下の図では、上のテーブルの統計情報が更新されなかったため、
rows=1000となっています。
-
オプティマイザが最適な実行計画を生成できなかった。
解決策:
-
結合に関与するすべてのテーブルで
ANALYZE <tablename>を実行し、統計情報を最新の状態に保ちます。 これにより、オプティマイザが正しい結合順序を決定するのに役立ちます。 -
ANALYZE <tablename>を実行しても結合順序が正しくない場合は、GUC パラメータを調整します。optimizer_join_order = queryを設定して、オプティマイザが SQL 文で指定された結合順序に強制的に従うようにします。このアプローチは、特に複雑なクエリに適しています。SET optimizer_join_order = query; SELECT * FROM a JOIN b ON a.id = b.id; -- テーブルbがハッシュテーブルのビルド側として使用されます。必要に応じて、結合順序ポリシーを調整することもできます。
パラメータ
説明
set optimizer_join_order = <value>このパラメータは、オプティマイザの結合順序アルゴリズムを制御します。有効な値は次のとおりです:
-
query: 結合順序の変換は実行されません。結合は、SQL クエリで指定された順序どおりに厳密に実行されます。この設定では、オプティマイザのオーバーヘッドが最も低くなります。 -
greedy: 貪欲法を使用して、考えられる結合順序を探索します。このオプションでは、中程度のオプティマイザオーバーヘッドが発生します。 -
exhaustive(デフォルト): Join Order 変換に動的計画アルゴリズムを使用します。最適な実行計画の生成を目的としますが、オプティマイザのオーバーヘッドが最も高くなります。
-
-
-
タイプ 3:不正確なハッシュテーブルの推定
ハッシュ結合では、小さい方の入力がハッシュテーブルをビルドする必要があります。しかし、クエリの複雑さや不正確な統計情報により、システムがビルド入力として大きい方のリレーションを選択し、OOM をトリガーする特大のハッシュテーブルを作成することがあります。
下の図に示すように、
Hash (cost=627353.35..727353.45 , rows=970902134 width=94)はビルド入力を表し、rows=970902134はハッシュテーブルをビルドするための推定データ量を示します。実際のテーブルに含まれるデータがこれより少ない場合、推定は不正確です。
解決策:
-
統計の確認: サブクエリのテーブル統計が最新かつ正確であるかを確認します。そうでない場合は、
ANALYZE <tablename>を実行してそれらを更新します。 -
ハッシュテーブル推定の無効化:次のパラメータを使用して、実行エンジンのハッシュテーブル推定をオフにしてください:
説明このパラメーターは、デフォルトで
offに設定されています。ただし、特定のチューニングシナリオで有効になっている場合があります。現在有効になっている場合は、必ずoffに戻してください。SET hg_experimental_enable_estimate_hash_table_size =off;
-
-
タイプ 4:大きなテーブルのブロードキャスト
ブロードキャストは、すべてのシャードにデータをコピーするため、シャード数が少ない小さなテーブルに対してのみ効率的です。結合中、ビルド側の入力がすべてのシャードにブロードキャストされます。大規模なデータセットや過剰なシャード数は、大量のメモリを消費し、OOM エラーを引き起こす可能性があります。
たとえば、8,000 万行のテーブルが、実行計画では推定 1 行としか表示されないことがあります。実際には 8,000 万行すべてがブロードキャストされるため、過剰なメモリを消費し、OOM をトリガーします。

解決策:
-
実行計画における推定行数が実際と一致するかどうかを確認してください。一致しない場合は、
ANALYZE tablenameを実行して統計情報を更新してください。 -
次の GUC パラメータを使用してブロードキャストを無効にし、再配布演算子として書き換えてください。
SET optimizer_enable_motion_broadcast = off;
-
-
-
原因:高いクエリ同時実行性
QPS が大幅に急増した場合、または各クエリがごくわずかなメモリしか使用していないにもかかわらず、OOM エラーに
HGERR_detl memory usage for existing queries=(2031xxxx,184yy)(2021yyyy,85yy)(1021121xxxx,6yy)(2021xxx,18yy)(202xxxx,14yy);が表示される場合は、高い同時実行性が原因である可能性が高いです。 解決策:-
書き込み同時実行性の削減:書き込み操作が原因である場合は、その同時実行性を減らしてください。詳細については、「データインポート/エクスポート中のOOMエラーの解決」をご参照ください。
-
読み書き分離の実装:プライマリインスタンスとセカンダリインスタンス (共有ストレージ) を使用した読み書き分離アーキテクチャを展開してください。
-
インスタンスのコンピューティング仕様を増強してください。
-
-
原因:複雑なクエリ
単一のクエリがその複雑さや大規模なデータ量のために OOM を引き起こす場合は、以下のアプローチを検討してください:
-
データの事前計算:事前計算されたデータを Hologres に書き込み、Hologres 内での大規模な ETL 操作を回避してください。
-
フィルター条件を追加してください。
-
SQL の最適化:固定プランや Count Distinct 最適化などのテクニックを使用してください。詳細については、「内部テーブルのクエリパフォーマンスの最適化」をご参照ください。
-
-
原因:UNION ALL
以下に示すように、SQL 文に多数の
UNION ALLサブクエリが含まれていると、エグゼキュータがそれらを並行して処理するため、メモリが過負荷になり OOM エラーが発生する可能性があります。subquery1 UNION ALL subquery2 UNION ALL subquery3 ...解決策:次のパラメータを使用して直列実行を強制し、OOM エラーを緩和してください。これによりクエリのパフォーマンスが低下することにご注意ください。
SET hg_experimental_hqe_union_all_type=1; SET hg_experimental_enable_fragment_instance_delay_open=on; -
原因:不適切なリソースグループ設定
OOM エラーでは、
memory usage for existing queries=(3019xxx,37yy)(3022xxx,37yy)(3023xxx,35yy)(4015xxx,30yy)(2004xxx,2yy); Used/Limit: xy1/xy2 quota/sum_quota: zz/100と報告されます。zz が小さい場合 (たとえば、割り当てられたリソースのわずか 10% にあたる 10)、そのグループ内のクエリはメモリが制限されるため、OOM が発生する可能性が高くなります。
解決策: リソースグループのクォータをリセットします。各リソースグループに、インスタンスの総リソースの少なくとも
30%を割り当てます。 -
原因:データスキューまたはシャードプルーニング
全体的なメモリ使用率が低いにもかかわらず OOM が発生する場合、データスキューまたはシャードプルーニングが特定のノードにメモリプレッシャーを集中させている可能性があります。
説明シャードプルーニングは、すべてのシャードではなく、シャードのサブセットのみをスキャンするクエリ最適化技術です。
-
データスキューをチェックするには、次の SQL クエリを使用します。
hg_shard_idは、各テーブルに存在する組み込みの隠しフィールドで、各行が格納されているシャードを示します。SELECT hg_shard_id, count(1) FROM t1 GROUP BY hg_shard_id; -
シャードプルーニングの確認: 実行計画にシャードプルーニングの兆候がないか確認します。たとえば、シャードセレクターに
l0[1]と表示されている場合、クエリに対して特定の 1 つのシャードのデータのみが選択されたことを意味します。-- 分散キーはxです。フィルター条件x=1に基づいて、シャードを迅速に見つけることができます。 SELECT count(1) FROM bbb WHERE x=1 GROUP BY y;
解決策:
-
データスキューを防ぐために、適切な分散キーを設計してください。
-
ビジネスロジックが本質的にデータスキューを引き起こす場合は、それに応じてアプリケーションロジックを変更してください。
-
-
原因:高カーディナリティの多段階 GROUP BY
Hologres V3.0 以降では、
GROUP BY列が分散キーと一致しない (分散キーがGROUP BYキーのサブセットではない) 場合、高カーディナリティデータに対する多段階集計で OOM (メモリ不足) が発生する可能性があります。各同時実行インスタンスが大きなハッシュテーブルを維持するため、メモリへの負荷が高くなります。これを軽減するには、次のパラメーターを設定します。-- GUC パラメータを使用して、集計ハッシュテーブルの最大行数を設定します。次の SQL 文は、partial_agg_hash_table が最大 8192 行を持つことができることを示します。デフォルト値は 0 で、これは制限がないことを示します。 SET hg_experimental_partial_agg_hash_table_size = 8192;
-
データインポート/エクスポート中の OOM エラーの解決
OOM エラーは、内部テーブル間、外部テーブルとのやり取り、MaxCompute からのインポートなど、Hologres でのデータ転送中に発生する可能性があります。
-
解決策 1:インポートとエクスポートにサーバーレスコンピューティングを使用する
サーバーレスコンピューティングを使用して、インスタンスのリソースを補完し、インポートおよびエクスポートタスクのリソース競合を回避してください。概要については、「サーバーレスコンピューティング」をご参照ください。使用方法については、「サーバーレスコンピューティングの操作」をご参照ください。
-
解決策 2:ワイドテーブルまたはワイドカラムのスキャン同時実行性を制御する
MaxCompute からのインポートでは、ワイドテーブルまたはワイドカラムと高いスキャン同時実行性の組み合わせによって OOM エラーが発生することがあります。次のパラメータを使用して、同時実行性を制御してください。
-
ワイドテーブルのスキャン同時実行性を制御する (一般的なシナリオ)
説明SQL 文と一緒に次のパラメータを適用してください。最初の 2 つのパラメータを優先してください。OOM エラーが解決しない場合は、それらの値をさらに減らしてください。
-- 外部テーブルへのアクセスの最大同時実行数を設定します。デフォルト値はインスタンスの vCPU 数と同じです。最大値は 128 です。外部テーブルへのクエリ、特にデータインポートシナリオで、他のクエリに影響を与え、システムビジーエラーを引き起こすのを防ぐため、大きな値を設定しないでください。このパラメータは Hologres V1.1 以降で有効です。 SET hg_foreign_table_executor_max_dop = 32; -- MaxCompute テーブルから読み取る各バッチのサイズを調整します。デフォルト値は 8192 です。 SET hg_experimental_query_batch_size = 4096; -- 外部テーブルにアクセスする際の DML 文の最大実行同時実行数を設定します。デフォルト値は 32 です。このパラメータは、インポート操作が過剰なシステムリソースを消費するのを防ぐために、データインポートおよびエクスポートシナリオ向けに最適化されています。このパラメータは Hologres V1.1 以降で有効です。 SET hg_foreign_table_executor_dml_max_dop = 16; -- MaxCompute テーブルにアクセスするための分割サイズを設定します。このパラメータは同時実行性を調整できます。デフォルト値は 64 MB です。テーブルが大きい場合は、この値を増やして、分割が多すぎてパフォーマンスに影響を与えるのを防ぎます。このパラメータは Hologres V1.1 以降で有効です。 SET hg_foreign_table_split_size = 128; -
ワイドカラムのスキャン同時実行性を制御する
すでにワイドテーブルのパラメータを調整しても OOM エラーが発生する場合は、データにワイドカラムが含まれているかどうかを確認してください。含まれている場合は、次のパラメータを調整して問題を解決してください。
-- ワイドカラムのシャッフル並列度を調整して、データの蓄積を減らします。 SET hg_experimental_max_num_record_batches_in_buffer = 32; -- MaxCompute テーブルから読み取る各バッチのサイズを調整します。デフォルト値は 8192 です。 SET hg_experimental_query_batch_size=128;
-
-
原因:外部テーブル内の過剰な重複データ
外部テーブルに大量の重複データが含まれている場合、インポートのパフォーマンスが低下し、OOM エラーが発生する可能性があります。たとえば、1 億行のうち 8,000 万行が重複しているテーブルは、重複度が高いと見なされます。ビジネスコンテキストに基づいて重複度を評価してください。
解決策:インポート前にデータを重複排除するか、より小さなバッチでインポートしてください。
エラー「The shards are incomplete, the workers or shards are unhealthy」の原因
このエラーは通常、メモリ不足 (OOM) 問題によって直接引き起こされるものではありません。Hologres インスタンスの CPU 使用率が過度に高くなり、ワーカーノードまたはシャードが異常な状態になったときに発生します。
この問題を解決するには:
-
Hologres インスタンスのモニタリングメトリクスをチェックして、CPU 使用率が上昇しているかどうかを確認してください。
-
CPU 使用率が高い場合は、ワークロードが減少するのを待ってからクエリを再試行してください。
-
エラーが続く場合は、複雑なクエリや過剰な同時実行性が CPU 飽和を引き起こしていないか確認してください。リソースを大量に消費するクエリを最適化するか、同時実行性を減らして CPU 使用率を下げてください。