このトピックでは、PolarDB for PostgreSQL のリソースマネージャー機能について説明します。
適用範囲
以下のバージョンの PolarDB for PostgreSQL がサポートされています。
PostgreSQL 18 (マイナーエンジンバージョン 2.0.18.0.1.0 以降)
PostgreSQL 17 (マイナーエンジンバージョン 2.0.17.2.1.0 以降)
PostgreSQL 16 (マイナーエンジンバージョン 2.0.16.3.1.1 以降)
PostgreSQL 15 (マイナーエンジンバージョン 2.0.15.7.2.0 以降)
PostgreSQL 14 (マイナーエンジンバージョン 2.0.14.5.1.0 以降)
PostgreSQL 11 (マイナーエンジンバージョン 2.0.11.2.1.0 以降)
マイナーエンジンバージョンは、コンソールで確認するか、SHOW polardb_version; 文を実行して確認できます。ご利用のマイナーエンジンバージョンが要件を満たしていない場合は、マイナーエンジンバージョンをアップグレードする必要があります。
背景情報
PolarDB for PostgreSQL クラスターのメモリは、次の 3 つの部分に分かれています:
共有メモリ
動的共有メモリ
プライベートメモリ
動的共有メモリとプライベートメモリは動的に割り当てられます。これらの使用量は、クラスターのワークロードに基づいて変動します。動的メモリとプライベートメモリの使用量が過剰になると、総メモリ使用量がオペレーティングシステムの制限を超える可能性があります。これにより、カーネルのメモリ制限メカニズムがトリガーされ、クラスタープロセスの予期せぬ終了、クラスターの再起動、またはクラスターが利用不可になる可能性があります。
プライベートメモリ内の MemoryContext によって管理されるメモリは、次の 2 つの部分に分けることができます:
作業計算領域メモリは、サービスの正常な運用に必要なメモリです。
キャッシュメモリ:データベースプロセスが内部メタデータをキャッシュするために使用されます。このメモリの使用量は、データベースのパフォーマンスにのみ影響します。
これらの問題に対処するため、PolarDB for PostgreSQL にはリソースマネージャー機能が搭載されています。この機能は、クラスターの実行中にリソース使用量を定期的にチェックします。プロセスがリソースのしきい値を超えた場合、リソースマネージャーはそのプロセスに制限を適用し、クラスターが使用不可になるリスクを軽減します。
リソースマネージャーはメモリ、CPU、I/O リソースを制限できますが、現在サポートされているのはメモリ制限のみです。
仕組み
メモリ制限は cgroups に依存しています。cgroups が利用できない場合、リソース制限を効果的に適用することはできません。リソースマネージャーは、PolarDB for PostgreSQL のバックグラウンドデーモンプロセスです。cgroups から定期的にメモリ使用量データを読み取り、いつメモリ制限を適用するかを判断します。リソースマネージャーがクラスターのメモリ使用量がしきい値を超えたことを検出すると、ユーザープロセスのカーネルのメモリアカウンティングを読み取ります。その後、メモリ使用量でプロセスをソートし、最もメモリを消費しているプロセスから順に、割り込みシグナル (SIGTERM) またはキャンセルシグナル (SIGINT) を送信します。
メモリ制限の仕組み
リソースマネージャーのデーモンプロセスはクラスターとともに起動し、プライマリ (RW)、読み取り専用 (RO)、およびスタンバイノードでアクティブになります。以下のパラメーターを変更することで、リソースマネージャーの動作を変更できます。
リソースマネージャーは次のようにメモリを制限します:クラスターのメモリ使用量がリソースマネージャーのパラメーターで定義されたウォーターマークレベルを超えると、大量のメモリを消費しているプロセスに SIGTERM シグナルを送信します。これにより、プロセスが終了し、メモリが解放されます。次の表に、関連するパラメーターを示します。
パラメーター | 説明 |
polar_resource_manager.enable_resource_manager | リソースマネージャーを有効にするかどうかを指定します。有効値:
|
polar_resource_manager.stat_interva | リソース使用量を定期的にチェックする間隔。単位:ミリ秒。有効値の範囲:10~10000。デフォルト値:500。 |
polar_resource_manager.total_mem_limit_rate | 制限として機能するクラスターのメモリ使用率。クラスターのメモリ使用量がこのパーセンテージを超えると、メモリリソースが強制的に制限されます。デフォルト値:95。 |
polar_resource_manager.total_mem_limit_remain_size | クラスターの予約メモリ量。使用可能なクラスターメモリがこの値を下回ると、メモリリソースが強制的に制限されます。単位:KB。有効値の範囲:0~MAX_KILOBYTES (最大整数値)。デフォルト値:262144。 |
polar_resource_manager.mem_release_policy | メモリリソースを制限するためのポリシー。有効値:
|
例
ユーザーセッションプロセスが SIGTERM シグナルを受信すると、プロセスは終了します。終了に関する情報がログに書き込まれます。以下はログ出力のサンプルです。
2022-11-28 14:07:56.929 UTC [18179] LOG: [polar_resource_manager] terminate process 13461 release memory 65434123 bytes
2022-11-28 14:08:17.143 UTC [35472] FATAL: terminating connection due to out of memory
2022-11-28 14:08:17.143 UTC [35472] BACKTRACE:
postgres: primary: postgres postgres [local] idle(ProcessInterrupts+0x34c) [0xae5fda]
postgres: primary: postgres postgres [local] idle(ProcessClientReadInterrupt+0x3a) [0xae1ad6]
postgres: primary: postgres postgres [local] idle(secure_read+0x209) [0x8c9070]
postgres: primary: postgres postgres [local] idle() [0x8d4565]
postgres: primary: postgres postgres [local] idle(pq_getbyte+0x30) [0x8d4613]
postgres: primary: postgres postgres [local] idle() [0xae1861]
postgres: primary: postgres postgres [local] idle() [0xae1a83]
postgres: primary: postgres postgres [local] idle(PostgresMain+0x8df) [0xae7949]
postgres: primary: postgres postgres [local] idle() [0x9f4c4c]
postgres: primary: postgres postgres [local] idle() [0x9f440c]
postgres: primary: postgres postgres [local] idle() [0x9ef963]
postgres: primary: postgres postgres [local] idle(PostmasterMain+0x1321) [0x9ef18a]
postgres: primary: postgres postgres [local] idle() [0x8dc1f6]
/lib64/libc.so.6(__libc_start_main+0xf5) [0x7f888afff445]
postgres: primary: postgres postgres [local] idle() [0x49d209]