Реплікація Proxmox не вдалася: чому це відбувається і як відновити

Було корисно?

Реплікація ламається в найгірший момент: відразу після того, як ви пообіцяли бізнесу, що вузол DR «повністю синхронізований». Потім з’являється один червоний рядок — replication failed — і раптом ваш план перетворюється на скріншот у презентації.

Це практичний польовий посібник із реплікації Proxmox VE, коли вона ламається: що реально відбувається під капотом, як швидко діагностувати вузьке місце й як відновити стан, не перетворюючи невеликий інцидент на довгий вікенд.

Що насправді робить «реплікація» в Proxmox (і чого вона не робить)

У Proxmox VE «реплікація» — це не якась магічна блокова дзеркальна копія для всього, що можна зберігати. Це планова задача, яка — коли ви використовуєте сховище на базі ZFS — створює снапшоти дисків ВМ і передає їх із вузла-джерела на вузол-призначення за допомогою ZFS send/receive. Для локальних пулів ZFS це надійно, швидко й відносно нудно. Якщо ні — значить один із шарів під капотом перестав бути нудним.

Під капотом типовий прогін реплікації виглядає так:

  1. Proxmox координує задачу (для кожної ВМ, за розкладом).
  2. ZFS створює снапшоти для дисків ВМ (datasets або zvols, залежно від макета).
  3. Виконується інкрементальний ZFS send від останнього успішного снапшоту до нового снапшоту.
  4. Потік передається по SSH на цільовий вузол.
  5. На цілі виконується ZFS receive у локальний dataset.
  6. Proxmox записує успіх/помилку та обрізає старі снапшоти реплікації.

Чого це не є:

  • Не механізм HA сам по собі. Воно подає дані на вузол; HA вирішує, де запускати ВМ.
  • Не безперервна реплікація. Це періодичні операції; ваше RPO найкраще — інтервал розкладу плюс затримки задач.
  • Не заміна резервного копіювання. Реплікація охоче реплікує корупцію, видалення та «ой».
  • Не універсальна для будь-якого сховища. Якщо ви не використовуєте ZFS-сумісне сховище, ви в іншому світі трблшутінгу.

Одна цитата, бо вона досі відображає реальність у продакшені: «Надія — це не стратегія.» — переказ ідеї, часто приписуваної лідерам з надійності в операціях.

Цікаві факти та історичний контекст

  • Снапшоти ZFS дешеві, бо це посилання в метаданих, а не повні копії — доки ви не зміните блоки, тоді використання простору зростає із дивергенцією.
  • ZFS send/receive походить із ранніх часів Solaris ZFS і став популярним, бо це портативний, стрімовий примітив реплікації з вбудованою консистентністю.
  • Інкрементальні відправлення вимагають спільного снапшоту на обох сторонах; видаліть його з будь-якого боку — і ланцюг зламається.
  • Реплікація Proxmox завжди була «орієнтована на сховище»: вона побудована навколо семантики ZFS, а не довільного копіювання диска.
  • SSH — це частина вашого pipeline зберігання для ZFS-реплікації; управління ключами й host key можуть зламати «сховище» зовсім не сховищно.
  • Resume tokens (фіча ZFS) дозволяють відновити перервані receives без повторного старту, але вони також створюють заплутані стани, якщо ви їх не розпізнаєте.
  • ZFS може виявляти приховану корупцію за допомогою контрольних сум, але реплікація все одно може поширювати логічну корупцію (наприклад, чисте видалення файлу бази даних).
  • Іменування снапшотів реплікації має значення, бо інструменти очікують патернів; довільне очищення снапшотів може зробити Proxmox «помилковим», коли ZFS насправді в порядку.
  • Дрейф часу — давній ворог: планування, порядок задач, кореляція логів і навіть перевірка сертифікатів ускладнюються через недбале NTP.

Швидкий план діагностики (перевірте 1/2/3)

Це порядок «перестаньте гадати». Ви намагаєтеся за кілька хвилин ідентифікувати вузьке місце, а не читати всі логи з минулого вівторка.

1) Це проблема контрольної площини (Proxmox) чи площини даних (ZFS/SSH/мережа)?

  • Якщо задача не стартує, не може резолвити вузли або повідомляє про проблеми з дозволами: контрольна площина.
  • Якщо вона стартує, але падає в процесі, зависає або повідомляє помилки ZFS receive: площина даних.

2) Підтвердіть стан задачі реплікації та останню помилку

  • Перегляньте логи задач і журнал для worker-а реплікації.
  • Витягніть фактичну помилку ZFS (dataset exists, no space, invalid stream тощо).

3) Перевірте три нудні попередні умови

  • SSH працює без інтерактивності від джерела до цілі для root (або налаштованого користувача).
  • Пули ZFS здорові на обох кінцях і мають вільний простір/резерв.
  • Існує спільний снапшот для інкрементальної реплікації.

4) Якщо задача повільна/зависла, а не «провалена», ізолюйте пропускну здатність

  • Чи обмежена вона мережею? (iperf3, помилки інтерфейсу, дуплекс, невідповідність MTU)
  • Чи обмежена диском? (zpool iostat, txg sync contention)
  • Чи обмежена CPU? (компресія, шифрування, вузьке місце на одному потоці)

Правило рішення: якщо ви не можете назвати вузьке місце за 10 хвилин, ви перевіряєте не ті речі — ви читаєте.

Чому реплікація ламається: реальні режими відмов

1) Розрив ланцюга снапшотів (класична ситуація)

Інкрементальна реплікація ZFS залежить від: «відправити від снапшоту A до снапшоту B». Це вимагає, щоб снапшот A існував на обох сторонах. Якщо хтось видаляє снапшоти на цілі, щоб «зекономити місце», або запускає агресивне обрізання, наступний інкрементальний send упаде, бо немає спільної бази.

Цей режим відмов поширений, бо виглядає як прибирання. Люди бачать снапшоти, припускають, що це «тимчасово», і чистять їх. Потім реплікація вимагає саме той снапшот, який ви щойно видалили.

2) Невідповідність dataset на цілі (не там, не того типу, не та назва)

ZFS receive вибагливий у гарному сенсі. Якщо призначення існує, але не відповідає очікуванням (несумісність типу: dataset vs zvol, несумісні властивості, неправильна семантика mountpoint), receive може кинути помилку. Proxmox очікує певної структури dataset під storage ID. Ручні зміни на цілі можуть зробити наступний receive конфліктним із реальністю.

3) Брак місця (і не лише по df -h)

ZFS потребує запасу для copy-on-write, метаданих і поведінки transaction group. Пул, зайнятий на 95%, не «в порядку». Це пул, що готується до невеликої опери на ім’я ENOSPC.

Також звертайте увагу на:

  • quota/reservation на dataset
  • refquota/refreservation
  • спеціальні класи алокації (special vdev full)
  • поведінку slop space

4) Помилки SSH і управління ключами (сховище “ограблене” в темному провулку)

Реплікація використовує SSH. Це означає, що зміни host key, жорсткіші шифри, відкликані ключі, нові політики jump-host або повернутий пароль root можуть зламати реплікацію помилками, що виглядають як «сховищні», але такими не є.

Жарт №1: SSH — як корпоративний бейдж — усе працює, поки Security не «покращить» його за п’ять хвилин до вікна обслуговування.

5) Проблеми мережевого шляху: MTU, втрата пакетів, асиметрична маршрутизація

ZFS send — це стабільний потік. Якщо мережа втрачає пакети, ви побачите зависання, скидання або пошкоджені потоки. Якщо MTU не співпадає (на одній стороні 9000, на іншій ні), ви можете отримати фрагментацію, дивну продуктивність або повний провал залежно від маршруту.

6) Проблеми зі здоров’ям пулу: degraded, помилки, повільний I/O

Якщо пул деградовано, відбувається resilvering або виникають checksum помилки, реплікація може провалюватися або ставати крижано повільною. Proxmox скаже «failed», але справжня проблема — підсистема зберігання, що задихається.

7) Розбіжності фіч-флагів ZFS і версій

Якщо цільовий пул не підтримує фічу, що використовується у стрімі send (або ви використовуєте raw/encrypted sends без відповідної підтримки), receive може впасти. Це важливо при реплікації між вузлами з різними версіями ZFS або з різними наборами feature flags.

8) Питання з ключами шифрування і raw send/receive

Зашифровані datasets можуть реплікуватися як raw-потоки (залишаючись зашифрованими) або як розшифровані потоки (вимагаючи ключів). Якщо політика змінилася посеред процесу або ключі не завантажені на цілі, ви отримаєте помилки на кшталт «cannot mount» або «key not loaded».

9) Планувальник і конкуренція блокувань

Задачі реплікації можуть конфліктувати з бекапами, операціями, що створюють багато снапшотів, scrub/resilver або іншими I/O спайками. Іноді помилка — це просто тайм-аут або блокування. Іноді — просте «занадто багато задач одночасно», приховане під маскою складності.

10) Пошкоджений або неповний стан receive (resume tokens, часткові datasets)

Перерваний receive може залишити після себе частковий стан. Сучасний ZFS може видати resume token, щоб продовжити. Але якщо receive було перервано і хтось потім вручну «поправив» ситуацію, видаливши снапшоти/datasets, ви можете опинитися в клубку, що потребує акуратного очищення.

Практичні завдання: команди, виводи та рішення

Ось реальні завдання, які можна виконати на вузлах Proxmox. Кожне містить: команду, приклад виводу, що це означає, і рішення.

Task 1: Confirm replication jobs and last status

cr0x@server:~$ pvesr status
JobID          Guest  Target     Status    Last Sync
local-zfs:101  101    pve02      ok        2025-12-26 09:10:02
local-zfs:102  102    pve02      failed    2025-12-26 08:55:14

Значення: Завдання для ВМ 102 провалилось; у вас є часовий штамп для кореляції.

Рішення: Витягніть лог конкретної задачі за цей проміжок часу і для цього VM/job ID перед тим, як щось робити.

Task 2: Read the Proxmox task log for the failed replication

cr0x@server:~$ grep -R "local-zfs:102" /var/log/pve/tasks/active /var/log/pve/tasks/index 2>/dev/null | tail -n 5
/var/log/pve/tasks/index:UPID:pve01:0000A3F1:0B7C9E2A:676D22E2:pvesr:local-zfs:102:root@pam:
cr0x@server:~$ cat /var/log/pve/tasks/UPID:pve01:0000A3F1:0B7C9E2A:676D22E2:pvesr:local-zfs:102:root@pam:
starting replication job 'local-zfs:102'
command: /usr/bin/ssh -o BatchMode=yes pve02 -- zfs receive -o readonly=on -u -F rpool/replica/vm-102-disk-0
cannot receive incremental stream: most recent snapshot of rpool/replica/vm-102-disk-0 does not match incremental source
TASK ERROR: command 'ssh ... zfs receive ...' failed: exit code 1

Значення: Невідповідність інкрементальної бази снапшота. Хтось видалив або змінив снапшоти з одного боку, або dataset розійшовся.

Рішення: Перевірте снапшоти на обох сторонах; плануйте новий повний send (або rebase), а не сліпі повтори.

Task 3: Inspect snapshots on the source dataset

cr0x@server:~$ zfs list -t snapshot -o name,creation -s creation rpool/data/vm-102-disk-0 | tail -n 8
rpool/data/vm-102-disk-0@replicate_2025-12-26_08-00-01  Fri Dec 26 08:00 2025
rpool/data/vm-102-disk-0@replicate_2025-12-26_08-30-01  Fri Dec 26 08:30 2025
rpool/data/vm-102-disk-0@replicate_2025-12-26_08-45-01  Fri Dec 26 08:45 2025
rpool/data/vm-102-disk-0@replicate_2025-12-26_09-00-01  Fri Dec 26 09:00 2025

Значення: На джерелі снапшоти реплікації ідуть далі. Добре.

Рішення: Порівняйте з ціллю. Якщо на цілі відсутній базовий снапшот, треба повне повторне насіння (re-seed) або відновити відповідний снапшот.

Task 4: Inspect snapshots on the target dataset

cr0x@server:~$ ssh pve02 -- zfs list -t snapshot -o name,creation -s creation rpool/replica/vm-102-disk-0 | tail -n 8
rpool/replica/vm-102-disk-0@replicate_2025-12-26_07-30-01  Fri Dec 26 07:30 2025
rpool/replica/vm-102-disk-0@replicate_2025-12-26_08-00-01  Fri Dec 26 08:00 2025

Значення: На цілі відсутні новіші снапшоти, які джерело очікує як базу для інкрементів (або задача очікує пізніший).

Рішення: Визначте останній спільний снапшот і чи відповідає записаний стан Proxmox реальності. Якщо стан неконсистентний — re-seed.

Task 5: Verify SSH non-interactive access and host key sanity

cr0x@server:~$ ssh -o BatchMode=yes -o ConnectTimeout=5 pve02 -- "echo ok && hostname"
ok
pve02

Значення: SSH працює без підтверджень. Це виключає клас помилок, коли чекають пароль або підтвердження hostkey.

Рішення: Якщо це не працює — виправте SSH спочатку. Не чіпайте ZFS, поки контрольна площина не чиста.

Task 6: Check pool health on both nodes

cr0x@server:~$ zpool status -x
all pools are healthy
cr0x@server:~$ ssh pve02 -- zpool status -x
all pools are healthy

Значення: Жодних очевидних помилок пулу.

Рішення: Якщо ви бачите «DEGRADED», «too many errors» або тривале resilvering — розглядайте це як інцидент зі сховищем; реплікація — симптом.

Task 7: Check free space and dataset quotas (the ZFS way)

cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint rpool | head -n 5
NAME    USED  AVAIL  REFER  MOUNTPOINT
rpool   3.21T  620G   192K  /rpool
cr0x@server:~$ ssh pve02 -- zfs list -o name,used,avail,refer,mountpoint rpool | head -n 5
NAME    USED  AVAIL  REFER  MOUNTPOINT
rpool   3.79T  110G   192K  /rpool

Значення: На цілі лишилося лише 110G. Це близько до провалу.

Рішення: Якщо на цілі тісно — не намагайтеся «насильно» реплікувати. Звільніть місце або збільшіть пул перед re-seed; інакше ви створите часткові receives і сплеск снапшотів.

Task 8: Identify if the target has a resume token (interrupted receive)

cr0x@server:~$ ssh pve02 -- zfs get -H -o name,property,value receive_resume_token rpool/replica/vm-102-disk-0
rpool/replica/vm-102-disk-0  receive_resume_token  -

Значення: Немає resume token. Ціль не чекає на відновлення часткового потоку.

Рішення: Якщо ви бачите довгий токен, вирішіть, відновлювати його (переважно) або відкотити/скасувати (ризиковано) залежно від політики й часу.

Task 9: Run a manual dry-run of incremental send size (capacity planning)

cr0x@server:~$ zfs send -nPv -i rpool/data/vm-102-disk-0@replicate_2025-12-26_08-00-01 rpool/data/vm-102-disk-0@replicate_2025-12-26_09-00-01
send from @replicate_2025-12-26_08-00-01 to rpool/data/vm-102-disk-0@replicate_2025-12-26_09-00-01 estimated size is 18.4G
total estimated size is 18.4G

Значення: Дельта ~18.4G. Корисно для рішення, чи достатньо пропускної здатності та вільного місця на цілі.

Рішення: Якщо оцінювана дельта велика — перенесіть реплікацію з години пік або збільште інтервал; великі дельти зазвичай означають, що розклад занадто рідкісний або задачі неодноразово падають.

Task 10: Measure network throughput quickly

cr0x@server:~$ iperf3 -c pve02 -t 10
Connecting to host pve02, port 5201
[  5]   0.00-10.00  sec  8.76 GBytes  7.52 Gbits/sec  0             sender
[  5]   0.00-10.00  sec  8.75 GBytes  7.52 Gbits/sec                receiver

Значення: ~7.5 Gbit/s ефективно. Не ідеальні 10G, але, ймовірно, достатньо, якщо ваші дельти не гігантські.

Рішення: Якщо ви бачите 200–800 Mbit/s на лінку 10G — перестаньте звинувачувати ZFS. Перевірте MTU, помилки, маршрутизацію й завантаження.

Task 11: Inspect interface errors and MTU

cr0x@server:~$ ip -s link show dev bond0
2: bond0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    RX:  bytes  packets  errors  dropped  missed  mcast
    91234567890  81234567  0  0  0  0
    TX:  bytes  packets  errors  dropped  carrier  collsns
    82345678901  72345678  0  0  0  0
cr0x@server:~$ ssh pve02 -- ip link show dev bond0 | head -n 2
2: bond0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000

Значення: Невідповідність MTU. Це може робити реплікацію повільною або крихкою залежно від маршруту.

Рішення: Уніфікуйте MTU на всьому шляху (включно зі свічами). Не «половинчасті» jumbo і не надійтеся на краще.

Task 12: Check Proxmox and system logs around the failure

cr0x@server:~$ journalctl -u pvedaemon -u pveproxy -u pvescheduler --since "2025-12-26 08:45" --until "2025-12-26 09:05" | tail -n 30
Dec 26 08:55:14 pve01 pvescheduler[1123]: starting replication job local-zfs:102
Dec 26 08:55:18 pve01 pvedaemon[1109]: VM 102: replication job failed: exit code 1

Значення: Підтверджує час і що це рівень задачі, а не глюк GUI.

Рішення: Якщо бачите повторні повторні спроби, тайм-аути або накладання задач — можливо, треба підкоригувати розклади або обмеження конкурентності.

Task 13: Validate the target dataset exists and is the expected type

cr0x@server:~$ ssh pve02 -- zfs list -o name,type,volsize,used,avail rpool/replica/vm-102-disk-0
NAME                         TYPE   VOLSIZE  USED  AVAIL
rpool/replica/vm-102-disk-0   volume 128G     91G   110G

Значення: На цілі — zvol («volume»). Це відповідає збереженню дисків ВМ як zvols.

Рішення: Якщо тип — «filesystem», а ви очікуєте «volume», зупиніться і виправте макет dataset — форсований receive у неправильний тип творить креативні катастрофи.

Task 14: Perform a controlled full re-seed (manual ZFS send/receive)

cr0x@server:~$ zfs snapshot rpool/data/vm-102-disk-0@replicate_reseed_2025-12-26_09-30
cr0x@server:~$ zfs send -Pv rpool/data/vm-102-disk-0@replicate_reseed_2025-12-26_09-30 | ssh pve02 -- zfs receive -u -F rpool/replica/vm-102-disk-0
send from rpool/data/vm-102-disk-0@replicate_reseed_2025-12-26_09-30 estimated size is 92.1G
total estimated size is 92.1G
TIME        SENT   SNAPSHOT
00:00:10    5.62G  rpool/data/vm-102-disk-0@replicate_reseed_2025-12-26_09-30

Значення: Ви перезаписуєте/відкатуєте ціль, щоб узгодити стан із джерелом, використовуючи -F для примусового rollback на цільовому dataset.

Рішення: Використовуйте -F тільки коли ви впевнені, що ціль — це репліка й там не працює жива ВМ. Якщо ця ціль «активна», ви щойно знищите активний стан диска.

Task 15: After re-seed, validate snapshot alignment and replication readiness

cr0x@server:~$ ssh pve02 -- zfs list -t snapshot -o name -s creation rpool/replica/vm-102-disk-0 | tail -n 3
rpool/replica/vm-102-disk-0@replicate_2025-12-26_08-00-01
rpool/replica/vm-102-disk-0@replicate_2025-12-26_09-00-01
rpool/replica/vm-102-disk-0@replicate_reseed_2025-12-26_09-30

Значення: На цілі тепер є reseed снапшот і попередні (залежно від того, що було відправлено). У вас знову є спільна база.

Рішення: Увімкніть реплікацію Proxmox для цієї ВМ/задачі і спостерігайте наступний інкрементальний прогін. Якщо він знову впаде — ймовірно системна проблема (місце, обрізання, колізії розкладів).

Task 16: Check for ZFS receive errors that hint at feature/encryption mismatch

cr0x@server:~$ ssh pve02 -- zpool get -H -o value feature@encryption rpool
active

Значення: Цільовий пул підтримує feature flag encryption.

Рішення: Якщо це «disabled» або «inactive», а джерело використовує зашифровані datasets, очікуйте помилок receive. Узгодьте підтримку фіч ZFS або змініть режим відправлення.

Плани відновлення, що не створюють нових проблем

Є дві основні стратегії відновлення: відновити ланцюг або пересіяти повністю (re-seed). Неправильний вибір марнує час; безпечний вибір ризикує втратою даних.

План A: Відновлення ланцюга снапшотів (коли можливо)

Використовуйте це, коли на цілі все ще є спільний снапшот, але стан Proxmox заплутався або нещодавній снапшот відсутній через перерване завдання.

  • Підтвердіть останній спільний снапшот на обох сторонах.
  • Не видаляйте нічого «щоб почистити», поки не дізнаєтеся, чого очікує Proxmox.
  • Якщо є resume token — спробуйте resume перед re-seed.
  • Запустіть ручний інкрементальний send із явними іменами снапшотів, щоб довести працездатність ланцюга.

Перевага: мінімум трафіку й часу. Недолік: потребує дисципліни й ретельної перевірки.

План B: Повний re-seed (грубий інструмент, що працює)

Використовуйте це, коли ланцюг зламаний, снапшоти були обрізані несинхронно або цільовий dataset розійшовся.

  • Переконайтеся, що цільовий dataset не використовується запущеною ВМ.
  • Переконайтеся в достатньому вільному просторі на цілі (реальний запас).
  • Зробіть новий reseed снапшот на джерелі.
  • Відправте його з примусовим receive у replica dataset.
  • Перевірте снапшоти та увімкніть заплановану реплікацію.

Жарт №2: Re-seed — як перевстановлення ОС, щоб виправити драйвер — ефективно, трохи соромно і іноді найкраще рішення.

Коли зупинитися і ескалувати

Зупиніться «пробувати речі» й ескалюйте до інциденту зі сховищем, якщо ви бачите:

  • зростання помилок пулу, checksum помилки або повторювані тайм-аути пристроїв
  • раптове падіння швидкості реплікації, при якому zpool iostat показує довгі очікування
  • цільовий пул майже повний і висока фрагментація
  • запущений scrub/resilver у вікнах реплікації

Три міні-історії з корпоративного життя (анонімізовані, правдоподібні, повчальні)

Міні-історія 1: Неправильне припущення, що зламало DR

Організація мала два кластери Proxmox: первинний і «теплий DR». Реплікація працювала щогодини і місяцями була зеленою. Сховище було ZFS з обох сторін, різні покоління заліза, однакова схема іменування dataset. Усі спокійно спали.

Потім прийшов новий інженер і зробив те, що роблять сумлінні люди: прибрав те, що виглядало як сміття. На DR він побачив купу снапшотів з іменами артефактів реплікації і вирішив, що це старі залишки. Він обрізав їх скриптом. Простір звільнився. Дашборди ще деякий час були зеленими, бо нічого не запускалося одразу.

На наступному циклі реплікації третина ВМ впала. Помилки писали, що інкрементальна базова снапшот не відповідає. Інженер (намагаючись допомогти) видалив ще снапшотів, думаючи, що Proxmox їх відновить. Це припущення: «снапшоти реплікації — тимчасові». Вони ні. Вони — ланцюг.

Відновлення технічно не було складним — повні re-seed допомогли — але операційно було неприємно. Кілька великих ВМ потребували повних відправлень через вже навантажене посилання у робочий час. Команді довелось обмежувати й перенавчувати задачі, і RPO DR було поганим цілий день. Постмортем підсумував велику жирну поради: ніколи не обрізайте снапшоти реплікації вручну, якщо ви не плануєте спеціально re-seed.

Міні-історія 2: Оптимізація, що відкотилася

Інша компанія хотіла зменшити час реплікації. Хтось помітив, що налаштування компресії відрізняються між пулами. Також бачили запас CPU на вузлах. Чудово: увімкнемо агресивну компресію, піднімемо частоту реплікацій і подивимось, як дельти зменшаться.

Вони змінили властивості ZFS на джерельних datasets на більш агресивний режим компресії. На папері: менше трафіку, швидша реплікація, менше місця. На практиці: у години пік з’явилася конкуренція за CPU на гіпервізорі й збільшилась затримка ВМ. Невелика — але достатня, щоб кілька чутливих сервісів стали флейкі.

Потім відкот став ще гіршим: задачі реплікації почали накладатися з бекапами. Обидві операції створювали багато снапшотів. Система витрачала більше часу на створення снапшотів, обрізання й синхронізацію txg, ніж на передачу даних. Реплікація стала час від часу падати через тайм-аути і блокування, що збільшувало дельти, що робило реплікацію довшою, що викликало ще більше накладань — приємний замкнений цикл.

Виправлення було нудним: пом’якшили компресію до збалансованих налаштувань, розділили вікна для реплікації й бекапів, ввели обмеження конкурентності. Деякі виграші зберегли, самонанесена затримка зникла, і передбачуваність повернулась — справжня валюта в операціях.

Міні-історія 3: Нудна практика, що врятувала день

Фінансова компанія мала звичку, що виглядала параноїдально: кожного місяця вони виконували контрольну DR-перевірку для кількох ВМ. Не масштабний тест, а обертовий вибір. Вони перевіряли, що replicated datasets присутні, що ВМ може завантажитись, і що перевірки на рівні застосунку проходять.

Одного місяця тест не пройшов. ВМ на DR не завантажувалась, бо replica dataset був присутній, але неповний. Статус реплікації показував «ok» для останнього запуску, але попередній частковий receive залишив dataset у неконсистентному стані «виглядає як є». Ніхто не помітив, бо основний вузол був у порядку, а дашборди люблять мовчати про такі речі.

Завдяки тесту вони виявили проблему до того, як вона стала критичною. Вони призупинили нові реплікації, виправили мережеву нестабільність і re-seed кілька дисків. Інцидент залишився в системі як тикет, а не заголовок новин.

Ось секрет: регулярна, нудна DR-практика змушує вас перевіряти весь ланцюг — ZFS, SSH, стан Proxmox і можливість завантаження. Вона також змушує підтримувати runbook у робочому стані, бо ви ним користуєтесь.

Типові помилки (симптом → корінна причина → виправлення)

1) «Most recent snapshot does not match incremental source»

Симптом: Реплікація падає з помилками інкрементальної невідповідності.

Корінь: Розірваний ланцюг снапшотів — снапшоти видалені на цілі/джерелі або dataset розійшовся через ручні зміни.

Виправлення: Знайдіть останній спільний снапшот; якщо його немає — зробіть контрольований повний re-seed з новим снапшотом і примусовим receive. Перестаньте видаляти снапшоти «поки не запрацює».

2) «cannot receive: destination exists» або «dataset already exists»

Симптом: Receive падає негайно.

Корінь: Цільовий dataset існує, але не є очікуваною ціллю репліки, або аргументи receive не відповідають (відсутній -F там, де треба).

Виправлення: Перевірте тип dataset і бажану структуру. Якщо це справжня репліка — використовуйте контрольований zfs receive -F. Якщо ні — перейменуйте або переналаштуйте storage layout, щоб уникнути колізій.

3) «No space left on device» під час receive

Симптом: Задача падає в середині потоку, іноді залишаючи частковий стан.

Корінь: Цільовий пул/dataset повний, квоти або недостатній запас призводять до ENOSPC під тиском copy-on-write.

Виправлення: Звільніть простір правильно (видалення старих бекапів, розширення пулу, корекція квот). Потім очистіть часткові receives і, за потреби, re-seed.

4) Реплікація «застрягла» або триває вічно, але не падає

Симптом: Задачі йдуть годинами, шикуються в чергу.

Корінь: I/O конкуренція з бекапами/scrub, падіння пропускної здатності мережі або повільні диски на цілі.

Виправлення: Виміряйте: iperf3, zpool iostat і помилки інтерфейсу. Розділіть вікна, обмежте конкурентність і уникайте scrub під час піків реплікації.

5) «Host key verification failed» або запити пароля в логах

Симптом: Реплікація падає одразу; логи згадують SSH.

Корінь: Змінені host keys, відсутні ключі або BatchMode не працює.

Виправлення: Відновіть довіру SSH і ключі. Підтвердіть, що ssh -o BatchMode=yes працює. Потім перезапустіть реплікацію.

6) Статус реплікації зелений, але DR завантаження не працює

Симптом: Спроба запустити репліковану ВМ приводить до паніки або відсутнього/пошкодженого диска.

Корінь: Репліка dataset неповний, неправильно змонтований, ключі шифрування не завантажені або отримано неправильний dataset.

Виправлення: Перевірте властивості dataset, стан ключів шифрування і виконуйте періодичні тестові завантаження. У сумнівних випадках — re-seed уражених дисків.

Контрольні списки / покроковий план

Чекліст: Перед тим, як почати відновлення

  1. Підтвердіть, який вузол — джерело, а який — ціль для проваленої задачі.
  2. Підтвердіть, що цільовий dataset не використовується запущеною ВМ.
  3. Збережіть лог провалу (лог задачі + точна помилка ZFS). Не покладайтеся на пам’ять.
  4. Перевірте SSH BatchMode-підключення.
  5. Перевірте здоров’я пулу та вільне місце на обох кінцях.
  6. Перелічіть снапшоти на обох кінцях і знайдіть останній спільний снапшот.

Покроково: Відновлення інкрементальної реплікації (переважно, коли можливо)

  1. Визначте останній спільний снапшот (точне написання).
  2. Оцініть розмір відправки за допомогою zfs send -nPv -i.
  3. Запустіть ручний інкрементальний send/receive, щоб підтвердити працездатність ланцюга.
  4. Перезапустіть задачу реплікації Proxmox і спостерігайте наступний прогін.
  5. Після успіху перегляньте політики збереження, щоб базовий снапшот не обрізався передчасно.

Покроково: Повний re-seed (коли ланцюг зламаний)

  1. Зупиніть або призупиніть задачу реплікації (щоб вона не змагалася з вами).
  2. Переконайтеся, що ціль має достатній запас; спочатку розширте або очистіть.
  3. Створіть новий «reseed» снапшот на джерелі.
  4. Відправте повний снапшот на ціль з примусовим receive (-F) лише якщо безпечно.
  5. Перевірте, що снапшот на цілі існує й відповідає.
  6. Увімкніть реплікацію і моніторте.

Чекліст: Після відновлення (не пропускайте)

  1. Запустіть ще один цикл реплікації успішно для ВМ.
  2. Підтвердіть, що вільне місце на цільовому пулі стабільне (не прямує до повного).
  3. Переконайтесь, що розклади не сильно накладаються з бекапами/scrub.
  4. Виконайте DR boot тест для принаймні однієї відновленої ВМ, якщо політика дозволяє.
  5. Задокументуйте корінну причину в одному абзаці так, щоб втомлений on-call це зрозумів.

FAQ

1) Чи є реплікація Proxmox тим самим, що й бекап?

Ні. Реплікація зберігає nearline-копію дисків ВМ на іншому вузлі, зазвичай для швидкого failover. Бекапи — це архіви точок часу з довготривалим зберіганням для відновлення. Бажано мати обидва.

2) Чому реплікація падає після того, як я «почистив старі снапшоти»?

Бо інкрементальна реплікація вимагає спільного снапшоту на обох вузлах. Видалення реплікаційних снапшотів розриває ланцюг. Якщо потрібно обрізати, робіть це через політики Proxmox або будьте готові до re-seed.

3) Чи можу я просто натискати «Retry», поки не запрацює?

Можете, але так ви перетворите розрив ланцюга на чергу задач. Retry доречний після виправлення кореневої причини (SSH, місце, MTU). Якщо помилка каже про інкрементальну невідповідність — повтори не створять відсутні снапшоти.

4) Яке найбезпечніше «велике молоток» вирішення?

Повний re-seed до цільового dataset, виконаний свідомо: перевірте, що ціль не використовується, достатньо місця, зніміть снапшот джерела, zfs send до zfs receive -F. Молоток безпечний, коли ви знаєте, що влучаєте.

5) Як зрозуміти, чи проблема в мережі?

Виміряйте. Використовуйте iperf3, перевірте помилки інтерфейсу через ip -s link і підтвердіть співпадіння MTU по всьому шляху. Якщо пропускна здатність низька і є помилки/втрати — реплікація ні в чому не винна.

6) Чи допомагає компресія ZFS реплікації?

Іноді. Вона може зменшити байти для передачі, але збільшує навантаження на CPU і може посилити конкуренцію під час пікових навантажень. Оптимізуйте для передбачуваності в першу чергу, швидкості — у другу.

7) Чи можуть зашифровані datasets реплікуватися без проблем?

Так, але треба узгодити очікування: raw encrypted send залишає дані зашифрованими; розшифровані sends вимагають завантажених ключів і поводяться інакше. Невідповідність фіч-флагів ZFS або відсутні ключі зламають receive.

8) Чому реплікація показує «ok», але репліка не завантажується?

Бо «ok» зазвичай означає, що остання задача повернула успіх — не те, що ви перевірили завантаження. Часткові datasets, неправильне відображення призначення або проблеми з ключами можуть залишатися. Тестуйте завантаження періодично.

9) Чи треба реплікувати кожну ВМ якнайчастіше?

Ні. Реплікація має витрати: снапшоти, I/O, обрізання і конкуренція задач. Класифікуйте ВМ за потребами RPO і розробіть розклад, що відповідає реальності.

10) Що варто автоматизувати як перше?

Сповіщення про: відмови реплікації, використання цільового пулу >80%, зростання помилок інтерфейсу і відсутність останніх снапшотів на цілі. Люди добре вирішують проблеми, але погано помічають повільне деградування.

Наступні кроки, які варто зробити

Якщо реплікація впала сьогодні, зробіть це в порядку:

  1. Витягніть точний лог задачі й витягніть рядок помилки ZFS/SSH.
  2. Перевірте SSH BatchMode і здоров’я пулів на обох кінцях.
  3. Перегляньте вільний простір на цілі й наявність снапшотів; знайдіть останній спільний снапшот.
  4. Якщо ланцюг цілий — відновіть інкременти. Якщо зламаний — re-seed свідомо.
  5. Після відновлення усуньте політичну причину: обрізання снапшотів, тренди заповнення, накладання розкладів, невідповідність MTU або управління ключами.

Мета реплікації — не зробити дашборди зеленими. Мета — зробити відмову нудною. Коли реплікація ламається, ставтесь до цього як до будь-якого іншого виробничого пайплайну: контрольна площина першою, площина даних другою і жодних «прибирань», поки ви не довели, чого саме бракує.

← Попередня
Спадкова магія: ніхто не знає, як це працює — не чіпайте
Наступна →
8088 і угода IBM про ПК, яка коронувала Intel (майже випадково)

Залишити коментар