PostgreSQL Streaming Replication (потоковая репликация)
Данное “руководство” будет использоваться для PostgreSQL версии 9.6 сервера под управлением Ubuntu Bionic Beaver
Потоковая репликация (Master -> Replica)
  В нашем случае имеется два сервера:
  - master 192.168.1.1
  - replica 192.168.1.2
Настраиваем Master
В файл /etc/postgresql/9.6/main/postgresql.conf вносим следующие изменения
  # Указывает IP-адрес или имя компьютера, на котором сервер postgres принимает клиентские подключения по TCP/IP.
  # Значением может быть список адресов, разделённых запятыми, либо символ *, обозначающий все доступные интерфейсы.
  listen_addresses = '*'
  # Параметр wal_level определяет, как много информации записывается в WAL. Со 
  # значением minimal (по умолчанию) в журнал записывается только информация, 
  # необходимая для восстановления после сбоя или аварийного отключения. Вариант 
  # replica добавляет в него то, что необходимо для архивирования WAL, а также 
  # информацию, необходимую для выполнения запросов на резервном сервере в режиме 
  # «только чтение». Наконец, logical добавляет информацию, требуемую для поддержки 
  # логического декодирования.
  wal_level = hot_standby
  # Задаёт максимально допустимое число одновременных подключений резервных серверов
  # или клиентов потокового копирования (т. е. максимальное количество одновременно
  # работающих процессов передачи WAL). По умолчанию это значение равно нулю, то
  # есть репликация отключается. Передающие WAL процессы учитываются в общем числе
  # соединений, так что этот параметр не может превышать max_connections.
  max_wal_senders = 3
  # Задаёт минимальное число файлов прошлых сегментов журнала, которые будут сохраняться в каталоге pg_xlog,
  # чтобы ведомый сервер мог выбрать их при потоковой репликации. Обычно сегмент имеет размер 16 мегабайт.
  # Если ведомый сервер, подключённый к передающему, отстаёт больше чем на wal_keep_segments сегментов,
  # передающий удаляет сегменты WAL, всё ещё необходимые ведомому, и в этом случае соединение репликации прерывается.
  # В результате этого затем также будут прерваны зависимые соединения.
  wal_keep_segments = 128
  
  # Когда параметр archive_mode включён, полные сегменты WAL передаются в хранилище архива.
  archive_mode    = on
  archive_command = 'cp %p /var/lib/pg-archive/%f'
Создадим директорию для хранения WAL сигментов:
  mkdir /var/lib/pg-archive/
  chown postgres /var/lib/pg-archive/
  chmod 700 /var/lib/pg-archive/
Чтобы архив не занял всё место на диске, добавим в cron следующее:
  40 7 * * * /usr/bin/find /var/lib/pg-archive/ -type f -mtime +5 -exec rm {} \;
Чистим все сигменты старше 5 дней, каждый день в 7:40
Создаём пользователя для репликации, с помощью которого будем забирать данные:
  sudo -u postgres psql -c 'CREATE ROLE replication WITH REPLICATION PASSWORD 'tsoAYHhdrKmq+oP8dl7M' LOGIN;'
В файл /etc/postgresql/9.6/main/pg_hba.conf добавляем следующее:
  # TYPE  DATABASE        USER            ADDRESS                         METHOD
  host    replication     replication     ip_address_slave_server         md5
Перезапускаем master сервер:
  systemctl restart postgresql && systemctl status postgresql
Настраиваем Slave (Replica)
В файл /etc/postgresql/9.6/main/postgresql.conf добавляем всё тоже самое что и на master сервере и добавляем:
  # Определяет, можно ли будет подключаться к серверу и выполнять запросы в процессе восстановления.
  # Значение по умолчанию — off (подключения не разрешаются). Задать этот параметр можно только при запуске сервера.
  # Данный параметр играет роль только в режиме ведомого сервера или при восстановлении архива.
  hot_standby = on
В нашем случае база на master сервере будет постоянно обновляться и дополняться, нам необходимо перенести на slave сервер начальное состояние. Для начала удалим все данные на SLAVE сервере:
  rm -Rf /var/lib/postgresql/9.6/main/*
Копируем данные с master сервера, после выполнения команды надо будет ввести пароль, который мы задавали при создании роли replication на master:
  su postgres -c "pg_basebackup -h 192.168.1.1 -D /var/lib/postgresql/9.6/main -R -P -U replication --xlog-method=stream"
В результате выполнении команды будет создан файл recovery.conf с примерно следующим содержимым:
  standby_mode = 'on'
  primary_conninfo = 'user=replication password=tsoAYHhdrKmq+oP8dl7M host=192.168.1.1 port=5432 sslmode=prefer sslcompression=1 krbsrvname=postgres'
Добавляем в этот файл строку:
  trigger_file = '/var/lib/postgresql/9.6/main/trigger_file'
trigger_file нам нужен, чтобы переключить salve сервер в master, т.е. чтобы вывести slave сервер из режима только чтение.
Запускаем на salve сервер:
  systemctl start postgresql && systemctl status postgresql
Проверяем что репликация запущена и работает. На master:
  ps wax|grep sender
получаем примерно такой вот ответ:
  28713 pts/0   S+    0:00 postgres: 9.6/main: wal sender process replication 
                        192.168.1.2(00000) streaming 0/150000000
На slave (replica):
  ps wax|grep receiver
получаем:
  1223 ?        Ss     0:00 postgres: 9.6/main: wal receiver process   streaming 0/150000000
Вроде всё работает :)
Проверим поглубже: master:
  sudo -u postgres psql -c 'SELECT *,pg_xlog_location_diff(s.sent_location,s.replay_location) byte_lag FROM pg_stat_replication s;'
Получаем список серверов подлюкченных к master, обращаем внимание на колонку byte_lag, она покажет нам на сколько отстаёт replica от master в байтах.
slave (replica):
  sudo -u postgres psql -c "SELECT now()-pg_last_xact_replay_timestamp();"
Получим когда последний раз была произведена сихронизация с master.
       ?column?     
  -----------------
   00:00:02.123112


