インスタンスタイプを変更したときにPostgreSQLのDB設定も変更したい
PostgreSQLをAWS RDSではなくAWS EC2上で動かすとき、インスタンスタイプに応じてDB設定(postgresql.conf)を変えたいことがある。
例えば低スペックで良いときはt3.mediumで、高スペックが必要なときはr5a.xlargeで、というようなときである。
このときDB側もshared_buffersやwork_memといったメモリ関連のパラメータをインスタンスのメモリ容量に合わせて変更したいときどうすれば良いか。
インスタンスタイプ(メモリ容量)に応じてpostgresql.confを用意しておき、サービス起動時にインスタンスタイプを確認して読み込むpostgresql.confを選択する、という方法がある。
下記にその方法について書いておく。
インスタンスタイプを確認し、DB起動時にpostgresql.confを指定する
手順としてDBはEC2インスタンス起動時にsystemdのサービスファイルによって自動起動されることを想定している。
DB起動用のシェルを作成する
下記のようにDBを起動するためのシェルを作成し、それをサービスファイルから呼び出す形になる。
#!/bin/bash
INSTANCE_TYPE=`curl -s http://169.254.169.254/latest/meta-data/instance-type`
if [ "${INSTANCE_TYPE}" = "t3.medium" ]; then
CONFIG_FILE=${PGDATA}/postgresql_lowspec.conf
else
CONFIG_FILE=${PGDATA}/postgresql.conf
fi
exec /usr/pgsql-13/bin/postmaster -D ${PGDATA} -c config_file=${CONFIG_FILE}
インスタンスタイプはEC2インスタンスのメタデータから取得することができる。
これをサービスファイルがあるディレクトリに作っておく。
[root@host ~]# cd /usr/lib/systemd/system
[root@host system]# vi run_postgres.sh
[root@host system]# chmod +x run_postgres.sh
サービスファイルを変更する
次に作成したこのシェルをPostgreSQLのサービスファイルから実行するようにする。
[root@host system]# vi postgresql-13.service
# サービスファイルの変更箇所
# DBクラスタがデフォルトの格納先ではない場合
Enviroment=PGDATA=(格納先のdataディレクトリのパス)
# systemctl start する時の設定
# ExecStart=/usr/pgsql-13/bin/pg_ctl start -D ${PGDATA} -s -w -t 300
ExecStart=/usr/lib/systemd/system/run_postgres.sh
# タイムアウトの無効化
TimeoutSec=0
これにより systemctl start postgresql-13 としたときにrun_postgres.shが呼び出され、
インスタンスタイプに対して設定したpostgresql.confファイルが読み込まれることになる。
ただしこの方法では1点注意するところがある。
run_postgres.shの中にあるようにpostmasterでDBを起動するとカーソルがコンソールに戻ってこない。
コマンドの終了宣言がされず、処理待ちのような状態になってしまう。
そのためサービスファイル内で TimeoutSec=0 のようにタイムアウトを無効化する必要がある。
仮に TimeoutSec=300 のように設定されている場合、起動してから300秒後にDBが停止する。
Systemdではrun_postgres.shから終了宣言が帰ってこないためタイムアウトで失敗とみなし、ステータス:failed としてサービスを停止させるのである。
※タイムアウトを無効化することで回避はできるが、ここらへんちゃんと解決する方法があったら教えてほしい。