はじめに
にゃーん。趣味でポスグレをやっている者だ。
今回はPostgreSQL 16のinitdbに追加されたGUC設定機能について書いてみました。
概要
項目 | 内容 |
---|---|
タイトル | Set arbitrary GUC options during initdb |
Topic | System Administration |
Last Modified | 2023-03-22 |
ステータス | commited |
概要 | initdb時に生成されるGUCをオプションで指定可能になった。 |
変更内容
PostgreSQLサーバアプリケーションinitdb
に任意のGUCを渡すオプションが追加されました。
-c name=value
--set name=value
複数のGUCを設定する場合には、このオプションを複数指定します。
initdb --help
でもこのオプションが表示されます。
$ initdb --help
initdb initializes a PostgreSQL database cluster.
Usage:
initdb [OPTION]... [DATADIR]
(略)
Less commonly used options:
-c, --set NAME=VALUE override default setting for server parameter
-d, --debug generate lots of debugging output
--discard-caches set debug_discard_caches=1
(略)
Report bugs to <pgsql-bugs@lists.postgresql.org>.
PostgreSQL home page: <https://www.postgresql.org/>
$
実行例
オプション指定の例
任意のportを指定する
自分が自宅でレプリケーション検証をするときには、同一サーバ上で異なるport
を指定したデータベースクラスタを複数生成して検証しています。
また、複数のバージョンを同一サーバ上で動かしているので、バージョンごとにport
を変える必要があり、initdb
後のport
変更(echo "port=xxxxx" >> $PGDATA/postgresql.conf
)を毎回のようにやっていました。
※ちなみに自分のport付与規則は先頭2桁をメジャーバージョン番号、以降3桁は用途に応じた通番をつけてます)
PostgreSQL 16のinitdbでは以下のように実行することで、指定したportの値をpostgresql.confに書き込んでくれます。ちょっと便利。
$ ~/pgsql/master/bin/initdb -c "port=16001" -U postgres -D /tmp/pg16-1
(略)
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Asia/Tokyo
creating configuration files ... ok
(略)
Success. You can now start the database server using:
/home/ec2-user/pgsql/master/bin/pg_ctl -D /tmp/pg16-1 -l logfile start
$
-c
オプションで指定したGUCについては生成時のログには特に出力されないようですね。-d
(debugオプション)付与時にも出力はされないようです。
さて、データベースクラスタが無事に生成されたので、データベースクラスタディレクトリ直下のpostgresql.conf内のportがデフォルトの5432ではなく、指定した16001になっているか確認します。
$ grep -n "port = " /tmp/pg16-1/postgresql.conf
64:port = 16001 # (change requires restart)
$
きちんとpostgresql.conf内のportの値が16001になっています。
portを設定している行数は64なので、末尾に追加しているというわけではなく、postgresql.confファイルの生成途中に、-c
オプションによる設定をしているようです。
複数のGUCを設定する例
今度はport
(デフォルト5432)を16002に、shared_buffers
(今の環境だとデフォルト128MB)の設定を65536kB(=64MB)に変更してみます。
複数のGUCを指定する場合には、-c name=value
の組を複数指定します。
$ ~/pgsql/master/bin/initdb -c "port=16002" -c "shared_buffers=65536kB" -U postgres -D /tmp/pg16-2
(略)
creating directory /tmp/pg16-2 ... okcreating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Asia/Tokyo
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
(略)
Success. You can now start the database server using:
/home/ec2-user/pgsql/master/bin/pg_ctl -D /tmp/pg16-2 -l logfile start
$
shared_buffers
がシステムデフォルトの12MBで生成したかのように表示が見えちゃうのがあれですが・・・。
無事に生成されたのでpostgresql.confの内容を確認します。
$ egrep -n '(port = |shared_buffers = )' /tmp/pg16-2/postgresql.conf
64:port = 16002 # (change requires restart)
130:shared_buffers = 65536kB # min 128kB
$
指定したport
とshared_buffers
がpostgresql.confに書き込まれています。
shared_buffersに指定した65536kBは64MBには変換されずそのまま書き込まれているようですね。
同じGUCを複数指定した場合
同じGUCを複数指定した場合は、最後に指定したものが有効になるようです。
$ ~/pgsql/master/bin/initdb -c "port=16002" -c "port=16003" -c "port=16001" -U postgres -D /tmp/pg16
(略)
/home/ec2-user/pgsql/master/bin/pg_ctl -D /tmp/pg16 -l logfile start
$ grep -n "port = " /tmp/pg16/postgresql.conf
64:port = 16001 # (change requires restart)
$
存在しないオプションを指定した場合
存在しないオプションを指定した場合は、initdb
実行時にエラーになります。
$ ~/pgsql/master/bin/initdb -D /tmp/pg16-1 -U postgres -c "hoge=5432"
(略)
creating configuration files ... ok
running bootstrap script ... 2023-05-19 11:22:51.222 GMT [557] LOG: unrecognized configuration parameter "hoge" in file "/tmp/pg16-1/postgresql.conf" line 821
2023-05-19 11:22:51.222 GMT [557] FATAL: configuration file "/tmp/pg16-1/postgresql.conf" contains errors
child process exited with exit code 1
initdb: removing data directory "/tmp/pg16-1"
$
不正な値を指定した場合
不正な値を指定した場合にもinitdb
実行時にエラーになります。きちんと値域もチェックしているようですね。
$ ~/pgsql/master/bin/initdb -D /tmp/pg16-1 -U postgres -c "port=0"
(略)
creating configuration files ... ok
running bootstrap script ... 2023-05-19 11:25:31.982 GMT [681] LOG: 0 is outside the valid range for parameter "port" (1 .. 65535)
2023-05-19 20:25:31.982 JST [681] FATAL: configuration file "/tmp/pg16-1/postgresql.conf" contains errors
child process exited with exit code 1
initdb: removing data directory "/tmp/pg16-1"
$
おわりに
普通にPostgreSQLを運用する場合には、最初の1回だけ実行するinitdb
ですが、検証時にはしばしばデータベースクラスタを再生成することがあります。そういうときに、GUCが指定できるのはありがたい機能ですね。
PostgreSQL 16のお気に入り新機能になりそうです。