Логическая репликация
-
Подключитесь к серверу под пользователем
postgresна порт5432и измените уровеньwal_levelнаlogical.Выполните
ALTER SYSTEM.postgres@postgres=# ALTER SYSTEM SET wal_level = logical;ALTER SYSTEM -
Перезапустите сервер в отдельном терминале.
[student@ServerName ~]$ sudo systemctl restart postgresql -
Подключитесь к БД
postgres, создайте БДlrepl_dbи подключитесь к ней. Создайте в ней схемуstudent, принадлежащую ролиstudent.Создайте базу данных.
postgres@postgres=# CREATE DATABASE lrepl_db;CREATE DATABASEПодключитесь к ней.
postgres@postgres=# \c lrepl_dbYou are now connected to database "lrepl_db" as user "postgres".Создайте схему.
postgres@lrepl_db=# CREATE SCHEMA student AUTHORIZATION student;CREATE SCHEMA -
Подключитесь ролью
student, удалите все таблицы и подчиненные объекты, принадлежащие ей.Выйдите из сеанса
postgresи войдите подstudent.postgres@lrepl_db=# \q[postgres@ServerName ~]$ logout[student@ServerName ~]$ psqlpsql (15.5)Type "help" for help.Найдите таблицы владельца
student.student@student=> SELECT schemaname, tablename FROM pg_tables WHERE tableowner = 'student';schemaname | tablename------------+-----------public | stabstudent | stabpublic | fatab(3 rows)Удалите таблицы.
student@student=> DROP TABLE stab;DROP TABLEstudent@student=> DROP TABLE fatab;DROP TABLEstudent@student=> DROP TABLE student.stab;DROP TABLE -
Создайте таблицу и опубликуйте ее.
Удалите старую таблицу (если есть) и создайте новую.
student@student=> DROP TABLE IF EXISTS tab2lr;NOTICE: table "tab2lr" does not exist, skippingDROP TABLEstudent@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+ \xExpanded display is on.Publication stud_pub-[ RECORD 1 ]-------Owner | studentAll tables | fInserts | tUpdates | tDeletes | tTruncates | tVia root | fTables:"student.tab2lr"Expanded display is off.Публикация
stud_pubсоздана для таблицыstudent.tab2lrи включает операцииINSERT,UPDATE,DELETEиTRUNCATE. -
Заполните таблицу данными.
Вставьте строки.
student@student=> INSERT INTO tab2lr VALUES (1, 'Первая запись.'),(2, 'Вторая.'),(3, 'Теперь - третья.');INSERT 0 3 -
Подключитесь суперпользователем на порт
5432и выполните резервное копирование только схемыstudentв БДstudentна сервере, прослушивающем порт7432.Выйдите из сеанса
studentи войдите подpostgres.student@student=> \q[student@ServerName ~]$ sudo -iu postgres[postgres@ServerName ~]$ psqlpsql (15.5)Type "help" for help.Подключитесь к БД
studentна мастере.postgres@postgres=# \c student - /tmp 5432You 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).
SETSETSETSETSETset_config------------(1 row)SETSETSETCREATE TABLEALTER TABLEALTER TABLEСтруктура таблицы успешно скопирована.
-
Подключитесь на порт
7432и проверьте наличие пустой таблицы.Подключитесь к реплике.
postgres@student=# \c - postgres /tmp 7432You are now connected to database "student" as user "postgres" via socket in "/tmp" at port "7432".Проверьте структуру таблицы.
postgres@student=# \d *.tab2lrTable "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)Таблица на реплике существует, но пуста — данные еще не реплицированы.
-
Создайте подписку.
Выполните
CREATE SUBSCRIPTION.postgres@student=# CREATE SUBSCRIPTION stud_subCONNECTION '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 publisherCREATE SUBSCRIPTIONПроверьте подписку.
postgres@student=# \x \dRs+ \xExpanded display is on.List of subscriptions-[ RECORD 1 ]------+-------------------------------------------------Name | stud_subOwner | postgresEnabled | tPublication | {stud_pub}Binary | fStreaming | fTwo-phase commit | dDisable on error | fSynchronous commit | offConninfo | host=/tmp port=5432 dbname=student user=postgresSkip LSN | 0/0Expanded display is off.Подписка
stud_subсоздана, подключена к публикацииstud_pubи активна (Enabled = t). -
Проверьте, выполнилась ли начальная синхронизация.
Выведите данные таблицы.
postgres@student=# SELECT * FROM student.tab2lr;
id | msg
---+------------------
1 | Первая запись.
2 | Вторая.
3 | Теперь - третья.
(3 rows)
Начальная синхронизация выполнена — все 3 строки скопированы с мастера.
- Добавьте еще одну строку на сервере
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.
- Удалите подписку.
Выполните DROP SUBSCRIPTION.
postgres@student=# DROP SUBSCRIPTION stud_sub;
NOTICE: dropped replication slot "stud_sub" on publisher
DROP SUBSCRIPTION
- Удалите публикацию.
Подключитесь к мастеру.
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
- Остановите сервер, прослушивающий порт
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? Выберите все верные варианты.