PostgreSQL 9.6.3をRHEL 7.3(AWSのEC2)のSystemdで起動管理する
目次
概要
Red Hat Enterprise LinuxではLinuxを構成する各種サービス(プロセス)の起動管理にinitシステムを利用していました。 バージョン7からinitがSystemdに置き換わり、RHEL 7向けのRPMパッケージをインストールすると、Systemdでの起動管理に 必要なファイル(サービスユニットファイル)がインストールされます(インストールされないミドルウェアもありますが)。
PostgreSQLでもコミュニティサイト(https://yum.postgresql.org/rpmchart.php)からダウンロードしたRPMパッケージを使用してインストールを実行すると、 Systemdには /usr/lib/systemd/system/postgresql-9.6.service というファイルによって、postgresql-9.6.serviceという名の サービスユニットが登録されます。
デフォルトのサービスユニットファイルを編集して利用してもいいのですが、 今回検証したサーバではデータベースクラスタ(PGDATA)をデフォルトから変更してPostgreSQLをセットアップしていたことと、 起動停止コマンドはマスタサーバプロセスであるpostgresをコマンドで直接起動するより、 pg_ctlコマンドで間接的に起動する方法の方が馴染みがあったので、大幅に編集するぐらいならSystemdの勉強も兼ねて ゼロからサービスユニットファイルを作成することにしました(今回はあえてそうしました)。 通常はデフォルトのサービスユニットファイルを編集して使えば問題ありません。 今回はあくまで Systemd のお勉強が目的となっています。
デフォルトで登録されているpostgresql-9.6.serviceは初期状態で自動起動がオンとなっているため、自動起動をオフに変更しておきます。
構成
想定環境
AWS(Amazon Web Services)のEC2上にインストール済みのPostgreSQL 9.6.3の環境を利用してSystemdの動作を確認しました。 PostgreSQLのコミュニティサイトからダウンロードしたrpmを元にインストール済みの状態から始めます。 参考までに、サーバのスペックは以下のとおりです。項目 | 内容 |
---|---|
インスタンスタイプ | t2.micro |
vCPU | 1 |
メモリ | 1GB |
ディスク | SSD 10GiB |
リージョン | 日本 |
また、セットアップ済みのPostgreSQLの主な設定は以下の通りです。
データベースクラスタ | /data/pgdata1 |
---|
サーバ構成
OSバージョン
Red Hat Enterprise Linux 7.3 x86_64
ソフトウェア・パッケージ一覧
- postgresql96-9.6.3-1PGDG.rhel7.x86_64.rpm
- postgresql96-libs-9.6.3-1PGDG.rhel7.x86_64.rpm
- postgresql96-server-9.6.3-1PGDG.rhel7.x86_64.rpm
環境構築
設定
デフォルトのサービスユニットの自動起動をオフにする
PostgreSQLのデフォルトのサービスユニットの自動起動をオフにします。
$ sudo su - ←rootユーザで作業する
# systemctl disable postgresql-9.6
Removed symlink /etc/systemd/system/multi-user.target.wants/postgresql-9.6.service.
サービスユニットファイルの作成
PostgreSQLのサービスユニットファイルを新規に作成します。 起動する対象のデータベースクラスタ($PGDATA)は環境設定ファイルから読み込む形にします。
Last login: Sat Aug 26 12:30:53 EDT 2017 on pts/0
# cd /etc/systemd/system/
# vi postgresql.service ←ファイルを新規作成
※ファイルを新規作成※
[Unit]
Description=PostgreSQL database server
After=network.target
[Service]
Type=forking
User=postgres
EnvironmentFile=/etc/sysconfig/pgsql/postgresql
ExecStart=/usr/pgsql-9.6/bin/pg_ctl start -w -D $PGDATA
ExecReload=/usr/pgsql-9.6/bin/pg_ctl reload -D $PGDATA
ExecStop=/usr/pgsql-9.6/bin/pg_ctl stop -m fast -D $PGDATA
[Install]
WantedBy=multi-user.target
Systemdで参照する環境設定ファイルの作成
PostgreSQL用のサービスユニットファイルから参照される環境設定ファイルを作成します。 PostgreSQLをインストールすると /etc/sysconfig/pgsql/ というディレクトリが自動で作成されるので、 このディレクトリ内に postgresql という名前の環境設定ファイルを作成します。 この設定ファイル内ではSystemdから起動する対象のデータベースクラスタ(ディレクトリ)を設定します。
# cd /etc/sysconfig/pgsql/
# vi postgresql ←ファイルを新規作成
※新規作成※
PGDATA=/data/pgdata1
Systemdから設定ファイルの認識確認
必要な設定ファイルがを作成したので、Systemdからサービスユニットが認識されているか確認します。 以下のようにサービスの状態が表示されたら一旦は成功です。
# systemctl status postgresql ● postgresql.service - PostgreSQL database server Loaded: loaded (/etc/systemd/system/postgresql.service; disabled; vendor preset: disabled) ←自動起動オフ Active: inactive (dead) ←停止状態 Docs: man:postgres(1) Aug 26 12:41:03 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: [/etc/systemd/system/postgresql.service...Nt Aug 26 12:41:03 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: [/etc/systemd/system/postgresql.service...e' Hint: Some lines were ellipsized, use -l to show in full.
SystemdからPostgreSQLの起動
SystemdからPostgreSQLを起動します。起動には systemctl コマンドを利用します。 実行後にステータスを確認し、Active: active (running) と表示されたら成功です。
# systemctl start postgresql # systemctl status postgresql ● postgresql.service - PostgreSQL database server Loaded: loaded (/etc/systemd/system/postgresql.service; disabled; vendor preset: disabled) ←自動起動オフ Active: active (running) since Sun 2017-08-27 03:27:29 EDT; 37s ago ←起動状態 Main PID: 2546 (postgres) CGroup: /system.slice/postgresql.service tq2546 /usr/pgsql-9.6/bin/postgres -D /data/pgdata1 tq2547 postgres: logger process tq2549 postgres: checkpointer process tq2550 postgres: writer process tq2551 postgres: wal writer process tq2552 postgres: autovacuum launcher process mq2553 postgres: stats collector process Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Starting PostgreSQL database server... Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal pg_ctl[2544]: waiting for server to start....2017-08-27 03:27:28 EDT [2546] LOG: redirecting log output to logging collector process Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal pg_ctl[2544]: 2017-08-27 03:27:28 EDT [2546] HINT: Future log output will appear in directory "pg_log". Aug 27 03:27:29 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Started PostgreSQL database server.
PostgreSQLの自動起動設定
続いてLinux起動時にPostgreSQLを自動起動するよう設定します。 実行後にステータスを確認し、Loaded: loaded (/etc/systemd/system/postgresql.service; enabled のようにenabledと表示されたら成功です。
# systemctl enable postgresql Created symlink from /etc/systemd/system/multi-user.target.wants/postgresql.service to /etc/systemd/system/postgresql.service. # systemctl status postgresql ● postgresql.service - PostgreSQL database server Loaded: loaded (/etc/systemd/system/postgresql.service; enabled; vendor preset: disabled) ←自動起動オン Active: active (running) since Sun 2017-08-27 03:27:29 EDT; 1min 55s ago ←起動状態 Main PID: 2546 (postgres) CGroup: /system.slice/postgresql.service tq2546 /usr/pgsql-9.6/bin/postgres -D /data/pgdata1 tq2547 postgres: logger process tq2549 postgres: checkpointer process tq2550 postgres: writer process tq2551 postgres: wal writer process tq2552 postgres: autovacuum launcher process mq2553 postgres: stats collector process Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Starting PostgreSQL database server... Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal pg_ctl[2544]: waiting for server to start....2017-08-27 03:27:28 EDT [2546] LOG: redirecting log output to logging collector process Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal pg_ctl[2544]: 2017-08-27 03:27:28 EDT [2546] HINT: Future log output will appear in directory "pg_log". Aug 27 03:27:29 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Started PostgreSQL database server.
SystemdからPostgreSQLの停止
起動が成功したので停止も確認します。 実行後にステータスを確認し、Active: inactive (dead) と表示されたら成功です。
# systemctl stop postgresql # systemctl status postgresql ● postgresql.service - PostgreSQL database server Loaded: loaded (/etc/systemd/system/postgresql.service; enabled; vendor preset: disabled) ←自動起動オン Active: inactive (dead) since Sun 2017-08-27 03:30:00 EDT; 6s ago ←停止状態 Process: 2603 ExecStop=/usr/pgsql-9.6/bin/pg_ctl stop -m fast -D $PGDATA (code=exited, status=0/SUCCESS) Main PID: 2546 (code=exited, status=0/SUCCESS) Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Starting PostgreSQL database server... Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal pg_ctl[2544]: waiting for server to start....2017-08-27 03:27:28 EDT [2546] LOG: redirecting log output to logging collector process Aug 27 03:27:28 ip-172-31-27-90.ap-northeast-1.compute.internal pg_ctl[2544]: 2017-08-27 03:27:28 EDT [2546] HINT: Future log output will appear in directory "pg_log". Aug 27 03:27:29 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Started PostgreSQL database server. Aug 27 03:29:59 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Stopping PostgreSQL database server... Aug 27 03:30:00 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Stopped PostgreSQL database server.
SystemdからPostgreSQLの設定の再読み込み
最後に設定の再読み込み(リロード)を確認します。上の手順でPostgreSQLを停止したので、先に起動したうえで設定の再読み込みを行います。 なお、PostgreSQLが停止した状態で再読み込みを実行しても失敗します。 設定の再読み込みはSystemdから見たステータスの変化はありませんが、ログとして systemd[1]: Reloaded PostgreSQL database server. と表示されたら成功とします。
# systemctl start postgresql # systemctl reload postgresql # systemctl status postgresql ● postgresql.service - PostgreSQL database server Loaded: loaded (/etc/systemd/system/postgresql.service; enabled; vendor preset: disabled) ←自動起動オン Active: active (running) since Sun 2017-08-27 10:06:11 EDT; 3min 18s ago ←停止状態 Process: 2603 ExecStop=/usr/pgsql-9.6/bin/pg_ctl stop -m fast -D $PGDATA (code=exited, status=0/SUCCESS) Process: 4722 ExecReload=/usr/pgsql-9.6/bin/pg_ctl reload -D $PGDATA (code=exited, status=0/SUCCESS) Process: 4696 ExecStart=/usr/pgsql-9.6/bin/pg_ctl start -w -D $PGDATA (code=exited, status=0/SUCCESS) Main PID: 4698 (postgres) CGroup: /system.slice/postgresql.service tq4698 /usr/pgsql-9.6/bin/postgres -D /data/pgdata1 tq4699 postgres: logger process tq4701 postgres: checkpointer process tq4702 postgres: writer process tq4703 postgres: wal writer process tq4704 postgres: autovacuum launcher process mq4705 postgres: stats collector process Aug 27 10:06:10 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Starting PostgreSQL database server... Aug 27 10:06:10 ip-172-31-27-90.ap-northeast-1.compute.internal pg_ctl[4696]: waiting for server to start....2017-08-27 10:06:10 EDT [4698] LOG: redirecting log output to logging collector process Aug 27 10:06:10 ip-172-31-27-90.ap-northeast-1.compute.internal pg_ctl[4696]: 2017-08-27 10:06:10 EDT [4698] HINT: Future log output will appear in directory "pg_log". Aug 27 10:06:11 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Started PostgreSQL database server. Aug 27 10:09:17 ip-172-31-27-90.ap-northeast-1.compute.internal systemd[1]: Reloaded PostgreSQL database server. ←設定がリロードされた
(補足) サービスユニットファイルを編集した場合
サービスユニットファイルを作成してSystemdから起動しようとしたけど失敗した・・・。 ファイルを編集して再度起動を試みる・・・、という繰り返しは何度か発生するものだと思います。 ここで、ファイルを編集したあとはSystemdにサービスユニットファイルが変更されたことを通知する必要があります。 その時に実行するのが以下のコマンドです。サービスユニットファイルの編集後に実行するのをお忘れなく。
# systemctl daemon-reload