Сначала создадим базу данных.
student$ psql
α=> CREATE DATABASE replica_usecases;
CREATE DATABASE
α=> \c replica_usecases
You are now connected to database "replica_usecases" as user "student".
Слот:
α=> SELECT pg_create_physical_replication_slot('replica');
pg_create_physical_replication_slot ------------------------------------- (replica,) (1 row)
Создаем автономную резервную копию, используя созданный слот, в каталоге PGDATA будущей реплики.
postgres$ rm -rf /var/lib/postgresql/10/beta/*
postgres$ pg_basebackup -U student --pgdata=/var/lib/postgresql/10/beta -R --slot=replica
Меняем порт и включаем режим горячего резерва:
postgres$ echo 'port = 5433' >> /var/lib/postgresql/10/beta/postgresql.auto.conf
postgres$ echo 'hot_standby = on' >> /var/lib/postgresql/10/beta/postgresql.auto.conf
Файл recovery.conf подготовлен утилитой pg_basebackup:
postgres$ cat /var/lib/postgresql/10/beta/recovery.conf
standby_mode = 'on' primary_conninfo = 'user=student passfile=''/var/lib/postgresql/.pgpass'' host=''/var/run/postgresql'' port=5432 sslmode=prefer sslcompression=1 krbsrvname=postgres target_session_attrs=any' primary_slot_name = 'replica'
Запускаем реплику.
student$ sudo pg_ctlcluster 10 beta start
Слот:
student$ psql -p 5433 -d replica_usecases
β=> SELECT pg_create_physical_replication_slot('replica');
pg_create_physical_replication_slot ------------------------------------- (replica,) (1 row)
Создадим автономную резервную копию cо второго сервера, чтобы показать возможность выполнения резервного копирования с реплики. Используем созданный слот, копию записываем в каталог PGDATA будущей третьей реплики.
postgres$ rm -rf /var/lib/postgresql/10/gamma/*
postgres$ pg_basebackup -U student -p 5433 --pgdata=/var/lib/postgresql/10/gamma -R --slot=replica
Меняем порт и включаем режим горячего резерва:
postgres$ echo 'port = 5434' >> /var/lib/postgresql/10/gamma/postgresql.auto.conf
postgres$ echo 'hot_standby = on' >> /var/lib/postgresql/10/gamma/postgresql.auto.conf
Файл recovery.conf подготовлен утилитой pg_basebackup. Дополнительно устанавливаем указание целевой ветви восстановления и задержку воспроизведения:
postgres$ echo "recovery_target_timeline = 'latest'" >> /var/lib/postgresql/10/gamma/recovery.conf
postgres$ echo "recovery_min_apply_delay = '10s'" >> /var/lib/postgresql/10/gamma/recovery.conf
Вот что получилось:
postgres$ cat /var/lib/postgresql/10/gamma/recovery.conf
standby_mode = 'on' primary_conninfo = 'user=student passfile=''/var/lib/postgresql/.pgpass'' host=''/var/run/postgresql'' port=5433 sslmode=prefer sslcompression=1 krbsrvname=postgres target_session_attrs=any' primary_slot_name = 'replica' recovery_target_timeline = 'latest' recovery_min_apply_delay = '10s'
Запускаем реплику.
student$ sudo pg_ctlcluster 10 gamma start
На первом сервере создадим таблицу и проверим, что она появилась сначала на одной реплике, а через 10 секунд - и на другой.
α=> CREATE TABLE test(s text);
CREATE TABLE
α=> INSERT INTO test VALUES ('Привет, мир!');
INSERT 0 1
Проверяем одну реплику:
β=> SELECT * FROM test;
s -------------- Привет, мир! (1 row)
Проверяем другую реплику:
student$ psql -p 5434 -d replica_usecases
γ=> SELECT * FROM test;
ERROR: relation "test" does not exist LINE 1: SELECT * FROM test; ^
Таблицы пока нет. Подождем 10 секунд...
γ=> SELECT * FROM test;
s -------------- Привет, мир! (1 row)
Таблица появилась.
α=> \q
student$ sudo pg_ctlcluster 10 alpha stop
student$ sudo pg_ctlcluster 10 beta promote
На втором сервере добавим в таблицу строки и проверим, что они появились на третьем сервере через 10 секунд.
β=> INSERT INTO test VALUES ('После перехода на второй сервер');
INSERT 0 1
Проверяем:
γ=> SELECT * FROM test;
s -------------- Привет, мир! (1 row)
Данных пока нет. Ждем 10 секунд...
γ=> SELECT * FROM test;
s --------------------------------- Привет, мир! После перехода на второй сервер (2 rows)
Данные появились.