PostgreSQLのreplication_slotについて

[ラクス Advent Calendar 2016](http://qiita.com/advent-calendar/2016/rakus)の7日目です。
昨日は@moomooyaさんの「[PostgreSQLとMySQLとMariaDBのNoSQL実装状況](http://qiita.com/moomooya/items/e7e8e2059d6b94280c5b)」でした。
***
はじめまして、@kumakichi_kunです。
SE（サーバエンジニア）やってます。
深刻なネタ不足のため、誰得？な内容であることをご承知の上でお読みください。

下記の公式を頑張って一通り見るとわかったような気になれます。
私もわかったような気になっている人ですｗ
[PostgreSQL9.4 公式](https://www.postgresql.jp/document/9.4/html/)
#目次
0. 「replication_slot」って何者？
0. 何が新しいの？
0. 構築時にやったこと（簡易）
0. 私が実際に導入した後にハマった落とし穴
0. 終わりに

#1.「replication_slot」って何者？
一言で説明すると、
**masterがslaveに必要なWALを判別して、自動削除しない**
という機能です。
それによって「WALがディスク容量を大量に食ってる～！」とかが起きづらいのウリ。
※replication自体の概要については他の方の立派な記事がとても参考になります。
[PostgreSQL におけるレプリケーションの仕組み](http://qiita.com/U_ikki/items/2d01bee76c0d2935cf7b)
[5ステップで始めるPostgreSQLレプリケーション](http://www.slideshare.net/uptimejp/5postgresql)

#2.何が新しいの？
- 9.3以前
 - masterのWAL管理はpostgresql.confに設定ベタ書き
 - slaveへの伝播も含めて考えないとWAL競合とかが起きる
 - 余分なWALは **必ず** 発生する
- 9.4でreplication_slotを導入すると・・・
 - 設定しなくても必要な分のWALを保持してくれる
 - WAL競合が起きない
 - *余分なWALを減らせる*

#3.構築時にやったこと（簡易）
※replication_slot設定にのみ焦点を当ててます。
通常のreplication の設定はしっかりとまとまっている他の方の記事をご参照ください。
[PostgreSQL9.3でのストリーミングレプリケーション環境の構築](http://qiita.com/mmmm/items/3a6423ed219189da6cba)
[PostgreSQLのレプリケーション機能をつかってみた](http://blog.asial.co.jp/1186)
[ストリーミング・レプリケーションの構築](http://lets.postgresql.jp/documents/technical/replication/1/)
####・master側
#####設定ファイル
```postgresql.conf
max_replication_slots = 1  # スタンバイDBの数
wal_level = hot_standby
max_wal_senders = 2        # スタンバイDBの数 + 1
archive_mode = on
archive_command = '...'    # 環境に合わせて
```
#####repication_slot作成
```sql
SELECT * FROM pg_create_physical_replication_slot('repl_slot');
  slot_name  | xlog_position
-------------+---------------
 repl_slot |
```
#####repication_slot確認
```sql
SELECT * FROM pg_replication_slots;
  slot_name   | plugin | slot_type | datoid | database | active | xmin  | catalog_xmin | restart_lsn 
--------------+--------+-----------+--------+----------+--------+-------+--------------+-------------
 repl_slot |        | physical  |        |          | t      | 66517 |              | 1/D1BD5D0
(1 行)
```
***
####・slave側
```recovery.conf
standby_mode = 'on'
primary_conninfo = 'host="masterのサーバ" port=設定したポート user=設定したユーザ password=ユーザのパスワード' # 環境に合わせて
primary_slot_name = 'repl_slot'
restore_command = '...'  # 環境に合わせて
```
大体が公式に書いてあります。「触りながら」読むと格段に身に付きますね。
[PostgreSQL9.4 公式](https://www.postgresql.jp/document/9.4/html/high-availability.html)

##4.私が実際に導入した後にハマった落とし穴
#####・masterサーバにWALが大量に残ってしまう問題
前提：replication_slotを利用してDBレプリケーションを組んでいる
①レプリケーションを切る(slaveのDBを止めるとか)
②masterでメンテナンス（vacuumfullとか）
⇒WALファイルが大量に生成＆一定期間残る
***
#####・原因
replication_slotは「slave」に必要なWALを残すものです。
その実体は、
slaveがmasterに送る「???まで適用終わったよ！」というお知らせと
masterが「???まで終わったんだね。じゃあ、???以前は削除するね」というやり取りで成立しています。そのため、
**「slaveが応答なしの状態だと、masterは無限にWALを残す」**
という動作になります。
***
#####・解決法
①と②の間に①´を行いましょう。
①´replication_slotを削除する
（ON/OFF切り替えられると *good* ですが、見つけられてません。。。）
そして、メンテ完了後のレプリケーション再構築時に再度replication_slotを作成しましょう！

#5. 終わりに
replication_slotに関する記事はまだまだ少ない印象があります。
（あまり探していないってのもあるかもしれませんが・・・）
こんな使い方できるぜ！とか、こういう風に使うと良い感じ！とか、
投稿されていくと盛り上がって行くのかな、と思います。


※誤字・脱字・不適切な表現・認識違い・読みづらい！などあれば、ドシドシご指摘くださいm(_ _)m