PostgreSQL9.5でcascading replicationを構成する


#はじめに
[MySQL](http://qiita.com/tomohiko_isobe/items/fcba3c5bbd755d87642e)に続いて、PostgreSQLでも同様のレプリケーションを構成してみます。

MySQLで言うchained replicationは、PostgreSQLではcascading replicationと呼ぶようです。

すなわち
`master -> slave1 -> slave2`
のような構成です。

このとき、slave1はslave2にとってのmasterでもあります。


#特記事項
通常のレプリケーション構築手順をslave1とslave2に実施することでcascading replicationは実現できますが、そのままだとslave1をmasterに昇格させた時、slave1->slave2のレプリケーションが停止してしまいます。

これは、slave1が昇格する際にTimeLineIDが上がり、slave2のTimeLineIDとズレてしまうためです。

これを回避するため、slaveのrecovery.confに追加の設定が必要となります。

#前提
- PostgreSQL9.5
- ストリーミングレプリケーション（スレーブ非同期）
- レプリケーション用ユーザ：replicator
- 各ノードは全て192.168.1.0/24のネットワークに所属
- Ubuntu16.04



#必要な設定
##共通
###postgresql.conf
```Bash:postgresql.conf
wal_level = hot_standby
synchronous_commit = local #スレーブ非同期
max_wal_senders = 2 #1以上、slaveの数+1
wal_keep_segments = 8 #任意
```

###pg_hba.conf
```Bash:pg_hba.conf
host    replication     replicator      192.168.1.0/24           trust #必要に応じてmd5
```
md5だとベースバックアップ取得時にreplicatorユーザのパスワードを要求されます。

###postgresユーザによる公開鍵認証設定

詳細手順は割愛します。
全ノードpostgresユーザで公開鍵認証によるsshログインができるようにしておきます。

##master
###レプリケーション用ユーザ作成
```Bash:psql
postgres=# create user replicator replication password 'replicator';
```

##slave1
###PostgreSQL停止
```Bash:command
$ sudo service postgresql stop
```

###ベースバックアップ
```Bash:command
$ sudo su - postgres
$ mv /var/lib/postgresql/9.5/main /var/lib/postgresql/9.5/main.org
$ pg_basebackup -U replicator -h MASTER_IP -D /var/lib/postgresql/9.5/main --xlog --progress --verbose
```

###recovery.conf作成
```Bash:command
$ sudo su - postgres
$ vi /var/lib/postgresql/9.5/main/recovery.conf
```

```Bash:recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=replicator password=replicator host= MASTER_IP'
trigger_file = '/var/lib/postgresql/9.5/main/failover'
recovery_target_timeline='latest'
restore_command = 'scp MASTER_IP:/var/lib/postgresql/9.5/main/pg_xlog/%f %p 2> /dev/null'
```

###PostgreSQL起動
```Bash:command
$ sudo service postgresql start
```

##slave2
###PostgreSQL停止
```Bash:command
$ sudo service postgresql stop
```

###ベースバックアップ
```Bash:command
$ sudo su - postgres
$ mv /var/lib/postgresql/9.5/main /var/lib/postgresql/9.5/main.org
$ pg_basebackup -U replicator -h SLAVE1_IP -D /var/lib/postgresql/9.5/main --xlog --progress --verbose
```

###recovery.conf作成
```Bash:command
$ sudo su - postgres
$ vi /var/lib/postgresql/9.5/main/recovery.conf
```

```Bash:recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=replicator password=replicator host= MASTER_IP'
trigger_file = '/var/lib/postgresql/9.5/main/failover'
recovery_target_timeline='latest'
restore_command = 'scp SLAVE1_IP:/var/lib/postgresql/9.5/main/pg_xlog/%f %p 2> /dev/null'
```

###PostgreSQL起動
```Bash:command
$ sudo service postgresql start
```

##レプリケーション確認
###master,slave1
```Bash:command
$ sudo -i -u postgres psql -x -c 'SELECT * from pg_stat_replication;'
```
```Bash:結果
state            | streaming
であればレプリケーションが正常に行なわれている
```

##フェイルオーバ（master昇格）
recovery.confにトリガファイルを指定してあるため、このファイルを作成し、postgresqlを再起動させることでmaster昇格が可能です。

###slave1 or slave2

```Bash:command
$ sudo su - postgres
$ touch /var/lib/postgresql/9.5/main/failover
$ exit
$ sudo service postgresql restart 
```