Бомба уповільненої дії: як зростання бази даних непомітно заповнило диск і зруйнувало резервні копії

💡 Усі статті, обговорення, новини про DevOps — в одному місці. Приєднуйтесь до DevOps спільноти!

Бомба уповільненої дії: як зростання бази даних непомітно заповнило диск і зруйнувало резервні копії

Додаток легкий, сама база даних важить лише пару гігабайт, але диск у робочому середовищі раптово заповнений на 78%. Куди подівся цей простір?

Я пішов розслідувати. Виявилося, що локальні дампи бази даних з’їли майже весь простір. Але їх там не повинно бути: контейнер резервних копій створює дамп кожні три години, завантажує його на S3 і видаляє локальну копію. А точніше, він повинен її видалити. Насправді, вони накопичувалися протягом останніх 10 днів.

Таді почалася найцікавіша таємниця. Логіка скрипта виглядала приблизно так:
«pg_dump | gzip > db_$(date).sql.gz && aws s3 cp db_$(date).sql.gz s3://bucket/ && rm db_$(date).sql.gz»

Зворотне кодування: коли дві помилки створюють комбінацію
Цей один рядок ідеально поєднав дві незалежні помилки:
— $(date) було обчислено двічі — один раз для створення файлу та один раз для аргументу завантаження AWS. Хоча база даних була крихітною, обидві позначки часу збігалися. Але зі зростанням бази даних дамп займав більше хвилини — і вуаля! Другий $(date) повернув ще хвилину. AWS s3 cp спробував завантажити файл, який фізично не існував, і зазнав помилки.
— Локальну копію було видалено за допомогою && в самому кінці. Це спрацювало лише за умови успішного завантаження. Завантаження не вдається, і локальний файл залишається на диску. Назавжди.
— І нарешті... завантаження непомітно завершилося невдало, і протягом останніх 10 днів у S3 не було жодної дійсної резервної копії. І ніхто цього не помітив, бо сам контейнер працював без критичних помилок («скрипт запущено, розгортання пройшло успішно»).

Виправлення зайняло лише кілька рядків, але воно принципово покращило надійність:
— Виправлено одну позначку часу у змінній на початку виконання скрипта.
— Додано set -o pipefail (тому ланцюжок завершується невдачею, якщо сам pg_dump завершується невдачею, а не завантажує порожній архів як «успішний»).
— Переписано логіку видалення: локальна копія стирається лише після суворого підтвердження успішного завантаження.

Завантажено свіжі дампи в S3, проріджено локальне сміття. Результат: відновлено ~155 ГБ, завантаження диска знизилося з 78% до поважних 26%.

Найпідступніше в таких помилках — це ланцюжок причин, який важко передбачити заздалегідь:
— Зростання бази даних, невідповідні імена файлів через різницю в часі в секунди, збій AWS та невидалені локальні копії.
— Сам скрипт міг би лежати в репозиторії дуже довго, але він спрацював саме тоді, коли дамп перевищив позначку в 60 секунд. Справжня бомба уповільненої дії з таймером, прив’язаним до обсягу даних.

Ви перевіряли свої резервні копії останнім часом? Чи справді вони потрапляють до репозиторію, чи ви просто довіряєте зеленій позначці в CI/CD?

👍ПодобаєтьсяСподобалось3
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Можливо буде цікаво. Півроку тому почав розроблювати централізовану систему управління бекапи. Вона все ще в беті, але вже обросла доволі таки не поганим функціоналом і продовжується розвиватися. Посилляння тут: backspace.guru

Зручності в тому, що маєте єдину панель управління резервними копіями, ніяких скриптів писати не треба. Все відбувається через докер і зручний UI для налаштування бекапу + при тому не засмічує систему і бекапи зберігаються у вас. Автоматична ротація, є шифрування і стиснення. Підтримка різних баз даних і їх офіційних інструментів.

Буду радий, якщо приєднаєтесь і лишите свій фідбек. Мінус — UI тільки в cloud

wal-g.readthedocs.io
wal-g.readthedocs.io/PostgreSQL

І інкрементальні бекапи будуть, а не «в нас останній бекап 12 годин назад робили», і на диску не буде сміття

Можна одразу на s3 стрімити дані,без локальної копії
serverfault.com/a/903739

О дякую подивлюсь.

Перевірка резервної копії — кількість файлів та їх ім’я в сховищі, за загальним розміром файлів, хеш, чи розгортання бази за резервною копією зі сховища?

Виявилося, що локальні дампи бази даних з’їли майже весь простір.

ось тому зазвичай і використовують окремі диски, файлову систему, ...

«pg_dump | gzip > db_$(date).sql.gz && aws s3 cp db_$(date).sql.gz s3://bucket/ && rm db_$(date).sql.gz»
Переписано логіку видалення: локальна копія стирається лише після суворого підтвердження успішного завантаження.

що люди тільки не роблять, аби не користуватись s3 mv

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

Бекап не має бути на ньому. Воно одразу після дампу іде на s3

Підписатись на коментарі