OSS Fan ~OSSでLinuxサーバ構築~

このエントリーをはてなブックマークに追加

PostgreSQL 9.4.8をCentOS 7.2へインストールしてストリーミングレプリケーションのスタンバイサーバ構築

カテゴリ:OSSセットアップ | ソフトウェア:PostgreSQL | タグ:
最終更新日:2020/12/31 | 公開日:2016/07/25

目次

概要

 PostgreSQLのサーバを2台準備し、ストリーミングレプリケーションを構成します。 2台のうち1台目をマスタサーバとして、通常通りデータの参照、更新を行えるようにします。 2台目をスタンバイサーバとして、マスタサーバでのデータ更新を非同期で取り込むようにします。 なお、スタンバイサーバはホットスタンバイとして構成することで、更新(insert文、updatet文等)はできませんが、参照(select文)のみ行えるようにします。

 運用形態としては、マスタサーバで本番運用し、マスタサーバが障害時にスタンバイサーバをマスタに昇格させます。 ただし、ストリーミングレプリケーションの機能だけでスタンバイか自動でマスタに昇格させることはできません。 別途クラスタウェア等を利用してマスタサーバの障害検知、スタンバイのマスタへの昇格を組み込む必要があります。

 今回の手順ではストリーミングレプリケーションの構成をとるところまでとし、 クラスタウェアとの連携は行わないものとします。

 マスタサーバに続いて、スタンバイサーバを構築します。

構成

想定環境

PostgreSQL 9.4.8のストリーミングレプリケーション構成

サーバ構成

OSバージョン

CentOS 7.2.1511 x86_64

パッケージ一覧

  • postgresql94-9.4.8-1PGDG.rhel7.x86_64.rpm
  • postgresql94-libs-9.4.8-1PGDG.rhel7.x86_64.rpm
  • postgresql94-server-9.4.8-1PGDG.rhel7.x86_64.rpm

環境構築

インストール

 PostgreSQLサーバに必要なパッケージを3つインストールします。 CentOS 7.2のインストールメディアに収録されているPostgreSQLパッケージは、バージョン9.2.13と少し古いので、 コミュニティで公開されている、より新しいバージョンを利用します。 2016年7月24日時点での最新バージョンは 9.5.3 ですが、9.5用のJDBCドライバが提供されていなかったので、 9.4の最新マイナーバージョンの 9.4.8 を採用しました。 下記URLよりファイルをダウンロードして /media/installer/ に配置した前提でインストールを開始します。

【関連サイト】
Red Hat系Linux向けPostgreSQL 9.4(x86_64)ダウンロードページ

 以下のコマンドを実行します。

# cd /media/installer/
# ls -l
合計 5228
-rw-r--r-- 1 root root 1087476  7月  7 22:42 postgresql94-9.4.8-1PGDG.rhel7.x86_64.rpm
-rw-r--r-- 1 root root  215152  7月  7 22:43 postgresql94-libs-9.4.8-1PGDG.rhel7.x86_64.rpm
-rw-r--r-- 1 root root 4044904  7月  7 22:44 postgresql94-server-9.4.8-1PGDG.rhel7.x86_64.rpm
# rpm -ihv ./postgresql94-*
警告: ./postgresql94-9.4.8-1PGDG.rhel7.x86_64.rpm: ヘッダー V4 DSA/SHA1 Signature、鍵 ID 442df0f8: NOKEY
準備しています...              ################################# [100%]
更新中 / インストール中...
   1:postgresql94-libs-9.4.8-1PGDG.rhe################################# [ 33%]
   2:postgresql94-9.4.8-1PGDG.rhel7   ################################# [ 67%]
   3:postgresql94-server-9.4.8-1PGDG.r################################# [100%]

設定

postgresユーザのパスワード設定

 PostgreSQLのパッケージをインストールすると、自動で postgres ユーザ(Linuxのユーザ)が作成されます。 作成直後はパスワードが設定されていないため、設定します。

# passwd postgres
ユーザー postgres のパスワードを変更。
新しいパスワード: ←パスワードを入力(表示されません)
新しいパスワードを再入力してください: ←上と同じパスワードを入力(表示されません)
passwd: すべての認証トークンが正しく更新できました。

postgresユーザの環境変数設定

 環境変数としてデータベースクラスタとPostgreSQLのコマンドへのパスを設定します。

# grep postgres /etc/passwd
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
# cd /var/lib/pgsql/
# vi .bash_profile
ファイル名:/var/lib/pgsql/.bash_profile
PGDATA=/var/lib/pgsql/9.4/data
export PGDATA
   ↓変更
PGDATA=/data/pgdata1
export PGDATA

※ファイルの末尾に追加※
export PATH=$PATH:/usr/pgsql-9.4/bin

データベースクラスタ用ディレクトリ($PGDATA)作成

 インストールしたRPMパッケージで初期設定されているデータベースクラスタは /var/lib/pgsql/9.4/data/ となっています。 このままでも良いのですが、ディレクトリ階層が深くて分かりづらいため /data/pgdata1/ に変更します。 ディレクトリを作成して必要なパーミッションを設定します。 データベースクラスタ用のディレクトリは管理者ユーザのpostgresユーザのみが参照、更新できるようにします。 また、同様にアーカイブログを格納するディレクトリとして /bkup/pgdata1/pg_arch/ を作成します。

# cd /
# mkdir -m 777 data
# ls -ld data
drwxrwxrwx 2 root root 6  7月 22 01:19 data
# mkdir -m 777 bkup
# ls -ld bkup
drwxrwxrwx 2 root root 6  7月 22 01:19 bkup
# su - postgres
-bash-4.2$ cd /data/
-bash-4.2$ mkdir -m 700 pgdata1
-bash-4.2$ ls -ld pgdata1
drwx------ 2 postgres postgres 6  7月 22 01:22 pgdata1
-bash-4.2$ cd /bkup/
-bash-4.2$ mkdir -m 700 pgdata1
-bash-4.2$ ls -ld pgdata1
drwx------ 2 postgres postgres 6  7月 22 01:22 pgdata1
-bash-4.2$ cd pgdata1/
-bash-4.2$ mkdir -m 700 pg_arch
-bash-4.2$ ls -ld pg_arch
drwx------ 2 postgres postgres 6  7月 22 01:23 pg_arch

マスタサーバからスタンバイサーバへベースバックアップをコピー

 スタンバイサーバではinitdbコマンドでデータベースクラスタを作成するのではなく、 構築済みマスタサーバのベースバックアップをスタンバイサーバへコピーして使用します。 ベースバックアップの取得にはpg_basebackupコマンドをスタンバイサーバで実行します。 このコマンドはマスタサーバのPostgreSQLが起動している状態で実行します。 pg_basebackupコマンドで指定するオプションの意味は以下の通りです。

オプション意味
-h 192.168.0.75バックアップを取得するマスタサーバのホスト名、もしくはIPアドレスを指定します。
-p 5432マスタサーバのPostgreSQLがリッスンしているTCPポートを指定します。
-U postgresマスタサーバのPostgreSQLに接続する際のユーザ名を指定します。バックアップ時に権限不足とならないよう念のため管理者ユーザのpostgresを指定しました。
-D /data/pgdata1ベースバックアップの出力先、つまりスタンバイサーバのデータベースクラスタのディレクトリパスを指定します。
--xlogWALファイルをバックアップの最後に収集します
--checkpoint=fastfastを指定することで瞬間的にI/O負荷が高まりますが、バックアップ前のチェックポイントにかかる時間を短縮できます。この時点でデータベースは空の想定なので問題ないと思います。
--progressバックアップの進捗状況を画面に表示します。
-bash-4.2$ pg_basebackup -h 192.168.0.75 -p 5432 -U postgres -D /data/pgdata1 --xlog --checkpoint=fast --progress
37538/37538 kB (100%), 1/1 tablespace
-bash-4.2$ ls -l /data/pgdata1/
合計 84
-rw------- 1 postgres postgres     4  7月 23 17:42 PG_VERSION
-rw------- 1 postgres postgres   206  7月 23 17:42 backup_label
drwx------ 5 postgres postgres    38  7月 23 17:42 base
drwx------ 2 postgres postgres  4096  7月 23 17:42 global
drwx------ 2 postgres postgres    17  7月 23 17:42 pg_clog
drwx------ 2 postgres postgres     6  7月 23 17:42 pg_dynshmem
-rw------- 1 postgres postgres  4363  7月 23 17:42 pg_hba.conf
-rw------- 1 postgres postgres  4224  7月 23 17:42 pg_hba.conf.bk20160721
-rw------- 1 postgres postgres  1636  7月 23 17:42 pg_ident.conf
drwx------ 2 postgres postgres    66  7月 23 17:42 pg_log
drwx------ 4 postgres postgres    37  7月 23 17:42 pg_logical
drwx------ 4 postgres postgres    34  7月 23 17:42 pg_multixact
drwx------ 2 postgres postgres    17  7月 23 17:42 pg_notify
drwx------ 2 postgres postgres     6  7月 23 17:42 pg_replslot
drwx------ 2 postgres postgres     6  7月 23 17:42 pg_serial
drwx------ 2 postgres postgres     6  7月 23 17:42 pg_snapshots
drwx------ 2 postgres postgres     6  7月 23 17:42 pg_stat
drwx------ 2 postgres postgres     6  7月 23 17:42 pg_stat_tmp
drwx------ 2 postgres postgres    17  7月 23 17:42 pg_subtrans
drwx------ 2 postgres postgres     6  7月 23 17:42 pg_tblspc
drwx------ 2 postgres postgres     6  7月 23 17:42 pg_twophase
drwx------ 3 postgres postgres    58  7月 23 17:42 pg_xlog
-rw------- 1 postgres postgres    88  7月 23 17:42 postgresql.auto.conf
-rw------- 1 postgres postgres 21281  7月 23 17:42 postgresql.conf
-rw------- 1 postgres postgres 21253  7月 23 17:42 postgresql.conf.bk20160721
-bash-4.2$ ls -l /bkup/pgdata1/pg_arch/
合計 0

 postgresql.conf.bk20160721 ファイルなど、私がマスタサーバ上でファイル編集前に取得したバックアップファイルもコピーされています。 一方、postmaster.opts ファイルや postmaster.pid ファイルなど、マスタサーバでの稼働状態を一時的に保持したファイルはコピーされていません。 ちゃんと考えられているんですね。 あと、WALアーカイブはコピーされないようです。

PostgreSQLスタンバイサーバの設定

 基本的にはマスタサーバでの設定と同じで良いのですが、 今回はスタンバイサーバをホットスタンバイ、つまり問い合わせのみ可能となるように設定します。 マスタサーバからコピーされた postgresql.conf ファイルを1行だけ書き換えます。

-bash-4.2$ cd /data/pgdata1/
-bash-4.2$ vi postgresql.conf
ファイル名:/data/pgdata1/postgresql.conf
#------------------------------------------------------------------------------
# REPLICATION
#------------------------------------------------------------------------------
#hot_standby = off                      # "on" allows queries during recovery
   ↓変更
hot_standby = on                        # "on" allows queries during recovery

リカバリ設定ファイルの作成

 スタンバイサーバでのみ recovery.conf ファイルを作成し、 PostgreSQL起動時に読み込ませることでスタンバイサーバであることを認識させます。 また、マスタサーバへの接続情報(primary_conninfo)を記述します。 ファイルのパーミッションは他の設定ファイルに合わせてオーナのみ読み書きできるようにします。

-bash-4.2$ cd /data/pgdata1/
-bash-4.2$ touch recovery.conf
-bash-4.2$ chmod 600 recovery.conf
-bash-4.2$ ls -l *.conf
-rw------- 1 postgres postgres  4363  7月 23 17:42 pg_hba.conf
-rw------- 1 postgres postgres  1636  7月 23 17:42 pg_ident.conf
-rw------- 1 postgres postgres    88  7月 23 17:42 postgresql.auto.conf
-rw------- 1 postgres postgres 21279  7月 23 17:50 postgresql.conf
-rw------- 1 postgres postgres     0  7月 23 17:53 recovery.conf ←作成された
-bash-4.2$ vi recovery.conf
ファイル名:/data/pgdata1/recovery.conf
standby_mode = 'on'
primary_conninfo = 'host=192.168.0.75 port=5432 user=pgrepl01 password=password'

 以上で設定は終了です。

インスタンス起動

 PostgreSQLのインスタンスを起動します。 起動には pg_ctl コマンドを使用します。

-bash-4.2$ pg_ctl start -w
サーバの起動完了を待っています....2016-07-23 19:13:10 JST [2680] LOG:  redirecting log output to logging collector process
2016-07-23 19:13:10 JST [2680] HINT:  Future log output will appear in directory "pg_log".
完了
サーバ起動完了

動作テスト

プロセス起動確認

 PostgreSQLのプロセスが起動していることを確認します。 今回の設定ではマスタサーバプロセス1つとワーカプロセス6つが起動します。

-bash-4.2$ ps -ef | grep postgres
(前略)
                                                ↓マスタサーバプロセス(1つ)
postgres  2680     1  0 19:13 pts/0    00:00:00 /usr/pgsql-9.4/bin/postgres
                                                ↓ワーカプロセス(6つ)
postgres  2681  2680  0 19:13 ?        00:00:00 postgres: logger process
postgres  2682  2680  0 19:13 ?        00:00:00 postgres: startup process   recovering 000000010000000000000007
postgres  2683  2680  0 19:13 ?        00:00:00 postgres: checkpointer process
postgres  2684  2680  0 19:13 ?        00:00:00 postgres: writer process
postgres  2685  2680  0 19:13 ?        00:00:00 postgres: stats collector process
postgres  2686  2680  0 19:13 ?        00:00:00 postgres: wal receiver process   streaming 0/70001A0
(後略)

 スタンバイサーバでは「wal writer process」の代わりに「wal receiver process」が起動し、 「startup process」が独自で起動します。 「autovacuum launcher process」と「archiver process」は起動しないようです。

ログ出力確認

 設定したログファイルに起動ログが出力されていることを確認します。

-bash-4.2$ cd /data/pgdata1/pg_log/
-bash-4.2$ ls -l
合計 24
-rw------- 1 postgres postgres  1986  7月 23 17:42 postgresql-20160721.log
-rw------- 1 postgres postgres 20405  7月 23 19:13 postgresql-20160723.log
-bash-4.2$ tail postgresql-20160723.log
2016-07-23 18:02:53 JST [2466] LOG:  received fast shutdown request
2016-07-23 18:02:53 JST [2466] LOG:  aborting any active transactions
2016-07-23 18:02:53 JST [2469] LOG:  shutting down
2016-07-23 18:02:53 JST [2469] LOG:  database system is shut down
2016-07-23 19:13:10 JST [2682] LOG:  database system was shut down in recovery at 2016-07-23 18:02:53 JST
2016-07-23 19:13:10 JST [2682] LOG:  entering standby mode
2016-07-23 19:13:10 JST [2682] LOG:  redo starts at 0/5000028
2016-07-23 19:13:10 JST [2682] LOG:  consistent recovery state reached at 0/6000000
2016-07-23 19:13:10 JST [2680] LOG:  database system is ready to accept read only connections
2016-07-23 19:13:10 JST [2686] LOG:  started streaming WAL from primary at 0/6000000 on timeline 1

SQL実行確認

 psqlコマンドで、SQLを実行できることを確認します。

-bash-4.2$ psql
psql (9.4.8)
"help" でヘルプを表示します.

postgres=# select now();
              now
-------------------------------
 2016-07-23 19:20:10.757084+09
(1 行)

postgres=# select oid, datname from pg_database;
  oid  |  datname
-------+-----------
     1 | template1
 13051 | template0
 13056 | postgres
(3 行)

postgres=# \q
-bash-4.2$

インスタンス再起動

 PostgreSQLインスタンスを再起動します。 pg_ctl コマンド1つで再起動できますが、ここでは確認のため停止・起動に分けて実行します。

-bash-4.2$ pg_ctl stop -m fast
サーバ停止処理の完了を待っています....完了
サーバは停止しました
-bash-4.2$ ps -ef | grep postgres
root      2348  2303  0 17:41 pts/0    00:00:00 su - postgres
postgres  2349  2348  0 17:41 pts/0    00:00:00 -bash
postgres  2711  2349  0 19:20 pts/0    00:00:00 ps -ef
postgres  2712  2349  0 19:20 pts/0    00:00:00 grep --color=auto postgres
↑マスタサーバプロセスとワーカプロセスが停止した
-bash-4.2$ pg_ctl start -w
サーバの起動完了を待っています....2016-07-23 19:20:55 JST [2715] LOG:  redirecting log output to logging collector process
2016-07-23 19:20:55 JST [2715] HINT:  Future log output will appear in directory "pg_log".
完了
サーバ起動完了

WALとWALアーカイブの出力確認

 WAL(Write Ahead Logging)ファイルが生成されていることを確認します。 WALアーカイブは生成されませんが、一応確認します。

-bash-4.2$ ls -l /data/pgdata1/pg_xlog/ ←WALディレクトリ
合計 49152
-rw------- 1 postgres postgres 16777216  7月 23 17:42 000000010000000000000005
-rw------- 1 postgres postgres 16777216  7月 23 19:13 000000010000000000000006
-rw------- 1 postgres postgres 16777216  7月 23 19:20 000000010000000000000007
drwx------ 2 postgres postgres       78  7月 23 19:13 archive_status
-bash-4.2$ ls -l /bkup/pgdata1/pg_arch/ ←WALアーカイブディレクトリ
合計 0 ←archiver process が起動していないため、やはり出力されていない