19.4. 資源の消費

19.4.1. メモリ

shared_buffers (integer)

データベースサーバが共有メモリバッファのために使用するメモリ量を設定します。 デフォルトは一般的に128メガバイト(128MB)です。 しかし、稼働中のカーネルの設定がこの値をサポートしていない場合、より少なくなることがあります(initdbの過程で決定されます)。 この設定は最低限128キロバイトなければなりません。 (BLCKSZがデフォルト値と異なる場合、この最小値も異なる値になります。) しかし、良い性能を引き出すためには、最小値よりかなり高い値の設定が通例必要です。 このパラメータはサーバ起動時にのみ設定可能です。

1GB以上のRAMを載せた専用データベースサーバを使用している場合、shared_buffersに対する妥当な初期値はシステムメモリの25%です。 shared_buffersをこれよりも大きな値に設定することが有効なワークロードもあります。 しかし、PostgreSQLはオペレーティングシステムキャッシュにも依存するため、shared_buffersにRAMの40%以上を割り当てても、それより小さい値の時より動作が良くなる見込みはありません。 shared_buffersをより大きく設定する場合は、大抵max_wal_sizeも合わせて増やす必要があります。これは、新規または変更された多量のデータを書き出す処理をより長い時間に渡って分散させるためです。

1GB未満のRAMのシステムでは、オペレーティングシステムに十分な余裕を残すために、RAMに対してより小さい割合を設定することが適切です。 また、Windowsでもshared_buffersに対し大きな値を設定することはあまり有効でありません。 設定値を比較的小さく保ち、代わりにオペレーティングシステムのキャッシュを使用することが、より良い結果になるでしょう。 Windowsシステムでの有効なshared_buffersの範囲は一般的に64MBから512MBです。

huge_pages (enum)

huge memoryページの利用を有効/無効にします。 可能な値は try (デフォルト), on, offです。

今のところこの機能はLinuxでのみサポートされています。 他のシステムではtryと設定しても無視されます。

huge pageを使うと、ページテーブルが小さくなり、メモリ管理に使用されるCPU時間が少なくなり、性能が向上します。詳細は、18.4.4. LinuxのHugePagesを見てください。

huge_pagestryに設定すると、サーバはhuge pageの利用を試み、失敗すると通常のアロケーションを行います。 onにすると、huge pageの利用に失敗した場合サーバは起動しなくなります。 offにすると、huge pageは使用されません。

temp_buffers (integer)

それぞれのデータベースセッションが使用する一時バッファの最大数を設定します。 一時バッファは、一時テーブルにアクセスする時にのみ使用されるセッションローカルのバッファです。 デフォルトは8メガバイト(8MB)です。 設定はそれぞれのセッション内で変更できますが、そのセッション内で一時テーブルが最初に使用されるまでになります。それより後に値の変更を試みても、そのセッションでは効果がありません。

セッションは、temp_buffersを上限として、必要に応じて一時バッファを確保します。 多くの一時バッファを実際に必要としないセッションで大きな値を設定するコストとは、temp_buffersの増分毎に、1つのバッファ記述子、約64バイトだけです。 しかし、バッファが実際に使用されると、それに対して追加の8192バイト(汎用的に言えばBLCKSZバイト)が消費されます。

max_prepared_transactions (integer)

同時にプリペアド状態にできるトランザクションの最大数を設定します(PREPARE TRANSACTIONを参照してください)。 このパラメータをゼロ(これがデフォルトです)に設定すると、プリペアドトランザクション機能が無効になります。 このパラメータはサーバ起動時にのみ設定可能です。

プリペアドトランザクションの使用を意図しないのであれば、このパラメータはプリペアドトランザクションが偶然に作成されないようゼロに設定すべきです。 プリペアドトランザクションを使用する場合、全てのセッションがプリペアドトランザクションを保留できるように、max_prepared_transactionsを少なくともmax_connectionsと同じ大きさに設定するのが良いでしょう。

スタンバイサーバを運用している場合、このパラメータはマスターサーバ上の設定よりも同等かもしくはより高水準に設定しなければなりません。そうしないと問い合わせがスタンバイサーバ内で受け入れられません。

work_mem (integer)

一時ディスクファイルに書き込む前に、内部並べ替えとハッシュテーブル操作が使用するメモリ容量を指定します。 デフォルト値は4メガバイト(4MB)です。 複雑な問い合わせの場合、いくつかの並び替えもしくはハッシュ操作が並行して実行されることに注意してください。 それぞれの操作による一時メモリへの書き込み開始の前に、この値が指定するのと同じメモリ容量の使用をそれらの操作に許容します。さらに、いくつかの実行中のセッションはこれらの動作を同時に行います。したがって、使用されるメモリの合計は、work_memの数倍になります。値を選択する時には、この事実に留意することが必要です。並び替え操作はORDER BYDISTINCT、およびマージ結合に対して使われます。ハッシュテーブルはハッシュ結合、ハッシュに基づいた集約、およびIN副問い合わせのハッシュに基づいた処理で使用されます。

maintenance_work_mem (integer)

VACUUMCREATE INDEX、およびALTER TABLE ADD FOREIGN KEYの様な保守操作で使用されるメモリの最大容量を指定します。 デフォルト値は64メガバイト(64MB)です。 1つのデータベースセッションでは、一度に1つしか上記操作はできませんし、通常インストレーションでこうした操作が同時に非常に多く発生することはありませんので、これをwork_memよりもかなり多めの値にしても安全です。 大きい値を設定することでvacuum処理と、ダンプしたデータベースのリストア性能が向上します。

自動バキュームが稼動すると、最大でこのメモリのautovacuum_max_workers倍が配分されるので、デフォルトの値をあまり高く設定しないよう注意してください。 別の設定項目autovacuum_work_memで制御するのが良いかもしれません。

replacement_sort_tuples (integer)

ソート対象のタプル数がこの指定値よりも小さい場合、クイックソートではなく、置換選択法を使ってソート処理の最初のラン出力を作ります。 メモリが限られた環境で、物理から論理への強い相関性を持つタプルが大量のソート処理に投入される場合に有用かもしれません。 なお、入力タプルが相関性を示す場合にはこの限りではありません。 デフォルトの戦略が多数のランを実行してしまい、その結果を最後にマージしなければならないのと違って、置換選択アルゴリズムにおいては、マージを必要としない一つの長いランを実行できる可能性があります。 このことにより、ソート処理を素早く完了できるかもしれません。

デフォルト値は150,000タプルです。 多くの場合、より高い設定値がより良い効率をもたらすどころか、むしろ非生産的かもしれません。 なぜなら、優先度キューは、利用可能なCPUキャッシュの大きさに敏感な一方、デフォルトのソート戦略はキャッシュに縛られない(cache-oblivious)アルゴリズムを使用して実行されるからです。 この性質により、デフォルトのソート戦略では自動的かつ透過的に利用可能なCPUキャッシュを有効に利用できます。

maintenance_work_memをデフォルト値に設定すると、入力タプルの幅が非常に大き場合を除き、通常ユーティリティコマンドが外部ソート(たとえば、CREATE INDEXがB-Treeインデックスを作成するために行うソート)が置換選択アルゴリズムを使うことはなくなります。

autovacuum_work_mem (integer)

個々の自動バキュームワーカプロセスが使用する最大のメモリ量を指定します。 デフォルトは-1で、maintenance_work_memが代わりに使われる設定になります。 別の文脈で実行されるVACUUMにはこの設定は影響しません。

max_stack_depth (integer)

サーバの実行スタックの最大安全深度を指定します。 このパラメータの理想的な設定はカーネルにより強要される実際のスタック容量の(ulimit -sもしくはそれと同等の機能で設定された)限界から、1メガバイト程度の安全余地を差し引いたものです。 安全余地は、サーバがすべてのルーチンではスタック深度を検査をせず、式評価などの主要な潜在的に再帰的なルーチンでのみ検査をするために必要となるものです。 デフォルト設定は2メガバイト(2MB)で、かなり控え目で、クラッシュの危険はなさそうです。 しかし、複雑な関数の実行を許容するには小さ過ぎるかも知れません。 スーパーユーザのみがこの設定を変更することができます。

max_stack_depthを実際のカーネルの制限よりも高い値に設定した場合、暴走した再帰関数により、個々のバックエンドプロセスがクラッシュするかもしれません。 PostgreSQLがカーネルの制限を決定することができるプラットフォームでは、この変数を危険な値に設定させません。 しかし、すべてのプラットフォームがこの情報を提供できるわけではありません。 このため、値を選ぶ時には注意が必要です。

dynamic_shared_memory_type (enum)

サーバが使う動的共有メモリの実装を指定します。可能な値は posix (shm_openで獲得するPOSIX共有メモリ)、 sysv (shmgetで獲得するSystem V共有メモリ)、 windows (Windows共有メモリ)、 mmap (データディレクトリ内のメモリマップファイルを使ってシミュレートする共有メモリ)、 none (この機能を使用しない)です。 すべての値がすべてのプラットフォームでサポートされているわけではありません。 そのプラットフォームでの推奨実装がデフォルトになります。 どのプラットフォームでもデフォルトになっていないmmapは、オペレーティングシステムが変更されたページをディスクに継続的に書き込み、I/O負荷を増加させるので一般的には利用が推奨されていません。 しかし、デバッグ目的のためにpg_dynshmemディスクがRAMディスク上にある場合や、他の共有メモリ機能が使えない場合は有用かもしれません。

19.4.2. ディスク

temp_file_limit (integer)

あるプロセスが一時ファイルとして使用できるディスクの最大容量を設定します。 例えば、ソートやハッシュの一時ファイルであったり、カーソルを保持する格納ファイルです。 この制限値を超えようとするトランザクションはキャンセルされます。 値はキロバイト単位で指定され、(デフォルトである) -1 の場合は制限がありません。 この設定はスーパーユーザのみ変更可能です。

この設定により、ある PostgreSQL セッションによって使用される一時ファイルの合計の容量が常に制約されることになります。 なお、問い合わせの実行において暗黙的に使用される一時ファイルとは異なり、一時テーブルとして明示的に使用されるディスク容量は、この制限には含まれません

19.4.3. カーネル資源使用

max_files_per_process (integer)

それぞれのサーバ子プロセスが同時にオープンできるファイル数の最大値をセットします。 デフォルトは1000ファイルです。 もしもカーネルがプロセス毎の安全制限を強要している場合、この設定を気にかける必要はありません。 しかし、いくつかのプラットフォーム(特にほとんどのBSDシステム)では、もし多くのプロセス全てがそれだけ多くのファイルを開くことを試みたとした場合、実際にサポートできるファイル数より多くのファイルを開くことを許しています。もしもToo many open filesエラーが発生した場合、この設定を削減してみてください。 このパラメータはサーバ起動時にのみ設定可能です。

19.4.4. コストに基づくVacuum遅延

VACUUM および ANALYZE コマンドの実行中、実行される各種I/O操作の予測コストを追跡し続ける内部カウンタをシステムが保守します。 累積されたコストが(vacuum_cost_limitで指定された)限度に達すると、操作を実行しているプロセスはvacuum_cost_delayで指定されたちょっとの間スリープします。その後、カウンタをリセットし、実行を継続します。

この機能の目的は、同時に実行されているデータベースの活動に対するこれらコマンドによるI/Oへの影響を、管理者が軽減できるようにすることです。 VACUUM および ANALYZEの様な保守用コマンドが即座に終了することが重要ではない事態が数多くあります。 しかし、他のデータベースの操作を行うに当たって、これらのコマンドがシステムの能力に多大な阻害を与えないことは通常とても重要です。 コストに基づいたvacuum遅延はこれを実現するための方法を管理者に提供します。

手動で実行したVACUUMコマンドについては、デフォルトでこの機能は無効になっています。 有効にするには、vacuum_cost_delay変数をゼロでない値に設定します。

vacuum_cost_delay (integer)

コストの限度を越えた場合、プロセスがスリープするミリ秒単位の時間の長さです。 デフォルトの値は0で、コストに基づいたvacuum遅延機能を無効にします。 正の整数はコストに基づいたvacuumを有効にします。 多くのシステムで、スリープ遅延の有効な分解能は10ミリ秒です。 vacuum_cost_delayの値の設定を10の倍数としない場合、次に大きい10の倍数に設定した結果と同一になるかもしれないことを覚えておいてください。

コストに基づいたバキューム処理を使用する場合、vacuum_cost_delayの適切な値は通常かなり小さくなり、たいていは10または20ミリ秒になります。 バキュームによるリソース消費の調整は、他のバキュームのコストパラメータを変更して行うことが最善です。

vacuum_cost_page_hit (integer)

共有バッファキャッシュの中のバッファにvacuumを掛ける予測コストです。バッファプールのロック、共有ハッシュテーブルの検索、およびページ内容走査のコストを示します。デフォルトの値は1です。

vacuum_cost_page_miss (integer)

ディスクから読み込まれなければならないバッファにvacuumを掛ける予測コストです。これが示すものは、バッファプールロックの試み、共有ハッシュテーブルの参照、ディスクから目的ブロックの読み込み、そしてその内容走査です。デフォルトの値は10です。

vacuum_cost_page_dirty (integer)

vacuumが、先だって掃除したブロックを変更する時に果たされた予測コストです。 ダーティブロックを再度ディスクに吐き出すのに必要な余分なI/Oを表します。デフォルトの値は20です。

vacuum_cost_limit (integer)

vacuumを掛けるプロセスをスリープさせることになる累計されたコストです。 デフォルトの値は200です。

注記

重要なロックを保有し可能なかぎり早急に完了しなければならないある種の操作があります。コストに基づいたvacuum遅延はこの様な操作では起こりません。 したがって、コストの累計が指定された限度をかなり高く越える可能性があります。 このような場合無駄な長い遅延を防止するため、実際の遅延はvacuum_cost_delay * 4 を上限として、以下のように計算されます。 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit

19.4.5. バックグラウンドライタ

バックグラウンドライタと呼ばれる個別のサーバプロセスがあり、その機能は(新規または更新された)ダーティな共有バッファの書き込みを行うことです。 ユーザの問い合わせを処理するサーバプロセスが、書き込みが起きるまで滅多に待つ必要がない、あるいは決して待つ必要がないように、共有バッファの書き込みを行います。 しかし、バックグラウンドライタは正味の全体的I/O負荷の増加を引き起こします。 その理由は、繰り返しダーティ化されるページは、バックグランドライタを使わなければチェックポイント間隔で一度だけ書き出されれば十分なのに対し、バックグラウンドライタは同じ間隔内で何度もダーティ化されると、それを複数回書き出すかもしれないからです。 本節で説明する各パラメータは、サイト独自の必要に応じて動作を調整することに使用できます。

bgwriter_delay (integer)

バックグラウンドライタの動作周期間の遅延を指定します。 それぞれの周期でライタは、(以下のパラメータで管理される)一部のダーティバッファの書き込みを行います。 そしてbgwriter_delayミリ秒スリープした後、これを繰りかえします。 しかし、バッファプールにダーティバッファが存在しない場合、bgwriter_delayに係わらずより長くスリープします。 デフォルトの値は200ミリ秒(200ms)です。 多くのシステムで、スリープ遅延の実精度は10ミリ秒です。 bgwriter_delayの値の設定を10の倍数としない場合、次に大きい10の倍数に設定した結果と同一になるかもしれないことを覚えておいてください。 このパラメータはpostgresql.confファイル、または、サーバのコマンドラインで設定可能です。

bgwriter_lru_maxpages (integer)

それぞれの周期で、この数以上のバッファはバックグラウンドライタにより書き込まれません。 ゼロに設定することでバックグラウンド書き込みは無効になります。 (分離し、そして専用の補助プロセスにより管理されるチェックポイントは影響を受けません。) デフォルト値は100バッファです。 このパラメータはpostgresql.confファイル内、または、サーバのコマンドラインでのみで設定可能です。

bgwriter_lru_multiplier (floating point)

各周期で書き出されるダーティバッファ数は、最近の周期でサーバプロセスが必要とした新しいバッファ数を基にします。 次の周期で必要となるバッファ数を推定するために、最近必要とされた平均がbgwriter_lru_multiplierと掛け合わせられます。 ダーティバッファの書き出しは、同数の整理済み、再利用可能なバッファが利用できるようになるまで行われます。 (しかし1周期にbgwriter_lru_maxpagesを越えるバッファ数を書き出しません。) したがって、1.0と設定することは、必要と予想されるバッファ数の書き込みについて必要なときに必要なだけというポリシーを表します。 より大きな値は突発的な要求に対する多少の緩衝材を提供します。 より小さな値はサーバプロセスでなされる書き込みを意図的に残します。 デフォルトは2.0です。 このパラメータはpostgresql.confファイル、または、サーバのコマンドラインでのみで設定可能です。

bgwriter_flush_after (integer)

bgwriterがbgwriter_flush_afterバイトより多く書く度に、OSが記憶装置に書き込むことを強制しようとします。 このことにより、カーネルのページキャッシュが持つダーティデータの量を一定量に制限し、チェックポイントの最後にfsyncが実行される際、あるいはOSがバックグラウンドでデータを大きな塊で書き出す際に性能の急激な低下を招く可能性を減らします。 多くの場合これによってトランザクションの遅延が大幅に少なくなりますが、あるケース、特にワークロードがshared_buffersよりも大きく、OSのページキャッシュよりも小さい時には性能が低下するかもしれません。 この設定が無効なプラットフォームがあります。 有効な設定値は、この強制書き込み機能が無効になる0から、2MBまでです。 デフォルト値は、Linuxでは512kBで、それ以外は0です。 (BLCKSZが8kbでなければ、この設定のデフォルト値と最大値がBLCKSZに比例して変更されます。) このパラメータはpostgresql.confファイル、または、サーバのコマンドラインでのみで設定可能です。

bgwriter_lru_maxpagesおよびbgwriter_lru_multiplierの値がより少ないと、バックグラウンドライタで引き起こされる追加のI/O負荷を軽減しますが、サーバプロセスが自分自身で行わなければならない書き込みが増加することになり、会話型問い合わせを遅らせることになります。

19.4.6. 非同期動作

effective_io_concurrency (integer)

PostgreSQLが同時実行可能であると想定する同時ディスクI/O操作の数を設定します。 この値を大きくすると、あらゆる個別のPostgreSQLセッションが並行して開始を試みるI/O操作の数が増加します。 設定可能な範囲は1から1000まで、または非同期I/Oリクエストの発行を無効にするゼロです。 現在、この設定はビットマップヒープスキャンのみに影響します。

磁気ディスクドライブにおいては、データベースに使用されるRAID 0ストライプ、RAID 1ミラーを構成する個々のドライブ数から始めると良いでしょう。(RAID 5ではパリティ用のドライブを数に含めません) しかし、同時実行セッションで発行される複数の問い合わせでデータベースが頻繁にビジーとなる場合、小さめの値で十分ディスクアレイがビジーになるかもしれません。 ディスクをビジーにするのに必要な値より大きな値を設定しても、余計なCPUオーバーヘッドを発生させるだけです。 SSDやそれ以外のメモリーベースの記憶装置は、多くの同時リクエストをこなすことができるので、最適な値は数百になるかもしれません。

非同期I/Oは実質的にposix_fadvise関数に依存します。 これは一部のオペレーティングシステムには存在しません。 この関数が存在しない場合、この値をゼロ以外に設定するとエラーとなります。 一部のオペレーティングシステム(例えばSolaris)では存在するけれども、実際何も行わないものもあります。

デフォルトは、サポートされているシステムでは1、そうでなければ0です。 この値は、テーブルスペースパラメータの同じ名前のパラメータを設定することで、特定のテーブルスペース内のテーブルに対して上書きできます。 (ALTER TABLESPACEを参照ください)。

max_worker_processes (integer)

システムがサポートするバックグラウンドプロセスの最大数を指定します。 このパラメータはサーバ起動時にのみ設定できます。 デフォルトは8です。

スタンバイサーバを起動しているときは、このパラメータを、マスタサーバの設定値と同じかそれ以上にしなければなりません。さもなければ、スタンバイサーバで問い合わせの実行ができなくなります。

max_parallel_workers_per_gather (integer)

一つのGatherノードに対して起動できるワーカー数の最大値を設定します。 パラレルワーカーは、max_worker_processesで確立されたプロセスのプールから取得されます。 実行時には、要求された数のワーカーは取得できないかもしれないことに注意してください。 そうなると、実行プランは期待していたよりも少ない数のワーカーで実行されることになり、効率は悪化するかもしれません。 この設定値をデフォルト値の0にすると、パラレルクエリの実行は行われません。

パラレルクエリの実行により、パラレルクエリではない場合に比べて非常に多くのリソースが使用されるかもしれないことに注意してください。 これは、個々のワーカープロセスは完全に別個のプロセスであり、システムに対してユーザセッションが追加されたのと大体同じくらいの影響があるからです。 この設定値を選択する際には、他のリソースの消費量を制御する他の設定値、たとえばwork_memを設定するときと同様に、この点を考慮しておく必要があります。 work_memのような設定値によるリソース制限は、個々のワーカーに対して個別に適用されます。 つまり、ひとつのプロセス対するよりも、すべてのプロセスの全体のリソース消費はずっと多いかもしれないということです。 たとえば、あるパラレルクエリが4つのワーカーを使っているとすると、ワーカーを使わない場合に比べて、最大5倍のCPU時間、メモリ、I/Oバンド幅、その他を使うかもしれません。

パラレルクエリに関する更なる情報については、15章パラレルクエリをご覧ください。

backend_flush_after (integer)

backend_flush_afterバイトが単一のバックエンドによって書き込まれる度に、OSが記憶装置に書き込むことを強制します。 このことにより、カーネルのページキャッシュが持つダーティデータの量を一定量に制限し、チェックポイントの最後にfsyncが実行される際、あるいはバックグラウンドで実行される大きなバッチの中でOSがデータを書き出す際に性能の急激な低下を招く可能性を減らします。 多くの場合これによってトランザクションの遅延を大幅に少なくなりますが、あるケース、特にワークロードがshared_buffersよりも大きく、OSのページキャッシュよりも小さい時には性能が低下するかもしれません。 この設定が無効なプラットフォームがあります。 有効な設定値は、この強制書き込み機能が無効になる0から、2MBまでです。 デフォルト値は0です(すなわち書き出し制御を行いません)。 (BLCKSZが8kbでなければ、最大値がBLCKSZに比例して変更されます。)

old_snapshot_threshold (integer)

スナップショットが使用されるときに、snapshot too oldエラーを引き起こす危険性なしにスナップショットを利用できる最小時間を設定します。 このパラメータはサーバ起動時にのみ設定できます。

この制限値を越えると、古いデータはバキュームされます。 これにより、長い間残っていたスナップショットによりデータが溢れてしまうのを防ぐことができます。 スナップショットから見えるデータが消えることによる不正な結果を防ぐため、スナップショットがこの制限値よりも古く、かつこのスナップショットが作られた以降に変更されたページを読むためにスナップショットが使用されるときはエラーが発生します。

-1を設定するとこの機能が無効になります。 これがデフォルトです。 実際の環境でのおすすめの値はおそらく数時間から2, 3日の間となるでしょう。 設定値は、分の粒度に書き換えられます。 小さな値(たとえば01min)は、テストの際に有用だということで許可されています。 60dのような大きな値の設定もできますが、多くのワークロードにおいて、大きなデータ溢れやトランザクションIDの周回がそれよりはずっと短い期間で起こる可能性があることに注意してください。

この機能が有効であると、リレーションの終端部にあるフリースペースはオペレーティングシステムには返却されません。 そうしないと、snapshot too oldの条件の検出に必要な情報を削除してしまうことになるからです。 明示的に解放されない限り(たとえばVACUUM FULLによって)、リレーションに割り当てられた領域は、そのリレーションの中での再利用に限定して紐付けられます。

この設定は、どのような状況でもエラーが検出されることを保証するものではありません。 (たとえば)マテリアライズされた結果集合を持つカーソルから正しい結果を得ることができるのであれば、たとえ参照している元のテーブルからVACUUMによって行が削除されたとしてもエラーにはなりません。 ある種のテーブルでは、早期にVACUUMできないので、この設定の影響を受けません。 例としては、システムカタログやハッシュインデックスが貼られたテーブルが挙げられます。 このようなテーブルにおいては、この設定によってデータ溢れを防ぐことも、スキャンの際にsnapshot too oldエラーを起こす可能性を作り出すこともできません。