Перейти к основному содержимому

Логическая репликация

  1. Подключитесь к серверу под пользователем postgres на порт 5432 и измените уровень wal_level на logical.

    Выполните ALTER SYSTEM.

    postgres@postgres=# ALTER SYSTEM SET wal_level = logical;
    ALTER SYSTEM
  2. Перезапустите сервер в отдельном терминале.

    [student@ServerName ~]$ sudo systemctl restart postgresql
  3. Подключитесь к БД postgres, создайте БД lrepl_db и подключитесь к ней. Создайте в ней схему student, принадлежащую роли student.

    Создайте базу данных.

    postgres@postgres=# CREATE DATABASE lrepl_db;
    CREATE DATABASE

    Подключитесь к ней.

    postgres@postgres=# \c lrepl_db
    You are now connected to database "lrepl_db" as user "postgres".

    Создайте схему.

    postgres@lrepl_db=# CREATE SCHEMA student AUTHORIZATION student;
    CREATE SCHEMA
  4. Подключитесь ролью student, удалите все таблицы и подчиненные объекты, принадлежащие ей.

    Выйдите из сеанса postgres и войдите под student.

    postgres@lrepl_db=# \q
    [postgres@ServerName ~]$ logout
    [student@ServerName ~]$ psql
    psql (15.5)
    Type "help" for help.

    Найдите таблицы владельца student.

    student@student=> SELECT schemaname, tablename FROM pg_tables WHERE tableowner = 'student';
    schemaname | tablename
    ------------+-----------
    public | stab
    student | stab
    public | fatab
    (3 rows)

    Удалите таблицы.

    student@student=> DROP TABLE stab;
    DROP TABLE
    student@student=> DROP TABLE fatab;
    DROP TABLE
    student@student=> DROP TABLE student.stab;
    DROP TABLE
  5. Создайте таблицу и опубликуйте ее.

    Удалите старую таблицу (если есть) и создайте новую.

    student@student=> DROP TABLE IF EXISTS tab2lr;
    NOTICE: table "tab2lr" does not exist, skipping
    DROP TABLE
    student@student=> CREATE TABLE tab2lr(id int PRIMARY KEY, msg text);
    CREATE TABLE

    Создайте публикацию.

    student@student=> CREATE PUBLICATION stud_pub FOR TABLE student.tab2lr;
    CREATE PUBLICATION

    Проверьте публикацию.

    student@student=> \x \dRp+ \x
    Expanded display is on.
    Publication stud_pub
    -[ RECORD 1 ]-------
    Owner | student
    All tables | f
    Inserts | t
    Updates | t
    Deletes | t
    Truncates | t
    Via root | f

    Tables:
    "student.tab2lr"

    Expanded display is off.

    Публикация stud_pub создана для таблицы student.tab2lr и включает операции INSERT, UPDATE, DELETE и TRUNCATE.

  6. Заполните таблицу данными.

    Вставьте строки.

    student@student=> INSERT INTO tab2lr VALUES (1, 'Первая запись.'),(2, 'Вторая.'),(3, 'Теперь - третья.');
    INSERT 0 3
  7. Подключитесь суперпользователем на порт 5432 и выполните резервное копирование только схемы student в БД student на сервере, прослушивающем порт 7432.

    Выйдите из сеанса student и войдите под postgres.

    student@student=> \q
    [student@ServerName ~]$ sudo -iu postgres
    [postgres@ServerName ~]$ psql
    psql (15.5)
    Type "help" for help.

    Подключитесь к БД student на мастере.

    postgres@postgres=# \c student - /tmp 5432
    You are now connected to database "student" as user "postgres" via socket in "/tmp" at port "5432".

    Сделайте дамп схемы student и примените его на реплике.

    postgres@student=# \! pg_dump -d student -n student -s | psql -d student -p 7432
    Разбор команды

    • \! — метакоманда, выполняющая оболочечную команду внутри psql;
    • pg_dump -d student -n student -s — дамп структуры (-s) схемы student (-n student) из БД student;
    • | psql -d student -p 7432 — передача дампа через конвейер в psql на сервере-реплике (порт 7432).
    SET
    SET
    SET
    SET
    SET
    set_config
    ------------
    (1 row)
    SET
    SET
    SET
    CREATE TABLE
    ALTER TABLE
    ALTER TABLE

    Структура таблицы успешно скопирована.

  8. Подключитесь на порт 7432 и проверьте наличие пустой таблицы.

    Подключитесь к реплике.

    postgres@student=# \c - postgres /tmp 7432
    You are now connected to database "student" as user "postgres" via socket in "/tmp" at port "7432".

    Проверьте структуру таблицы.

    postgres@student=# \d *.tab2lr
    Table "student.tab2lr"
    Column | Type | Collation | Nullable | Default
    -------+---------+-----------+----------+---------
    id | integer | | not null |
    msg | text | | |
    Indexes:
    "tab2lr_pkey" PRIMARY KEY, btree (id)

    Проверьте количество строк.

    postgres@student=# SELECT count(*) FROM student.tab2lr;
    count
    -------
    0
    (1 row)

    Таблица на реплике существует, но пуста — данные еще не реплицированы.

  9. Создайте подписку.

    Выполните CREATE SUBSCRIPTION.

    postgres@student=# CREATE SUBSCRIPTION stud_sub
    CONNECTION 'host=/tmp port=5432 dbname=student user=postgres'
    PUBLICATION stud_pub;
    Разбор команды

    • CREATE SUBSCRIPTION stud_sub — создание подписки с именем stud_sub;
    • CONNECTION 'host=/tmp port=5432 dbname=student user=postgres' — строка подключения к мастер-серверу (путь к Unix-сокету /tmp, порт 5432, БД student, пользователь postgres);
    • PUBLICATION stud_pub — имя публикации для подписки.
    NOTICE: created replication slot "stud_sub" on publisher
    CREATE SUBSCRIPTION

    Проверьте подписку.

    postgres@student=# \x \dRs+ \x
    Expanded display is on.
    List of subscriptions
    -[ RECORD 1 ]------+-------------------------------------------------
    Name | stud_sub
    Owner | postgres
    Enabled | t
    Publication | {stud_pub}
    Binary | f
    Streaming | f
    Two-phase commit | d
    Disable on error | f
    Synchronous commit | off
    Conninfo | host=/tmp port=5432 dbname=student user=postgres
    Skip LSN | 0/0
    Expanded display is off.

    Подписка stud_sub создана, подключена к публикации stud_pub и активна (Enabled = t).

  10. Проверьте, выполнилась ли начальная синхронизация.

Выведите данные таблицы.

postgres@student=# SELECT * FROM student.tab2lr;
id | msg
---+------------------
1 | Первая запись.
2 | Вторая.
3 | Теперь - третья.
(3 rows)

Начальная синхронизация выполнена — все 3 строки скопированы с мастера.

  1. Добавьте еще одну строку на сервере 5432 и проверьте на 7432.

Вставьте строку на мастере.

postgres@student=# \! psql -d student -p 5432 -c "INSERT INTO student.tab2lr VALUES(4, 'Четвертая. Ну и хватит, пожалуй.')"
INSERT 0 1

Проверьте данные на реплике.

postgres@student=# SELECT * FROM student.tab2lr;
id | msg
---+----------------------------------
1 | Первая запись.
2 | Вторая.
3 | Теперь - третья.
4 | Четвертая. Ну и хватит, пожалуй.
(4 rows)

Новая строка автоматически реплицирована на сервер 7432.

  1. Удалите подписку.

Выполните DROP SUBSCRIPTION.

postgres@student=# DROP SUBSCRIPTION stud_sub;
NOTICE: dropped replication slot "stud_sub" on publisher
DROP SUBSCRIPTION
  1. Удалите публикацию.

Подключитесь к мастеру.

postgres@student=# \c - postgres /tmp 5432
You are now connected to database "student" as user "postgres" via socket in "/tmp" at port "5432".

Удалите публикацию.

postgres@student=# DROP PUBLICATION stud_pub;
DROP PUBLICATION

Выйдите из psql.

postgres@student=# \q
  1. Остановите сервер, прослушивающий порт 7432.

Выполните pg_ctl stop.

[postgres@ServerName ~]$ pg_ctl stop -D ~/repl/ -l repl_srv.log
waiting for server to shut down.... done
server stopped

Самопроверка​

Вопрос 1

Какая команда устанавливает wal_level = logical и что необходимо сделать после?

Вопрос 2

Что включает публикация по умолчанию? Выберите все верные варианты.

Вопрос 3

Что делает команда pg_dump -d student -n student -s?

Вопрос 4

Сколько строк будет в таблице student.tab2lr на подписчике после начальной синхронизации, если на мастере было вставлено 3 строки?

Вопрос 5

Что происходит с новой строкой, вставленной на мастере после создания подписки?

Вопрос 6

Что происходит при выполнении DROP SUBSCRIPTION stud_sub? Выберите все верные варианты.