Пошкодження поштових скриньок Dovecot: кроки відновлення з мінімізацією шкоди

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

Спочатку ви відчуваєте це як атмосферу. Користувачі скаржаться, що кількість непрочитаних підказує щось дивне, папки показують «фантомні» повідомлення, пошук бреше, або Outlook зависає на «Synchronizing…» назавжди. Потім логи починають веселитися: «Corrupted index», «UID validity changed», «Mailbox GUID mismatch», «Internal error occurred». У вас поштові скриньки пошкоджені, і кожен клік ризикує перетворити виправлення на повну втрату даних.

Це продакшн-плейбук для відновлення поштових скриньок Dovecot способом, що мінімізує шкоду. Він суб’єктивний, бо невизначеність — це те, як ви «відновлюєте» єдину копію скриньки фінансового директора рекурсивним видаленням.

Практична модель: що означає «пошкодження» в Dovecot

Dovecot — це не монолітне «сховище пошти». Це набір поведінок, який накладається на обраний формат зберігання (Maildir, mdbox, sdbox) плюс метадані (індекси, кеші, списки UID), плюс опціональні функції (quota, full-text search), плюс поведінка клієнта (IMAP IDLE, CONDSTORE, QRESYNC).

Пошкодження поштової скриньки в Dovecot зазвичай означає одну з трьох речей:

  1. Метадані суперечать реальності. Файли індексів кажуть, що повідомлення X існує, але підлеглий файл або запис повідомлення відсутній (або навпаки). Більшість «корупційних» звернень потрапляють сюди.
  2. Підлегла система зберігання неконсистентна. Імена файлів Maildir пошкоджені, дублюються, частково записані; або mdbox map/log вийшли з синхрону; або файловa система повернула застарілі/часткові дані. Саме тут важливо мінімізувати шкоду.
  3. Подання клієнта несумісне з тим, що тепер стверджує сервер. UIDVALIDITY changes, modseq скидається, помилки «unknown UID». Сервер може бути правий, але треба впоратися з наслідками на клієнтах.

Чого не варто робити: трактувати корупцію як одну помилку з єдиним вирішенням. Це невідповідність між шарами. Ваше завдання — ідентифікувати, який шар «бреше», а потім примусово виконати контрольовану звірку в безпечному напрямку.

За замовчуванням — найбезпечніший напрямок: віддавати перевагу підлеглому сховищу повідомлень як джерелу істини, а потім відбудовувати метадані. Але якщо підлегле сховище пошкоджене, може знадобитися зробити знімок, скопіювати те, що читається, і відбудувати сховище з експортованих повідомлень.

Також: «пошкодження» часто є лише симптомом чогось іншого: флаттер зберігання, антивірус, що сканує in-place, багаті мережеві FS семантики, або занадто «розумний» скрипт міграції.

Цитата, яку варто повісити на дошці: (перефразована ідея) «Сподівання — це не стратегія» — часто приписується інженерам з операцій. У ремонті скриньок сподівання — це як ви перезаписуєте останню хорошу копію.

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

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

Перший: підтвердьте радіус ураження і чи відбуваються записі

  • Це один користувач, одна скринька чи все одразу?
  • Клієнти все ще пишуть (нова доставка, IMAP APPEND, зміни прапорів)?
  • Ви бачите активні помилки файлової системи або диска?

Якщо записі тривають і сховище нестабільне, ви не «ремонтуєте», ви граєтеся в азартну гру. Заморозьте або ізолюйте.

Другий: класифікуйте відмову за підписом логу

  • Індекси/кеші: «Corrupted index file», «cache file is corrupted», «index header mismatch». Зазвичай виправляється відбудовою індексів.
  • UID/UIDVALIDITY: «UIDVALIDITY changed», «Invalid UIDNEXT», «uidlist corruption». Більший вплив на клієнтів, але зазвичай це теж відновлення метаданих.
  • Рівень сховища: «read() failed», «Short read», «mbox map corrupted», «mdbox: rebuild failed», «Invalid message size». Це може бути реального пошкодження даних.

Третій: вирішіть позу відновлення

  1. Недеструктивний ремонт: знімок/бекап, зупинити записи, відбудувати індекси, примусово синхронізувати.
  2. Контрольована реконструкція: експортуйте те, що читається (або dsync з репліки), збудуйте чисту скриньку, імпортуйте назад.
  3. Режим судової експертизи: збережіть усе, зробіть копію і працюйте над копією, коли є юридичні/комплаєнс вимоги.

Перед тим як щось торкатися: правила безпеки, що запобігають шкоді

Відновлення поштових скриньок — одна з тих задач, де інструмент зробить саме те, що ви попросили, а не те, що ви мали на увазі. Ваш головний наказ — не перетворити локальну неконсистентність на незворотне видалення.

Правило 1: Заморожуйте записи або ізолюйте скриньку

Відбудова метаданих під час модифікації скриньки призводить до повторного пошкодження, зміни UIDNEXT і клієнтів, що ніколи не сходяться. Для одного користувача тимчасово вимкніть доступ або направте його на хост обслуговування. Для всього бекенду можливо зупинити IMAP/LMTP на короткий час або злити проксі.

Правило 2: Зробіть знімок/беккап каталогу скриньки (включно з індексами)

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

Правило 3: Працюйте на копії, коли саме сховище може бути пошкоджено

Якщо файлова система видає помилки, не запускайте агресивні команди ремонту на єдиній копії. Клонування тома або хоча б rsync дерева скриньки на здорове сховище — мінімум.

Правило 4: Віддавайте перевагу відбудові над «хірургічними правками»

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

Короткий жарт #1: Пошкодження поштових скриньок — як блискітки: здається, ви все прибрали, а потім воно з’являється в логах ще три тижні.

Факти та історичний контекст (чому це відбувається)

  • Індекси Dovecot — це оптимізація, а не джерело істини. Вони існують, щоб IMAP працював швидко: швидкі запити прапорів, сортування, ниткування та кеш.
  • Maildir спроєктовано для безпечної concurent доставки з використанням семантики імен файлів, але воно припускає файлову систему, що підтримує атомарний rename і консистентні операції директорій.
  • UIDVALIDITY IMAP — це контракт з клієнтами. Змініть його — і клієнти можуть вважати це іншу скриньку; деякі з них перезавантажаться, деякі продублюють повідомлення, деякі просто засмучені.
  • dsync виник для потреб реплікації Dovecot і тепер — корисний інструмент ремонту, бо змушує отримати консистентний вигляд шляхом повторного обходу сховища.
  • mdbox/sdbox з’явилися, бо «один файл на повідомлення» в Maildir не завжди дружні до дисків (навантаження на inode, масштабування директорій, витрати на бекап). Вони жертвують простотою файлової системи заради керованої Dovecot консистентності.
  • Багато повідомлень про корупцію — насправді баги семантики сховища — особливо мережеві файлові системи, що не поводяться як локальні POSIX під rename/fsync навантаженням.
  • Dovecot завжди був вибагливим щодо версій індексів. Оновлення можуть викликати відбудову індексів; змішування старих і нових бінарників проти тих самих індексів може створювати плутанину.
  • Індекси повнотекстового пошуку (FTS) відокремлені від індексів поштових скриньок і можуть бути неправильними, поки пошта в порядку. Користувачі називають це «втраченими листами». Зазвичай це «втрачені результати пошуку».

Це не виправдання. Це підказки. Режими відмов формувалися десятиліттями очікувань IMAP та незручної правди, що електронна пошта — розподілена система з власними припущеннями.

Тріаж за форматом зберігання: Maildir vs mdbox/sdbox

Maildir: ваші повідомлення — це файли

У Maildir пошкодження часто означає неконсистентність директорій і імен файлів:

  • Повідомлення знаходяться в tmp/, які ніколи не були переміщені до new/ або cur/.
  • Дубльовані імена файлів або неунікальні базові імена (часто через некоректну поведінку агента доставки).
  • Клієнти та сервер не погоджуються щодо прапорів, бо імена файлів кодують прапори, а кеші метаданих відстають.
  • Проблеми файлової системи викликають часткові записи або дивні записи в директоріях.

Позиція відновлення: збережіть дерево директорій, а потім відбудуйте індекси/кеші Dovecot. Якщо файли повідомлень пошкоджені — переходьте до вилучення.

mdbox/sdbox: ваші повідомлення — це записи, а Dovecot керує мапами

У mdbox повідомлення зберігаються в більших файлах, а Dovecot використовує відображення/індекси для розташування записів повідомлень. Корупція може проявлятися як:

  • Несинхронність map/index: метадані вказують на запис, який не розбирається.
  • Пошкодження логів або map після некоректного завершення або проблем зі сховищем.
  • Події «диск заповнений», що обрівають запис посеред запису.

Позиція відновлення: будьте консервативні. Спершу зробіть знімок. Відбудовуйте метадані стандартними Dovecot інструментами; уникайте «виправлення» шляхом видалення випадкових файлів dovecot.index* без розуміння формату й обсягу.

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

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

Завдання 1: Визначте пошкоджену скриньку та підпис помилки

cr0x@server:~$ sudo journalctl -u dovecot --since "2 hours ago" | egrep -i "corrupt|uidvalidity|uidnext|index|mdbox|sdbox|short read|internal error" | tail -n 30
Jan 03 10:41:12 mx1 dovecot[2219]: imap(user@example.com)<11234>: Error: Mailbox INBOX: Corrupted index file /var/vmail/example.com/user/dovecot.index: Header size mismatch
Jan 03 10:41:14 mx1 dovecot[2219]: imap(user@example.com)<11234>: Error: Mailbox INBOX: UIDVALIDITY changed (14211 -> 18602)

Значення: Маємо підпис корупції індексу та зміну UIDVALIDITY (або Dovecot так думає). Це, ймовірно, територія відбудови метаданих, але потрібно зупинити записи або уникнути хаосу.

Рішення: Переведіть у режим технічного обслуговування уражену скриньку (блокування логіну або направлення користувача) і зробіть знімок перед ремонтами.

Завдання 2: Підтвердіть версію Dovecot та бекенд зберігання

cr0x@server:~$ dovecot --version
2.3.19.1
cr0x@server:~$ doveconf -n | egrep -i "mail_location|mail_driver|mail_home|namespace inbox|mail_plugins"
mail_location = maildir:/var/vmail/%d/%n
mail_plugins = quota fts fts_lucene

Значення: Це Maildir, і у вас є quota + FTS. Очікуйте окремих проблем з FTS і потреби перерахунку квот після ремонту.

Рішення: Плануйте спочатку відбудувати індекси поштової скриньки; FTS відбудовуйте лише коли пошта стане консистентною.

Завдання 3: Перевірте сигнали здоров’я файлової системи (не ремонтуйте на вмираючому диску)

cr0x@server:~$ dmesg -T | egrep -i "ext4|xfs|btrfs|zfs|I/O error|blk_update_request|nvme|ata|sense" | tail -n 20
[Fri Jan  3 10:35:22 2026] EXT4-fs warning (device sdb1): ext4_end_bio:342: I/O error 10 writing to inode 928381 (offset 0 size 4096 starting block 1234567)

Значення: Є помилки запису I/O. Якщо ви зараз відбудовуєте індекси, ви можете записувати ще більше метаданих у несправну файлову систему.

Рішення: Зупиніться. Стабілізуйте сховище: переключіться на резерв, монтуйте в режимі тільки для читання якщо потрібно, або відновіть із знімка/репліки.

Завдання 4: Перевірте вільне місце та доступність inode (класичний тихий вбивця)

cr0x@server:~$ df -h /var/vmail
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       2.0T  1.9T   12G 100% /var/vmail
cr0x@server:~$ df -i /var/vmail
Filesystem     Inodes   IUsed   IFree IUse% Mounted on
/dev/sdb1     61054976 61054912     64  100% /var/vmail

Значення: Диск і inode заповнені. Maildir почне ламатися дивними способами, бо не може створити нові файли для доставки або відбудови індексів.

Рішення: Звільніть простір/іноди спершу, потім адресуйте корупцію. Інакше ви «виправите» її в гірший стан.

Завдання 5: Зробіть знімок/беккап каталогу скриньки перед змінами

cr0x@server:~$ sudo rsync -aHAX --numeric-ids --info=progress2 /var/vmail/example.com/user/ /srv/recovery-snapshots/example.com/user-2026-01-03/
...output...

Значення: У вас тепер копія у часі, з якої можна робити diff і відкотитися. Якщо rsync видає помилки — це сам по собі сигнал цілісності сховища.

Рішення: Якщо rsync повідомляє про помилки читання, переходьте в режим судової експертизи: клонування файлової системи і уникнення подальших записів.

Завдання 6: Перевірте список скриньок і базовий доступ за допомогою doveadm (перевірка тільки для читання)

cr0x@server:~$ sudo doveadm mailbox list -u user@example.com | head
INBOX
Sent
Drafts
Trash
Archive

Значення: Dovecot може перерахувати скриньки. Якщо це завершується з internal errors, корупція може бути ширшою, ніж одна папка.

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

Завдання 7: Перевірте статус скриньки на наявність неконсистентних лічильників

cr0x@server:~$ sudo doveadm mailbox status -u user@example.com messages unread uidvalidity uidnext highestmodseq vsize INBOX
messages=842 unread=19 uidvalidity=18602 uidnext=901 highestmodseq=120044 vsize=188392012

Значення: Отримали когерентний рядок статусу. Якщо uidnext менше, ніж messages, або з’являються помилки — ймовірно потрібен resync.

Рішення: Якщо лічильники UID виглядають неправильно, заплануйте doveadm force-resync після бекапу і заморозки записів.

Завдання 8: Примусово синхронізуйте скриньку (відбудова метаданих без видалення пошти)

cr0x@server:~$ sudo doveadm force-resync -u user@example.com INBOX
cr0x@server:~$ sudo doveadm mailbox status -u user@example.com messages unread uidvalidity uidnext INBOX
messages=842 unread=19 uidvalidity=18602 uidnext=902

Значення: Dovecot переобйшов сховище і відбудував ключові метадані. UIDNEXT змінився на одиницю — це може бути нормальним після звірки.

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

Завдання 9: Перебудуйте індекси Dovecot для користувача (агресивно, але поширено)

cr0x@server:~$ sudo doveadm index -u user@example.com -q INBOX
cr0x@server:~$ sudo doveadm index -u user@example.com -q '*'

Значення: Пересоздає дані індексів. Прапорець -q зменшує шум; перевіряйте логи на «corrupt» повідомлення під час індексації.

Рішення: Якщо індексування викидає «read() failed» або «Short read», трактуйте це як пошкодження сховища/повідомлення, а не лише метаданих.

Завдання 10: Видаліть лише файли індексу/кешу (останній засіб, але інколи необхідно)

cr0x@server:~$ sudo find /var/vmail/example.com/user/ -maxdepth 2 -type f -name "dovecot.index*" -o -name "dovecot-uidlist" -o -name "dovecot-uidvalidity" -o -name "dovecot.list.index*" -print
/var/vmail.example.com/user/dovecot-uidlist
/var/vmail.example.com/user/dovecot.index
/var/vmail.example.com/user/dovecot.index.cache
cr0x@server:~$ sudo mv /var/vmail.example.com/user/dovecot.index /var/vmail.example.com/user/dovecot.index.bak
cr0x@server:~$ sudo mv /var/vmail.example.com/user/dovecot.index.cache /var/vmail.example.com/user/dovecot.index.cache.bak
cr0x@server:~$ sudo mv /var/vmail.example.com/user/dovecot-uidlist /var/vmail.example.com/user/dovecot-uidlist.bak

Значення: Ви видалили метадані так, щоб Dovecot змусилися їх пересоздати з Maildir. Це може змінити UIDs і дратувати клієнтів, але часто це найчистіший скидання.

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

Завдання 11: Виявлення «кинутих» повідомлень Maildir у tmp/ (доставка перервана)

cr0x@server:~$ sudo find /var/vmail/example.com/user/Maildir/tmp -type f | head
/var/vmail/example.com/user/Maildir/tmp/1704271042.M12345P6789.mx1,S=2048,W=2090
cr0x@server:~$ sudo find /var/vmail/example.com/user/Maildir/tmp -type f | wc -l
17

Значення: Повідомлення, що застрягли в tmp/, можуть бути невидимі для клієнтів. Вони можуть бути частково записані або просто ніколи не перейменовані через заповнений диск чи крах.

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

Завдання 12: Огляньте підозрілий файл повідомлення без модифікації

cr0x@server:~$ sudo ls -lh /var/vmail/example.com/user/Maildir/tmp/1704271042.M12345P6789.mx1,S=2048,W=2090
-rw------- 1 vmail vmail 2.0K Jan  3 10:30 /var/vmail/example.com/user/Maildir/tmp/1704271042.M12345P6789.mx1,S=2048,W=2090
cr0x@server:~$ sudo head -n 20 /var/vmail/example.com/user/Maildir/tmp/1704271042.M12345P6789.mx1,S=2048,W=2090
Return-Path: <sender@example.net>
Delivered-To: user@example.com
Received: by mx1 with LMTP id 7xYk...; Fri, 03 Jan 2026 10:30:41 +0000
Date: Fri, 03 Jan 2026 10:30:40 +0000
From: Sender <sender@example.net>
To: user@example.com
Subject: test
Message-ID: <...>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8

Значення: Виглядає як дійсне RFC 5322 повідомлення. Добрий знак.

Рішення: Якщо воно валідне — можна перемістити його в new/ (з правильними правами) і виконати resync. Якщо заголовки відсутні/спотворені — тримайте в карантині.

Завдання 13: Безпечно перемістіть кинуті tmp-повідомлення в new/ (лише після перевірки)

cr0x@server:~$ sudo sh -c 'for f in /var/vmail/example.com/user/Maildir/tmp/*; do test -f "$f" && mv -n "$f" /var/vmail/example.com/user/Maildir/new/; done'
cr0x@server:~$ sudo doveadm force-resync -u user@example.com INBOX

Значення: Повідомлення тепер помітні. Прапорець -n запобігає перезапису у випадку колізії імен.

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

Завдання 14: Перерахунок квоти (після ремонту; квоти можуть брехати)

cr0x@server:~$ sudo doveadm quota get -u user@example.com
Quota name=User quota Type=STORAGE Value=2048M Limit=2048M %
cr0x@server:~$ sudo doveadm quota recalc -u user@example.com
cr0x@server:~$ sudo doveadm quota get -u user@example.com
Quota name=User quota Type=STORAGE Value=1460M Limit=2048M %

Значення: До перерахунку система могла рахувати повідомлення, яких фактично не було (або навпаки). Після recalc значення відповідають реальності.

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

Завдання 15: Діагностика плутанини FTS (пошук зламаний, пошта в порядку)

cr0x@server:~$ sudo doveadm fts rescan -u user@example.com INBOX
cr0x@server:~$ sudo doveadm fts optimize -u user@example.com

Значення: FTS відбудовується окремо. Це виправляє «пошук не знаходить лист, який я бачу».

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

Завдання 16: Використовуйте dsync як «примус до істини» (відмінно з репліками)

cr0x@server:~$ sudo doveadm dsync -u user@example.com backup -R -f /var/vmail/example.com/user/ "remote:replica-user@example.com"
dsync(user@example.com): info: Sync: mailbox INBOX: 842 messages, 0 expunges, 2 flag changes

Значення: Dsync звіряє відмінності між двома сховищами. У режимі backup він віддає перевагу локальній стороні як джерелу істини; змінюйте напрямок обережно.

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

Короткий жарт #2: Друга найнебезпечніша річ на поштовому сервері — це «швидке виправлення». Перша — це «швидке виправлення» запущене як root без знімка.

Контрольні списки / покроковий план (відновлення з мінімізацією шкоди)

Оберіть шлях, що відповідає вашій ситуації. Помилка — трактувати всю корупцію як відбудову індексу.

План A: Лише корупція індексу (найпоширеніше, найменш страшне)

  1. Підтвердьте обсяг. Одна скринька чи багато? Використовуйте логи і doveadm mailbox status.
  2. Заморозьте записи для цієї скриньки. Тимчасово блокуйте логін для користувача або перемістіть його на бекенд техобслуговування.
  3. Зробіть знімок/беккап каталогу скриньки. Включайте приховані файли та dovecot.* файли.
  4. Запустіть resync. doveadm force-resync -u user@example.com INBOX
  5. Перебудуйте індекси. doveadm index -u user@example.com -q '*'
  6. Перерахунок квоти. Якщо ви використовуєте quota: doveadm quota recalc
  7. Відбудуйте FTS якщо користувачі скаржаться на пошук.
  8. Розморожуйте записи і слідкуйте за логами. Якщо помилки повторюються відразу — зупиніться і перевірте сховище/семантику доставки.

План B: Некоординованість директорій Maildir (безлад у tmp/new/cur)

  1. Заморозьте записи. Доставка та IMAP-зміни повинні призупинитися для цієї скриньки.
  2. Зробіть бекап всього Maildir. Збережіть «месиво» в незмінному вигляді.
  3. Порахуйтe кинуті tmp файли. Якщо їх небагато — огляньте; якщо тисячі — у вас системна проблема з доставкою/fsync.
  4. Валідуйте вибірку tmp файлів. Перевірте заголовки та правдоподібність розмірів.
  5. Перемістіть валідні tmp файли в new/ з неперестворювальними переміщеннями.
  6. Видаліть/перебудуйте індекси. Відсуньте вбік dovecot.index* і dovecot-uidlist, потім resync.
  7. Повідомлення для користувачів. Порадьте перезапустити клієнти; деякі повторно завантажать заголовки. Якщо UIDVALIDITY змінюється — попередьте про дублювання у деяких клієнтів.

План C: Підозра на пошкодження підлеглого сховища (I/O errors, short reads, truncated records)

  1. Негайно зупиніть записи. Якщо можливо — перемонтуйте поштове сховище тільки для читання або переключіться на відмову на резерв.
  2. Отримайте копію байт-в-байт або знімок. Працюйте на копії.
  3. Спробуйте недеструктивні Dovecot відбудови на копії. Якщо вони падають з помилками читання — не продовжуйте бездумні спроби.
  4. Експортуйте читаємі повідомлення. Для Maildir скопіюйте цілі файли. Для mdbox використайте інструменти Dovecot для експорту, якщо можливо.
  5. Відновіть з репліки/бекапу відсутні частини. Dsync може допомогти звірити.
  6. Запустіть чисте сховище скриньки. Імпортуйте експортовані повідомлення в нову скриньку і переключіть клієнтів.
  7. Розберіться з причиною події зі зберіганням. Виправте корінь: диск, контролер, мережеві FS семантики або планування ємності.

План D: Існує репліка і здається здоровою (план «використати другу копію»)

  1. Підтвердіть сигнали здоров’я репліки. Переконайтеся, що репліка може обслуговувати скриньку без помилок.
  2. Зробіть знімок обох сторін. Так, навіть здорової. Помилки реплікації можуть бути симетричними катастрофами.
  3. Свідомо оберіть напрямок. Якщо primary пошкоджено — віддайте перевагу репліці як джерелу істини.
  4. Запустіть dsync у потрібному режимі. Зробіть невеликі тести на одній скриньці спочатку.
  5. Перевірте кількість повідомлень і вибірково нещодавні листи.
  6. Відновіть нормальний трафік і стежте.

Поширені помилки: симптом → корінна причина → виправлення

1) Симптом: «Відсутні листи», але лише пошук зламаний

Корінна причина: Корупція або відставання індексу FTS; скринька в порядку.

Виправлення: Запустіть doveadm fts rescan для уражених користувачів/скриньок після стабілізації індексів скриньок.

2) Симптом: UIDVALIDITY changed; клієнти дублюють або повторно завантажують все

Корінна причина: Видалено/пересоздано dovecot-uidvalidity або примусова відбудова, що скинула UIDVALIDITY; або скриньку було пересоздано під час міграції.

Виправлення: Уникайте видалення UIDVALIDITY без потреби. Якщо вже змінилось — повідомте користувачів; для впертих клієнтів може знадобитися видалити та додати акаунт.

3) Симптом: Відбудова індексів «працює», але корупція повертається щодня

Корінна причина: Семантика підлеглого сховища (мережевий FS, антивірус, інструмент бекапу змінює файли), або помилки диска, або періодичний дефіцит місця.

Виправлення: Дослідіть dmesg, параметри mount, та сторонні процеси, що торкаються файлів. Виправте середовище, потім відбудуйте один раз.

4) Симптом: Багато повідомлень застрягло в tmp/ і нові доставки іноді пропадають

Корінна причина: Диск повний / вичерпано іноди / крах під час доставки / некоректна робота LMTP/LDA.

Виправлення: Вирішіть питання ємності. Потім валідируйте і перемістіть tmp у new, після чого force-resync.

5) Симптом: «Internal error occurred. Refer to server log» при відкритті скриньки

Корінна причина: Невідповідність прав/власника після відновлення, або індекси створені з неправильним UID, або порушена спадковість ACL.

Виправлення: Перевірте власника файлів і очікування Dovecot щодо mail_uid/mail_gid; виправте права, потім перебудуйте індекси.

6) Симптом: mdbox показує раптові прогалини, «Invalid message size»

Корінна причина: Обрізаний mdbox файл через disk-full або помилку I/O під час запису.

Виправлення: Зробіть знімок, спробуйте Dovecot rebuild/export на копії, відновіть відсутні повідомлення з репліки/бекапу. Не видаляйте випадкові файли.

7) Симптом: Одна папка зламана, інші в порядку; помилка згадує dovecot.list.index

Корінна причина: Корупція індексу списку скриньок, іноді після некоректного завершення або змішування версій бінарників.

Виправлення: Відсуньте вбік dovecot.list.index* для користувача, потім дайте Dovecot згенерувати заново, перелікуючи скриньки і виконавши resync.

8) Симптом: Після ремонтів хаос з прапорами повідомлень (прочитано/непрочитано)

Корінна причина: Прапори Maildir в іменах файлів не погоджуються з кешем; або клієнти кешують стан і повторно застосовують зміни після підключення.

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

Три корпоративні міні-історії з польових боїв

Міні-історія 1: Інцидент через хибне припущення

Середня компанія запускала Dovecot з Maildir на мережевій файловій системі. Команда припустила, що «це просто файли» означає, що вона поводитиметься як локальний диск. Працювало місяцями, і саме так припущення перетворюються на «факти».

Потім відбувся вікно обслуговування: failover сховища, коротка затримка і кілька клієнтів, що не припинили синхронізацію. В понеділок вранці: користувачі повідомляли про відсутні повідомлення в Sent, але лише в певних підпапках. Логи показували інтермітуючу корупцію індексів і час від часу «short read».

Початкова реакція була передбачувана: перебудова індексів для уражених користувачів, по черзі. Це допомагало кілька годин, потім ті ж самі скриньки «знову пошкоджувалися». Хтось спробував радикальніше — видалити dovecot.* по всьому бекенду — бо в лабораторії це спрацювало одного разу. Це викликало зміни UIDVALIDITY для частини скриньок, і клієнти відповіли повторним завантаженням, дублями і перетворили службу підтримки на справжній перформанс.

Корінною причиною не був Dovecot. Мережевий FS не гарантував очікувану семантику rename+fsync під час failover. Maildir залежить від цих операцій для атомарного переходу «повідомлення з’явилось». Під навантаженням переходи tmp→new ставали дивними, а індекси Dovecot були лише посланцями.

Вони виправили це, перемістивши зберігання на локальний диск на поштових нодах і використовуючи реплікацію на рівні Dovecot. Перебудови індексів перестали бути щоденною звичкою. Урок: система, що «зазвичай поводиться як POSIX», не те саме, що POSIX, коли у CEO в телефоні 20 IMAP операцій в секунду.

Міні-історія 2: Оптимізація, що повернулась бумерангом

Інша організація хотіла швидших бекапів і менше inode. Maildir здався «неефективним», тому вони мігрували на mdbox. Це було розумне інженерне рішення з прихованою вартістю: оперативна пам’ять команди була ще Maildir-орієнтованою, а їхні рукописи залишились «просто перемістити файли».

Вони також налаштували систему на швидкість: агресивне кешування і активна FTS конфігурація. Все було швидко, поки під час пікового навантаження не сталося заповнення диска. Подія «диск повний» не драматична; вона нудна, а потім робить усе інше драматичним.

Після цього частина користувачів не могла відкрити INBOX. Логи містили «Invalid message size» у mdbox, і відбудова індексів не допомагала. Хтось спробував видалити те, що здавалося «лише індексами» у директорії mdbox. Це погіршило проблему, бо вони видалили файли відображення, які не були лише кешем.

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

Урок: оптимізації — це добре. Але кожна оптимізація має операційну ціну. Якщо ви не платите її поступово (моніторинг, рукописи, навчання), заплатите одразу під час інциденту.

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

Регульована компанія запускала Dovecot з реплікацією і суворою політикою «знімок перед змінами». Це не було гламурно. Воно також означало, що on-call мав повільнішу першу реакцію, бо кожен рукопис починався з «заморозити, зробити знімок, перевірити».

Одного дня партія скриньок почала кидати помилки корупції індексів після некоректного виведення живлення. Користувачі були голосні; менеджмент гучніший. SRE на зміні все одно пройшов нудний чекліст: ізолював скриньку, зробив знімок, спробував force-resync, перебудував індекси, потім перевірив невеликою групою doveadm статусів.

Для тих кількох скриньок, що й досі падали, вони не вдавались до хаосу. Вони негайно переключили цих користувачів на репліку, а потім використали dsync для звірки, коли primary стабілізувався. Ніяких ручних правок. Ніяких випадкових видалень. Ніяких «спробуй і подивися» циклів.

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

Часті питання

1) Чи можна видалити dovecot.index для виправлення корупції?

Інколи так — але лише після бекапу/знімка і після зупинки записів для цієї скриньки. Віддавайте перевагу doveadm force-resync і doveadm index спочатку. Видалення файлів індексу може викликати UID/прапорне зміщення і болісний ресинк для клієнтів.

2) Чи видалить doveadm force-resync повідомлення?

Воно призначене для звірки метаданих з підлеглим сховищем, а не для видалення пошти. Але якщо підлегле сховище відсутнє повідомлення, «результат» — ці повідомлення більше не відображаються. Це не команда їх видаляє; це проста фіксація реальності.

3) Користувачі кажуть, що пошта пропала, але я бачу файли в Maildir. Чому?

Dovecot може не бачити їх через корупцію індексу, проблеми з правами або тому, що вони застрягли в tmp/. Перевірте власність і розташування, потім resync.

4) Як обійтися зі змінами UIDVALIDITY з мінімальним хаосом для клієнтів?

Уникайте їхнього непотрібного тригера. Якщо вони вже сталися — комунікуйте чітко: клієнти можуть перезавантажити або дублювати листи. Заохочуйте перезапуск клієнтів; для впертих випадків видалення й повторне додавання акаунта — часто найчистіший клієнтський скидання.

5) Чи є Maildir «безпечнішим» за mdbox щодо корупції?

Maildir легший для огляду і рятування на рівні файлів. mdbox може бути ефективнішим і консистентнішим під великим навантаженням, але вимагає більшого поваги до Dovecot-управляємих метаданих. «Безпечніше» залежить від того, чи ваша команда розуміє формат і чи ваше сховище поводиться коректно.

6) Чи можуть антивіруси або агенти бекапу спричинити корупцію скриньок?

Так. Усе, що змінює, блокує, перейменовує або частково читає/пише файли повідомлень і метадані dovecot, може створити неконсистентності. Класична помилка — агент, що сканує in-place і змагається з доставкою або оновленнями індексів.

7) У чому різниця між проблемами індексів скриньки та FTS?

Індекси скриньки впливають на вміст папки, прапори і базові IMAP операції. FTS впливає на результати пошуку. Користувачі часто повідомляють про проблеми FTS як «втрачені листи», бо вони шукають замість перегляду.

8) Чи можна запускати ремонти під час того, як сервер працює?

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

9) Як зрозуміти, що корупцію спричинила файловa система?

Шукайте I/O помилки в dmesg, попередження файлової системи і невдачі rsync/read при копіюванні maildir. Якщо помилки корелюють з подіями зі сховищем (failover, disk-full, стрибки латентності) — підозрюйте сховище.

10) Чому після ремонту кількість непрочитаних неправильна?

Стан «непрочитано» — це комбінація прапорів повідомлень і стану індексу/кешу. Після відбудови лічильники можуть змінитися, щоб відповідати тому, що є на диску. Деякі клієнти також «повторно застосовують» кешований стан після підключення; дайте час на стабілізацію.

Висновок: наступні кроки, які ви можете зробити сьогодні

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

Практичні наступні кроки:

  1. Додайте в рукопис перевірку: «знімок перед змінами» для будь-якого ремонту скриньки.
  2. Інструментуйте оповіщення про місце на диску і inode спеціально для поштового сховища; disk-full — фабрика корупції.
  3. Вирішіть політику «джерела істини» заздалегідь (primary vs replica) і документуйте напрямки dsync.
  4. Аудитуйте сторонні агенти (антивірус, бекап, індексація), що торкаються сховища безпосередньо.
  5. Практикуйтесь на staging-копії: проганяйте doveadm force-resync, doveadm index, перерахунок квот і відбудову FTS, щоб on-call не вчився під час інциденту.

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

← Попередня
Cmd+K: модальне вікно пошуку — списки результатів, підказки клавіатури та порожні стани (HTML/CSS‑перший)
Наступна →
Покоління Intel Core: як розшифрувати назви без паніки

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