Що таке логічна реплікація?
Логічна реплікація — це метод реплікації змін даних з однієї бази даних PostgreSQL (публікатора) до іншої (підписника). На відміну від фізичної реплікації, яка передбачає копіювання цілих блоків даних, логічна реплікація фокусується на реплікації окремих змін даних (вставки, оновлення, видалення) на основі їх ідентифікаторів реплікації.
Як працює логічна реплікація?
Модель публікації та підписки:
- Публікатор створює публікації, що є групами таблиць для реплікації.
- Підписник підключається до цих публікацій і отримує дані.
- Підписники можуть також ділитися своїми даними, дозволяючи каскадну реплікацію або більш складні налаштування.
Ініціалізація синхронізації даних:
Реплікація починається з знімка даних на публікаторі та копіювання їх на підписника.
Оновлення в реальному часі:
Після початкової синхронізації будь-які зміни на публікаторі негайно відправляються на підписника. Ці зміни застосовуються в тому ж порядку для забезпечення узгодженості.
Для детальнішого розуміння того, як працює логічна реплікація, зверніться до діаграми.
Кроки для налаштування логічної реплікації
Крок 1: Налаштування рівня WAL
Рівень запису перед записом (WAL) визначає, скільки даних буде записано, що впливає на функціональність, таку як реплікація та резервне копіювання. Ось рівні WAL у PostgreSQL:
- Minimal: Для автономних баз даних без потреби в реплікації або відновленні на певний момент часу (PITR).
- Replica: Використовується для стандартної стрімінгової реплікації або лише для читання. Цей рівень підтримує фізичну реплікацію, яка працює на бінарному рівні для реплікації всієї інстанції бази даних.
- Logical: Потрібен для логічної реплікації, наприклад для синхронізації окремих таблиць або інтеграції з зовнішніми системами.
Для логічної реплікації потрібно встановити рівень WAL на logical
у файлі postgresql.conf:
wal_level = logical
Інші необхідні налаштування
На публікаторі:
- maxreplicationslots: Встановіть це значення хоча б на кількість очікуваних підписок плюс кілька додаткових слотів для синхронізації таблиць.
- maxwalsenders: Встановіть це значення так, щоб воно відповідало maxreplicationslots та будь-яким фізичним реплікам, які ви плануєте використовувати.
На підписнику:
- maxreplicationslots: Встановіть це значення для обробки очікуваних підписок на підписнику плюс кілька резервних слотів для синхронізації.
- maxlogicalreplicationworkers:_ Встановіть це значення хоча б на кількість підписок плюс додаткові працівники для синхронізації таблиць.
- maxworkerprocesses: Переконайтесь, що це значення встановлено хоча б на (maxlogicalreplication_workers + 1).
Крок 2: Налаштування бази даних
Цей крок включає створення необхідних таблиць і структури в базі даних підписника (отримувача).
Спочатку вибираєте конкретну базу даних, схему та таблиці, які ви хочете копіювати. Потім створюєте порожню копію цієї структури в базі даних підписника. Це гарантує, що підписник готовий отримати дані.
Для цього ми використовуємо дві команди: pgdump_ та pgrestore_:
pg_dump --host= \
--port= \
--username= \
--
--port= \
--username= \
--no-owner \
--dbname= \
--no-acl \
--format=c \
< dump.sql
Після виконання цих команд база даних підписника матиме порожні таблиці з такою ж структурою, як і обрані таблиці на публікаторі.
Тепер ви готові налаштувати фактичний процес реплікації (створення підписок, публікаторів тощо).
Крок 4: Створення публікації на базі даних публікатора
«Публікація» — це спосіб, яким база даних публікатора надає дані для реплікації. Підписники потім «підписуються» на ці публікації, щоб отримувати дані.
Щоб опублікувати конкретні таблиці, використовуйте цю команду:
CREATE PUBLICATION <publication_name> FOR TABLE <table_names>;
Замініть <publication_name>
на описову назву вашої публікації, а <table_names>
на назви таблиць, які ви хочете опублікувати (через коми, якщо таблиць кілька).
Реплікація лише необхідних даних: використання фільтрів у публікаціях бази даних
Ви можете легко контролювати, які дані реплікуються з вашої бази даних, використовуючи вирази фільтрів. Наприклад:
CREATE PUBLICATION <publication_name> FOR TABLE <table_name> WHERE (<column_name> > 10000 AND <column_name> = 'TEST');
Ця команда створює публікацію, яка реплікує тільки ті дані, де значення <column_name>
більше за 10000, а інше значення <column_name>
дорівнює 'TEST'. Це допомагає ефективно реплікувати лише необхідні вам дані.
Крок 5: Налаштування користувача реплікації на базі даних публікатора
Щоб дозволити підписнику доступ до опублікованих даних, потрібно створити користувача з необхідними правами доступу на базі даних публікатора. Важливо дотримуватись принципу найменших привілеїв, що означає, що користувач повинен мати лише ті права, які необхідні для реплікації. Ось як створити цього користувача та надати йому права:
Створіть користувача з логіном і паролем:
CREATE ROLE <username> WITH LOGIN PASSWORD '<password>';
Надати права на реплікацію: для бази даних AWS RDS:
GRANT rds_replication TO <username>;
Надати права на реплікацію: для стандартних установок PostgreSQL:
GRANT replication TO <username>;
Надання доступу до бази даних та схеми:
GRANT CONNECT ON DATABASE <dbname> TO <username>;
GRANT USAGE ON SCHEMA <schema_name> TO <username>;
GRANT SELECT ON <table_name> TO <username>;
Щоб надати доступ до всіх таблиць у схемі:
GRANT SELECT ON ALL TABLES IN SCHEMA <schema_name> TO <username>;
Крок 6: Створення підписки на базі даних підписника
«Підписка» — це спосіб, яким приймаюча база даних (підписник) підключається до публікуючої бази даних для отримання даних. Підписник визначає, які публікації він хоче отримувати.
Щоб створити підписку, використовуйте наступну команду на базі даних підписника:
CREATE SUBSCRIPTION <subscription_name>
CONNECTION 'host=<host> port=<port> user=<username> password=<password> dbname=<dbname>'
PUBLICATION <publication_name>;
Ця команда встановлює підключення і вказує підписнику, які опубліковані дані він повинен отримати.
Після виконання наведених вище кроків, логічна реплікація буде налаштована, і база даних підписника почне отримувати оновлення. Ви можете підтвердити це, безпосередньо запитуючи відповідні таблиці на підписнику. Наступним ми розглянемо налагодження та моніторинг процесу реплікації.
Моніторинг і налагодження реплікації PostgreSQL
Моніторинг і налагодження є важливими для здорової настройки логічної реплікації.
Ось як перевірити та моніторити процес:
Перевірка публікацій на публікаторі:
Використовуйте наступний запит на публікаторі для переліку всіх існуючих публікацій та перевірки їх конфігурації:
SELECT * FROM pg_publication;
Перевірка таблиць у публікації:
Щоб побачити, які таблиці включені в конкретну публікацію, виконайте цей запит на публікаторі:
SELECT * FROM pg_publication_tables WHERE pubname = '<publication_name>';
Моніторинг підписки на підписнику:
Щоб перевірити статус підписки, включаючи затримку та час останнього отриманого повідомлення, використовуйте цей запит на підписнику:
SELECT * FROM pg_replication_slots;
Перевірка логів PostgreSQL на підписнику:
Якщо реплікація не працює, як очікується, перевірте логи PostgreSQL на підписнику на наявність повідомлень про помилки. Ці логи можуть дати важливі підказки щодо проблем з підключенням або неправильних налаштувань.
tail /var/log/postgresql/postgresql-10-main.log
Обмеження логічної реплікації та як з ними працювати
Логічна реплікація пропонує потужний спосіб копіювання змін даних, але має свої обмеження. З ними можна ознайомитись у обмеженнях
Налаштування логічної реплікації PostgreSQL може бути складним процесом, що включає багато кроків на обох базах даних: джерелі (публікатор) і призначенні (підписник). Моніторинг реплікації також вимагає регулярних перевірок і може забирати багато часу.
Як було зазначено раніше, логічна реплікація PostgreSQL має певні обмеження, зокрема проблеми з обробкою змін схем (DDL), що є найбільш поширеним джерелом проблем.
Керування логічною реплікацією за допомогою простого Ruby-скрипту: наш підхід
Щоб полегшити задачу та мінімізувати ручну роботу, ми створили просту утиліту на Ruby, яка автоматизує налаштування. Ми також створили скрипти для безпечного внесення змін до таблиць на обох базах даних без порушення реплікації.
Наша утиліта ефективно обробляє додавання стовпців і індексів за допомогою компонента під назвою ddl_executor
. Однак видалення стовпців може бути складнішим. У деяких випадках вам може знадобитися тимчасово зупинити запис на джерельній базі даних, щоб уникнути неконсистентності даних.
Ви можете знайти утиліту Ruby за адресою pglogicalrepl. Зверніть увагу: ця утиліта не була протестована в повноцінному виробничому середовищі. Для інструкцій щодо використання звертайтеся до файлу README, який додається до коду.
Ось скріншот допомоги команди `./pglrepl.rb help` для цієї утиліти, що демонструє всі доступні команди. Ця утиліта зменшує операційні завдання для логічної реплікації. Крім того, команда **_./pg_l_repl.rb execute_ddl [DDL STATEMENT]
_** дозволяє одночасно виконувати DDL-запити на обох базах даних: підписнику і публікаторі.
Висновок:
Логічна реплікація, пропонуючи гнучкість з можливостями вибіркової реплікації даних та сумісності між версіями, має також операційні витрати. Вона включає вручну виконувані кроки під час налаштування, потребує значного технічного обслуговування через обмеження на операції DDL і може бути ресурсоємною через обробку простих журналів. Це збільшене навантаження на процесор та введення/виведення може вплинути на використання ресурсів, особливо в умовах високої транзакційної активності.
На відміну від цього, фізична реплікація використовує бінарні журнали, що дає можливість швидкої та ефективної реплікації.
Оскільки фізична реплікація працює на рівні зберігання даних, вона мінімізує навантаження на процесор і є більш підходящою для систем з високим пропуском даних, а також для сценаріїв, де потрібна висока доступність та підтримка відмовостійкості, і вимагає дуже мало обслуговування.
Оптимальний вибір між логічною та фізичною реплікацією повністю залежить від специфіки вашого застосунку та вимог.
Використовуйте логічну реплікацію, коли:
- Важлива вибіркова реплікація даних.
- Потрібна сумісність між версіями.
- Потрібна конфігурація з багатьма майстрами.
Використовуйте фізичну реплікацію, коли:
- Важлива висока доступність та підтримка відмовостійкості.
- Потрібна послідовна масштабованість для читання.
- Потрібна точна реплікація даних з основного сервера.
Зрештою, рішення має ґрунтуватися на ретельній оцінці вимог вашого застосунку, цілей масштабованості та потреб у розподілі даних.
Перекладено з: Postgres Logical Replication: Sample Ruby Script & Easy Setup Guide