Логічна реплікація PostgreSQL: слоти зростають, підписка відстає
Логічна реплікація PostgreSQL ламається тихо. Слот реплікації фіксує позицію в журналі попереднього запису й утримує її до підтвердження підписника — якщо підписка зупинена, відстала або не встигає застосовувати зміни, основна база продовжує писати, а звільнити журнал не може.
Вільне місце на розділі з даними витрачається зі швидкістю запису, і зупиняється не реплікація, а сама база.
Далі спрацьовує ланцюжок: переповнення сховища, журналу нікуди писатися, запис зупиняється. Зупинка автоматичного очищення мертвих рядків іде слідом, тому таблиці роздуваються, а після звільнення місця потрібно ще наздогнати накопичене відставання підписника.
Аварійний перезапуск основної бази в цей момент розтягується на години недоступності запису: застосунок отримує відмови, а відновлення потребує ручного розбору — який слот тримає журнал, наскільки відстала підписка, які таблиці розійшлися.
Відставання підписника рідко має одну причину.
Зазвичай складається кілька: підписка ловить конфлікт застосування й падає в циклі, публікація перелічує зайві таблиці, на підписнику не вистачає ресурсів під навантаження застосування, а довгі транзакції на джерелі тримають знімок і не дають позиції зсунутися.
Без спостереження за станом слотів реплікації та відставанням підписки це помічають уже за заповненим диском.
Налаштування реплікації починається із запобіжників: межа, скільки журналу слот має право утримувати, вимкнення невикористовуваних слотів, обмеження списку публікованих таблиць, вимірювання відставання підписки. Далі розбираємо, як це закривається на практиці.
Що змінюється в експлуатації: оновлення без зупинки сервісу
Логічна реплікація передає зміни на рівні рядків, а не копіює базу повністю, тому цільовий контур залишається живим і доступним на читання весь час перенесення.
Публікація на джерелі та підписка на приймачі збираються так, щоб перемикання зайняло хвилини: спочатку накочується структура таблиць, потім дані, і тільки після звірки контрольних сум трафік переводиться на нову базу.
Оновлення структури таблиць перестає бути подією з плановим вікном простою на ніч — це правка в робочому режимі.
Звітне навантаження йде на окремий контур. Важкі з'єднання, повні сканування та агрегації більше не конкурують за пам'ять, з'єднання й час процесора з транзакціями запису — черги на блокуваннях між записом і аналітикою просто не відтворюються.
Основна база обслуговує прикладний потік, і час відгуку запису перестає залежати від того, хто в цей момент будує звіт.
Окремий клас відмов, який іде разом із цим, — тривале вікно блокування та нестача місця при копіюванні бази повністю.
Галузеві розбори інцидентів при міграції, Звіти з експлуатації СУБД, показують, що основна частка незапланованих простоїв припадає саме на ці два сценарії, а не на саму передачу змін.
Практичний результат: зміна схеми на бойовій базі виконується без зупинки сервісу, звітні запити не впливають на прикладні, а повернення на попередній контур залишається можливим на будь-якому кроці, поки триває звірка даних.
Режими реплікації: публікації, підписки та обмеження
Логічна реплікація будується навколо пари «публікація — підписка»: на джерелі публікація описує, які таблиці та які операції потрапляють у потік, на приймачі підписка читає слот і застосовує зміни.
На відміну від повної копії кластера, потік збирається на рівні рядків і таблиць, тому приймач може бути іншої конфігурації й приймати лише частину схеми.
Звідси й розвилка: одна механіка закриває і перенесення окремих таблиць, і обмін між контурами, і вивантаження в аналітику. Вибір визначає, чи потрібен запис на приймачі, скільки таблиць бере участь і хто відповідає за розв'язання конфліктів.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Повна копія кластера | Потрібен дубль усього сервера: відмовостійкість, відновлення | Передається кластер повністю, приймач лише для читання, конфігурації мають збігатися |
| Вибіркова передача таблиць | Потрібна частина схеми: довідники, службові таблиці, переїзд без зупинки | Лише таблиці з первинним ключем або налаштованим ідентифікатором рядків; зміни схеми переносяться вручну |
| Двосторонній обмін між контурами | Кілька майданчиків пишуть одночасно, потрібна збіжність даних | Потрібне правило розв'язання конфліктів: пріоритет вузла, останній запис, відкидання дубля; ризик циклів |
| Вивантаження через проміжну чергу | Потрібно роз'єднати джерело й споживачів, додати фільтрацію та повтор | Затримка вища за пряму підписку; потрібен контроль зміщення та повторної доставки |
| Передача в аналітичний контур на читання | Звіти й аналітика не повинні навантажувати основний вузол | Лише читання, зворотного запису немає, правки в аналітиці до джерела не дійдуть |
Публікації та підписки не замінюють фізичну реплікацію: зміни схеми, послідовності та об'єкти поза таблицями переносяться окремо. Правила розв'язання конфліктів фіксуються до ввімкнення обміну — інакше розбіжність спливе вже в даних.
Етапи робіт: від аудиту навантаження до передачі в експлуатацію
Логічна реплікація переносить не копію сторінок, а потік змін, тому до запуску потрібен профіль навантаження: які таблиці дають основний обсяг запису, як часто змінюється схема, чи є первинні ключі. Порядок етапів нижче не випадковий — кожен наступний спирається на дані попереднього.
- Аудит навантаження та поточної схеми. Знімаємо статистику за обсягом і частотою змін, тривалими запитами, правами та складом об'єктів. Окремо позначаємо таблиці без первинного ключа — для них потрібен свій підхід.
- Проєктування схеми передачі даних. Фіксуємо, що потрапляє в реплікацію, а що залишається локальним, як обходяться секвенції та зміни структури. На виході — схема потоків і список ризиків з планом на кожен.
- Підготовка об'єктів і прав. Створюємо ролі реплікації з мінімально потрібними правами, приводимо ідентифікатори репліки, звіряємо версії та розширення на джерелі й приймачі.
- Налаштування публікацій і підписок. Піднімаємо публікацію на джерелі та підписку на приймачі, стартову синхронізацію запускаємо так, щоб вона не блокувала бойовий запис і не гальмувала застосунки.
- Контроль відставання на бойовому профілі. Спостерігаємо відставання під реальним навантаженням: піки запису, довгі транзакції, конфлікти застосування. Ставимо оповіщення з порогами, щоб зростання помічалося до того, як стане критичним.
- Репетиція перемикання навантаження. Зупиняємо запис, чекаємо нульового відставання, переводимо застосунки на новий вузол, перевіряємо послідовності та фонові завдання. Зворотний відкат проходимо так само.
- Передача регламенту експлуатації. Віддаємо документацію: як читати метрики відставання, що робити при конфлікті, як додати таблицю в публікацію. Чергова зміна розбирає сценарії на тестовому контурі.
Що залишається у вашому контурі: конфігурації та регламенти
Роботи з реплікації закінчуються не запущеною підпискою, а пакетом артефактів, який фізично залишається у вас. Нижче — те, що ми передаємо в контур замовника і без чого потік змін живе рівно до першої нештатної ситуації.
- Файли параметрів сторони, що публікує, і сторони, що підписується, з коментарями, що змінено й чому: новий вузол піднімається копіюванням, а не з пам'яті інженера.
- Опис об'єктів передачі та документація з реплікації: які таблиці входять у публікацію, що виключено свідомо, як обробляються послідовності та конфлікти запису.
- Схема потоків даних: звідки зміни потрапляють у публікацію, через які вузли йдуть, де можна розірвати потік без втрати цілісності.
- Матриця прав доступу: окремі ролі для публікації та підписки, кому дозволено читати стан слотів і хто відповідає за моніторинг.
- Оповіщення про відставання: пороги за затримкою застосування, адресати та порядок ескалації — про розбіжність дізнаємося до того, як її помітить бізнес.
- Інструкція чергової зміни: типові збої, як читати стан підписки, у який момент зупиняти потік і кого піднімати.
- Регламент перемикання та повернення до попередньої схеми плюс пам'ятка з відновлення перерваної підписки — включно з випадком, коли слот на місці, але потік зупинився.
Розбір проєкту: перенесення звітного навантаження без простою
Що було
Звітний контур жив на тому самому сервері, що й бойова база PostgreSQL. Нічні оновлення схеми вимагали зупинки запису на кілька годин, а важкі аналітичні вибірки в пікові години тримали блокування й розганяли відставання підписки до десятків хвилин.
Чергова зміна розбирала такі звернення майже кожну зміну: частина — через затримки звітів, частина — через завислі транзакції.
Що стало
Реплікацію на бойовому контурі розвели на виділений контур аналітики: публікація на конкретний набір таблиць, підписка зі своїм слотом і початковим копіюванням даних без зупинки джерела.
Нові таблиці додаються в публікацію окремим кроком, конфлікти за ключем знімаються повторним застосуванням — оновлення схеми більше не блокує запис.
Метрики до і після: вікно оновлення схеми скоротилося з кількох годин до нуля, відставання репліки тримається в межах хвилини навіть у години пік, на спокійному навантаженні — секунди.
Звернення чергової зміни щодо звітного навантаження скоротилися вчетверо за перший місяць роботи контуру.
Вимірювання підтверджуються двома джерелами: графіком відставання репліки в системі контролю та журналом перемикань підписки. Обидва залишаються в замовника, тому деградацію видно до того, як її помітять користувачі звітів.
Що робити, якщо вже розгорнуто повну копію кластера?
Повна копія кластера й логічна підписка не конфліктують — вони працюють на різних рівнях. Фізична репліка пересилає потік змін усього кластера повністю, а логічна розбирає його на рівні таблиць і передає лише ті, що перелічені в публікації.
Тому публікацію можна підняти на джерелі поряд із уже працюючою копією, дати підписці наздогнати й перемикати споживачів поступово, без зупинки сервісу.
Налаштування при цьому використовуються повторно: ролі, права доступу, мережеві правила та слоти на цільовому вузлі вже є, публікація додається поверх.
Первинну синхронізацію вибраних таблиць робимо не з нуля, а з поточної копії — вона вже містить актуальний зріз, і залишається наздогнати зміни за позицією в журналі. Перехід вкладається в години роботи, а не у вікно простою.
Поки співіснують дві схеми, джерело істини залишається одне.
Споживачі, що читають, продовжують ходити попереднім шляхом, а нові запити направляємо на вибіркові таблиці й звіряємо результат: кількість рядків, контрольні суми за ключовими таблицями, відставання підписки в секундах. Поки відставання не нульове або звірка дає розбіжності, старий контур залишається основним.
Вимикаємо його, коли підписка тримає нульове відставання під бойовим навантаженням і звірка проходить кілька разів підряд без розбіжностей.
Порядок: зупинити запис через попередній шлях, переконатися, що останні зміни дійшли, зняти підписку, потім прибрати фізичну копію й звільнити її дискове місце. Слот, залишений без підписника, — головна загроза: він накопичує журнал і забиває диск.
Технічні сумніви: слоти, відставання, конфлікти
Логічна реплікація — це потік змін із публікації в підписку, і збої трапляються не під час запуску, а в нештатних режимах. Розбираємо п'ять ситуацій, які найчастіше спливають уже в робочому контурі.
Що буде, якщо підписника вимкнено?
Зміни накопичуються в слоті на джерелі: підписка пам'ятає позицію й після ввімкнення продовжить із неї. Поки підписник мовчить, слот утримує журнал, тому на джерелі тримаємо запас місця.
Чи можна передавати частину таблиць?
Так, публікація збирається за списком таблиць або схем, решта не залишає джерело. Приймачі мають існувати заздалегідь із сумісною структурою та первинним ключем.
Як бути з конфліктами при записі в обидва контури?
Конфліктний рядок зупиняє застосування, і підписка чекає втручання. Ми розмежовуємо зони запису за таблицями, а розбіжності розбирає правило розв'язання, а не ручна правка рядків.
Що відбувається зі слотами при простої?
Слот зберігається, навіть якщо підписку видалено, і продовжує утримувати журнал — звідси переповнення диска. У регламент входять моніторинг відставання та видалення невикористовуваних слотів.
Чи потрібно зупиняти сервіс при зміні схеми?
Додавання колонки проходить на живій системі; зміна типу або первинного ключа потребує паузи підписки та повторної синхронізації таблиці. Порядок — приймач, потім джерело, далі потік.
Обговорімо задачу: надішліть схему поточного контуру
Щоб повернутися з оцінкою робіт, а не із загальними міркуваннями, потрібен мінімум вхідних даних — зазвичай вони вже є у вашої команди. Чим точніші вихідні дані, тим менше уточнювальних кіл і тим реалістичніший план робіт за строками.
- Схема поточного контуру: де розміщені джерело та приймач, як пов'язані по мережі, чи є проміжні вузли та балансувальники.
- Список таблиць і послідовностей: що переносимо повністю, що частково, де є секціонування, зовнішні ключі та генеровані значення.
- Вимоги до вікна оновлення: допустиме відставання приймача, чи потрібне перенесення окремих таблиць без зупинки запису.
- Цільовий контур: версія та редакція СУБД, напрямок реплікації — односторонній чи двосторонній, чи потрібний каскад на кілька приймачів.
- Поточні системи контролю: збір журналів, оповіщення щодо відставання слота реплікації та щодо конфліктів застосування змін.
- Обмеження за навантаженням: профіль запису в пікові години, добовий обсяг змін, поведінка при обриві зв'язку.
Опишіть задачу у вільній формі та додайте те, що вже є — цього достатньо, щоб почати. Ми повернемося з оцінкою та планом робіт: етапами, порядком перемикання й точками відкату на кожному кроці.







