Greenplumにおけるメモリオーバーフローの主なケースと対処法

GreenplumはMPPアーキテクチャを採用した並列処理型データベースであり、大量のメモリを積極的に活用して高速処理を実現する。しかし、メモリ使用量が制御を超えると、セグメントプロセスがOSによって強制終了(OOM Killer)され、クラスタ全体の安定性に深刻な影響を及ぼす可能性がある。

メモリオーバーフローを引き起こす主な要因

  • ノードあたりの物理メモリ不足
  • OSカーネルパラメータ(例:vm.overcommit_memory)の不適切な設定
  • データ分布の偏り(スキュー)により特定セグメントに過大な負荷が集中
  • 集約やウィンドウ関数で分布キー以外のカラムを使用し、再分散時にメモリ需要が急増
  • 統計情報の古さやインデックスの劣化による非効率な実行計画

メモリオーバーフローの回避策

  • SQLクエリの最適化(結合順序、フィルタ条件の改善など)
  • リソースキューによる同時実行クエリ数の制限
  • ホストあたりのセグメント数を減らし、各セグメントの利用可能メモリを増加
  • gp_vmem_protect_limit によるセグメント単位の仮想メモリ上限設定
  • statement_mem をセッション単位で調整し、個別クエリのメモリ使用量を制御

OSカーネルパラメータの推奨設定

Huge PageはGreenplumのPostgreSQLバージョンでは未対応のため無効化すること。また、メモリオーバーコミットポリシーは以下のように設定:

# SWAP使用時は2、未使用時は0を推奨
vm.overcommit_memory = 2
vm.overcommit_ratio = 98  # 計算式に基づき調整

データベースパラメータの要点

  • gp_vmem_protect_limit:1セグメントが使用可能な最大VMEM(MB単位)
  • runaway_detector_activation_percent(デフォルト90):この閾値を超えると高メモリ消費クエリが自動キャンセルされる
  • statement_mem(デフォルト125MB):1クエリが使用可能なメモリ量。超過時はディスクにspill
  • gp_workfile_limit_files_per_query:spillファイル数の上限(デフォルト100,000)。超過時はクエリが中止

メモリパラメータ計算例

256GB RAM + 64GB SWAP のホストで、プライマリ8セグメント+ミラー8セグメントを配置。フェイルオーバー時最大11セグメント稼働を想定:

# 利用可能メモリ総量(経験則に基づく)
gp_vmem = ((256 + 64) - (7.5 + 0.05 * 256)) / 1.7 ≈ 176 GB

# オーバーコミット比
vm.overcommit_ratio = (256 - (0.026 * 176)) / 256 ≈ 98%

# セグメントあたり上限
gp_vmem_protect_limit = (176 * 1024) / 11 ≈ 16384 MB

リソースキューによる制御

リソースキューはLinuxのcgroupと類似した仕組みで、同時実行数やメモリ総量を制限できる:

CREATE RESOURCE QUEUE heavy_queries 
WITH (
  ACTIVE_STATEMENTS = 5,
  MEMORY_LIMIT = '20GB',
  PRIORITY = HIGH
);

注意点として、gp_resqueue_memory_policy = 'auto' の場合、statement_mem がリソースキューの MEMORY_LIMIT より優先される可能性がある。

典型的なエラーケースと対応

ケース1: VMEM使用量が90%超過によるクエリキャンセル

ERROR: Canceling query because of high VMEM usage. Used: 7296MB, available 816MB...

対応策

  • gp_vmem_protect_limit を適正値に再設定(公式計算機利用)
  • 関連テーブルおよびシステムカタログ(pg_classなど)に対して VACUUM/ANALYZE/REINDEX 実施

ケース2: statement_mem不足

ERROR: insufficient memory reserved for statement

対応策:セッション単位で SET statement_mem = '512MB'; を実行

ケース3: OSからのメモリ割り当て失敗

Out of memory. Failed on request of size ... VM Protect failed to allocate ...

原因:gp_vmem_protect_limit が物理メモリ+SWAP容量を超える設定になっている可能性あり。
対応策:OSレベルのメモリ可用性を確認し、パラメータを下方修正

ケース4: spillファイル数超過

ERROR: number of workfiles per query limit exceeded

対応策:spillファイル上限を引き上げるのではなく、まずSQL最適化・データスキュー解消・統計情報更新を実施。根本原因が解消されない限り、単なるパラメータ緩和は一時しのぎに過ぎない。

メモリ使用量の監視

実行中のセッションのメモリ消費状況は以下のビューで確認可能:

SELECT * FROM gp_toolkit.gp_session_state_memory_consumption;

一般的な最適化手順

  1. EXPLAIN ANALYZE で実行計画を確認し、ハッシュ結合やソートのコストを評価
  2. work_mem を一時的に増加(例:SET work_mem = '1GB';)してspillを回避
  3. データ分布キーの見直しと再分散(ALTER TABLE ... SET DISTRIBUTED BY)
  4. 不要な同時実行を抑制するため、ユーザを適切なリソースキューに割り当て

タグ: Greenplum メモリ管理 OOM リソースキュー パラメータチューニング

5月14日 12:35 投稿