2012年12月1日

PostgreSQL初期設定これだけは変えておこう

PostgreSQL Advent Calendar 2012(全部俺)のDay 1です。

初日は、まずPostgreSQLを使い始める際の基本的なお作法である初期設定について簡単にまとめてみます。

PostgreSQLは、パラメータの設定を変更せずにデフォルトの設定のまま使い始めても、もちろん動くことは動くのですが、後からいろいろと問題が出てくることもありますし、特に性能関連のパラメータのデフォルト値はあまりに小さく、チューニング云々以前の問題だったりします。

というわけで、私が普段PostgreSQLをインストールして使い始める時、開発機であってもいくつかパラメータを初期設定するようにしています。

使い始める前に設定から入るのは確かに面倒なのですが、最初に設定が必要なパラメータは少数(今回紹介するのは5つ)ですので、まずは最初に必要最低限の設定をしてから使い始めましょう、というのが本エントリの趣旨です。

■設定するパラメータの種類


最初に設定を行うPostgreSQLのパラメータには、大きく分けて

・メモリ(バッファ)関連
・チェックポイント関連
・サーバログ関連

というカテゴリがあります。これらについて以下に順番に解説していきます。

■メモリ(バッファ)関連


まずは、メモリ(バッファ)関連のパラメータです。メモリ関連のパラメータは2つあります。

これらのパラメータは、「バッファ関連」とあるように、データをバッファリングするメモリ領域のサイズを指定するものです。データベースはディスクI/Oの処理が多いので、バッファの仕組みをうまく使うことがパフォーマンス上、非常に重要になります。そのため、この値が小さすぎると「パフォーマンスが全然出ない」という状況に陥ります。

一つ目は「shared_buffers」です。これは「共有バッファ」と呼ばれる、テーブルやインデックスのデータを8kbのブロック単位でバッファリングするメモリ領域のサイズを指定するパラメータです。


shared_buffersのデフォルトでは32MBとなっていますが、この設定値は現在のハードウェアの標準から考えるとあまりに小さすぎる値です。私は初期値として物理メモリの1/4~1/2程度のサイズを割り当てるようにしています。(最適な値はハードウェアの構成やデータベースのサイズなどにも依存しますのでチューニングが必要です。)

二つ目は「wal_buffers」です。これは「トランザクションログ(WAL)」と呼ばれるファイルをディスクに書き出す時にバッファリングされるメモリ領域です。

デフォルトでは先に紹介したshared_buffersの「1/32」のサイズに設定されます。例えば、shared_buffersを1GB割り当てたのであれば、wal_buffersは32MBになりますし、shared_buffersがデフォルトの32MBだった場合にはwal_buffersは1MBとなります。

wal_buffersの適正値を簡単に知る方法は今のところ提供されていないのですが、私自身は初期設定としては16~32MB程度を割り当てるようにしています。(9.3からはwal_buffersの利用状況を計測できる機能が提供される予定です。私のパッチが取り込まれれば・・)

■チェックポイント関連


二番目のカテゴリがチェックポイント関連のパラメータです。チェックポイント関連のパラメータも2つあります。

「チェックポイント」というのは、共有バッファの内容をディスクに一括して書き出す(フラッシュ)処理になります。つまり、チェックポイント処理を行うことによって、共有バッファの内容がディスクに保存されていることを保証できるようになるのです。ただし、チェックポイントはディスクへの書き出しを行う処理ですから、当然処理は重くなりますし、これが頻発するとデータベースのパフォーマンスが低下することになります。そのため、ここで紹介するパラメータは「チェックポイントをどの程度の間隔で発生させるか」という設定になります。

まず一つ目が「checkpoint_segments」です。これは、「いくつのトランザクションログファイルを消費したらチェックポイントを発生させるか」という設定になります。

トランザクションログのファイルはひとつ16MBであり、checkpoint_segmentsのデフォルト値は「3」ですので、デフォルトの設定だと48MB(16MB×3)のトランザクションログを書くとチェックポイントが発生することになります。しかし、この設定のままだとチェックポイントが頻発してしまうことがあります。私は、checkpoint_segmentsに64~128程度を初期値として設定することにしています。

なお、チェックポイントが頻発すると、PostgreSQLがサーバログに以下のようなメッセージを出すことがありますので、このメッセージが出た時にはチェックポイントの設定を見直す必要があるかもしれません。
LOG:  checkpoints are occurring too frequently (19 seconds apart) 
HINT:  Consider increasing the configuration parameter "checkpoint_segments". 
二つ目は「checkpoint_timeout」というパラメータです。これは、チェックポイント発生する間隔を「時間」で指定するものです。

checkpoint_timeoutのデフォルト値は「5分(5m)」になっていますが、これも少し短すぎるので私は「60分(60m)」を初期値として設定するようにしています。

■サーバログ関連


三つ目のカテゴリがサーバログに関するパラメータです。ここでは「log_line_prefix」というパラメータをひとつだけ紹介します。

「log_line_prefix」というパラメータは、PostgreSQLサーバが出力するサーバログの各行の先頭部分に何を付加して出力するか、という設定です。

PostgreSQLのサーバログは、デフォルトの設定ではタイムスタンプやプロセスIDといった「サーバログとして当然必要な情報」が出力されません。そのため、開発中であっても何かを分析する時に困ってしまうことがあります。そのため、私は log_line_prefix には最低限、タイムスタンプとプロセスIDを出力するように以下のように設定しています。
log_line_prefix = '[%t] %p: '

■check_pg_settings.sql


上記の設定項目を設定するのは知っている人にとっては簡単ですが、慣れてない人にとっては面倒で、かつ見落としが出ることもあるかと思います。

というわけで、設定をチェックしてくれる check_pg_settings.sql というSQLスクリプトを作ってみました。(かなり強引なスクリプトですが・・・)

https://gist.github.com/4179435

これをPostgreSQLに対して以下のように実行します。
psql -f check_pg_settings.sql postgres
そうすると、以下のようにいろいろ警告やらアドバイスやらを出してくれます(このエントリでは割愛しましたが、スクリプトではアーカイブログの設定についてもチェックしてます)。
        name         |  setting   |                                      result
---------------------+------------+-----------------------------------------------------------------------------------
 shared_buffers      | 1024       | WARNING: too small. (<65536=512MB)
 wal_buffers         | 8          | WARNING: too small. (<1024=8MB)
 checkpoint_segments | 3          | WARNING: default value (3) is too small.
 checkpoint_timeout  | 300        | WARNING: default value (300=5m) is too small.
 wal_level           | minimal    | WARNING: `minimal' cannot enable archive log mode.
 archive_mode        | off        | WARNING: archive log mode is disabled.
 archive_command     | (disabled) | WARNING: archive log mode is disabled.
 archive_timeout     | 0          | WARNING: archive timeout is disabled.
 log_line_prefix     |            | WARNING: empty by the default. need to have pid (%p) and timestamp (%t) at least.
(9 rows)
全体的に「値がちっちゃいよ!」と言われてしまってますね。

で、この結果を見ながら設定をポチポチ直していくことができるわけです。

ウッカリさんには嬉しいスクリプトですね(多分)。

■まとめ


というわけで、まずは使い始める前に「適当な」設定をするための設定項目とその中身を簡単にまとめてみました。

もちろん、これ以外にも設定項目はいろいろあります。「アーカイブログはどうした」とか、「ログのローテートは」とかあるかと思いますが、ミニマルな設定、という意味ではこれくらいが妥当なのではないかと思います。

ではまた明日。

0 件のコメント:

コメントを投稿