Pull to refresh

Comments 66

После одного такого фэйла — делал truncate на конкретную таблицу, но из головы вылетело, что на ней завязана почти вся база по внешним ключам, а on delete в большинстве мест был cascade (благо хоть бета-версия продукта была с ограниченным числом пользователей «из своих») — бэкап стал одним из главных шагов при разворачивании боевого окружения.
Народная мудрость:
Есть два типа администраторов — те, кто не делает бэкапы, и те, кто уже делает
На самом деле три типа:
1. не бекапятся
2. бекапятся
3. бекапятся и проверяют, что разбекапливается
4) кто делает архивы бэкапов.
5) кто делает архивы бекапов с хранением в другой серверной
ну да, я как то об этом не подумал. Именно так и делаем. Скажу больше У нас еть архивы архивов (те дубликат) в разных местах :)
6) кто хранит архивы дампов в git :)
7) кто шифрует бэкапы (пару раз видел как много бэкапов приводили к утечке)
И еще есть те, кто слышал, что надо бекапится, и по этому они бекапятся, но на тот же диск.
вообще-то, они не так уж и неправы

Резервные копии — это главным образом защита на случай случайной порчи данных по вине ПО или человека («человеческий фактор»). Там, базу убили и т. п.
А вот от сбоя диска («аппаратный фактор») по идее и защита должна быть другая — RAID.

Другое дело, что бекапы можно с грехом пополам использовать и для того, и для другого, но, в наиболее интересных случаях, базу разворачивать из бекапа долго, и поэтому как правило это неверное решение для защиты от сбоя аппаратуры. В моей практике был случай, когда dd диска с пропуском ошибок чтения и последующая проверка и починка ФС было эффективнее, чем разворачивание этих же данных из бекапов (бекапы, очевидно, были и были работоспособные).
Третья группа на самом деле скорее 3.1. Просто 3 — это те кто ДУМАЮТ что бекап делаеться )
Третьим можно посочувствовать. Не каждому дано столько испытать.
Как показывает практика — каждому. Что прикольно, все руководства про делание бекапов твердят: «проверяйте их работоспособность», но никто не говорит, КАК это нужно делать :(
Что мешает взять чистую среду и развернуть там бекап? Заодно все ньюансы сразу узнаете и гарантированное время восстановления (если получится восстановится).
А вообще хорошо бы иметь автоматическую проверку с уведомлением если восстановление не удалось. У меня так бекап каждый час проверяется.
Те, кто делает и те, кто уже делает :)
Ух, представляю сколько адреналина будет выделено надпочечниками при прохождении этого пути джедая в первый раз.
Чтобы контролировать процесс выделения адреналина и седения волос и существует disaster recovery plan — который нужно составить, проверить и периодически тестировать и обновлять.
Вы абсолютно правы. А вот про седение волос я как то не подумал.
а разве бд не принято удалять через drop database в интерпретаторе mysql? Пускай хоть и случайно… Если сравнивать удаление бд как и удаление файла — то тогда стоит применять те же процедуры по восстановлению, что и для обычных файлов(при помощи специальных утилит).
«Перевод» писался как разбор возможности восстановления приведенной в статье.
Дабы кто-нибудь не ринулся «ничтоже сумняшеся» восстанавливать базу или считать что у него есть более-менее гарантированный способ восстановить «если что».
при «случайном» rm -rf /var/lib/mysql/* на мастере, все равно данные останутся на slave серверах. то есть физически все достаточно легко восстановимо. опять таки, slave (опуская его основную роль) — самый удобный способ бекапирования данных

а вот при случайном truncate или drop database, о которых говорилось выше, приходит упитанный песец…
Пушной зверек приходит в любом случае при отсутствии бекапов. При наличии оных варьируется лишь размер зверька :) и время восстановления.
это естесственно. тут вопрос не только во времени восстановления, но и в количестве утерянного.
Имхо, в данном случае самым эффективным для админа будет убить себя об стену во избежание повторных инцидентов и разборок с начальством )
это звучит как полноценный ответ на вопрос «Случайно удалили продакшн базу? Что дальше?»
дальнейшие варианты ответа:
— искать новую работу
— искать новую работу в другом городе
— искать хорошую больницу
— искать новую почку
— и т.п.
Заголовок такой должен быть:

Случайно удалили продакшн базу и нету резевной копии, что дальше?
я думаю: Заголовок такой должен быть:

Нет резервного копирования, что дальше?
Засыпать в картридж тонер в лучшем случаи.
Админское сэпукку.
Спасибо — сразу в закладки утащил.

Знакомая ситуация )
А после DROP DATABASE есть какие-то варианты кроме искать работу, продавать почку? :)
Восстанавливаются файлы на диске. Через отмену транзакции диска в ext3.
Главное — быстро выключить сервер, желательно проводом из розетки.
Потом вытаскивается винт и всё восстанавливается. Потерь около 0.
Хм, интересно, а можно поподробнее?
carlo17.home.xs4all.nl/howto/undelete_ext3.html
С помощью вот этого в одной онлайн-игре при мне воскрешали состояние игры, когда в апдейт скрипт затесалась досадная опечатка после drop database;
Пробовал когда-то таким способом, не вышло. ext3grep и другие утилиты не восстановили ничего толкового. С онлайн играми там немного иначе, сервер у них держит часто всю базу в памяти и при его остановке сбрасывает кэш на диск, т.е. подставив рабочие таблички, возможно получить актуальные данные даже после полного дропа базы.
Что именно не вышло? DROP DATABASE имеет геморрой только если innodb, там придётся еще ручками транзакцию откатывать.
MyISAM (жалких 16 гигов) восстановились на ура :)
В далеком детстве мой админ решил приколоться с меня. Он не думал, что я могу знать много всего сложного, и не знать патч Бармина. Ну а я ему верил суке :)
В общем восстановилось не всё. Вернее мои демоны, и данные восстановились, а все остальное… а остальное он потом заново всё настраивал.
undelete хорошая штуковина. однажды спасло, когда удалил свой хомяк с личными данными
Более надежный и простой вариант этого будет не вытаскивать данные из mysql в виде дампа, а вытаскивать данные напрямую из файловых дескрипторов процесса. Сам mysqld лучше по STOP остановить, чтобы ничего лишнего не натворил.

Для файлов ls -l /proc/2544/fd/ | grep /var/lib/mysql/ сделать cat каждого такого дескриптора в соответствующий для него файл. Чтобы было что-то типа cat /proc/2544/fd/13 > /var/lib/mysql/mysql/host.MYI и т.д.
Чтобы вытянуть данные напрямую из файлов, нужно знать структуру таблицы. А структуру таблицы без .frm файла — нужно или знать наизусть или иметь в бекапах.
При наличии бекапов — такой извращенный метод снимается с повестки дня. А без — ИМХО тогда уже лучше остановить и использовать тулзы типа debugfs для восстановления файлов на уровне ФС.
Есть одна очень важная причина, почему лучше поставить mysqld на STOP, а не пытаться сначала делать симлинки, а потом через mysqld что-то вытаскивать: при работающем mysqld какая-нибудь из операций может открыть какую-нибудь новую таблицу, хоть даже временную и из-за этого закрыть старую в кэше. Тогда для какой-нибудь из еще не сохраненных таблиц может закрыться файловый дескриптор в кэше таблиц, после чего она пропадет и в /proc...fd/. Кроме этого, mysqld может во время работы на этом fd открыть какой-нибудь другой файл, а у вас симлинк из /var/lib/mysq/… указывает жестко на этот fd, в результате чего под видом одной таблицы mysqld может потом увидеть совершенно другу.

Если так хочется вытаскивать из работающего mysqld, то лучше все-таки вместо симлинков из /proc в /var/lib/mysql вытащить туда содержимое, просто поменяв ln -s на cat > Это все-таки снижает риск потерять данные при восстановлении. Вы предложили очень хороший вариант, но его можно еще немного улучшить.

По поводу структур таблиц и .frm, кстати, все не так мрачно. Работающий mysqld держит для открытых таблиц их структуру и может ее показать через show create table dbname.tablename;
Плюс еще если таблицы через ORM или migration чего-нибудь типа Ruby on Rails генерировались, то повторить структуру будет не проблема. И есть еще шанс воспользоваться, например, бэкапом годовой давности — данные в нем будут уже не актуальные, но структура может быть с тех пор и не менялась.
Я не ратую за такой способ восстановления данных :) описал его чтобы другие знали что от него можно ожидать, а что нет. Вообще обязательно остановить application, чтобы внутри базы ничего не происходило.

Работающий mysqld держит для открытых таблиц их структуру и может ее показать через show create table dbname.tablename;

Вот у меня во время эксперимента оно из кеша выпало похоже, так как ни show create ни describe не отработали (может наудалял лишнего)

бэкапом годовой давности

Это должен быть какой-то очень стабильный проект :) Мне пока попадались проекты где с бекапом годовой давности можно сходить… почитать маны. И накатка дельты структуры не факт что пройдет гладко, но это уже к бекапам мало относится.
> ни show create ни describe не отработали

Вероятно, существует разница, если указывать в show create table имя из БАЗА.ТАБЛИЦА, или сделать сначала USE БАЗА, а потом show create на TAБЛИЦА. Во втором случае mysqld видит у базы пустой листинг таблиц из-за отсутствия для таблиц файлов .frm, и выдает ошибку из-за того, что не может найти ее в листинге. А в первом случае он не пытаясь делать листинг для базы, а пытается взять данные из кэша таблиц, найдя по полному имени таблицы (БАЗА.ТАБЛИЦА)
Вот вы удалили базу данных и сразу на хабр, а тут эта статья!
Да, вот так похоже и происходит — удаляют люди базу, им коллеги сразу шлют инвайт на хабр, чтобы тут читали и писали, а продакшн не трогали бы никогда.
Сделал один раз DELETE без условия, грохнулась одна важная таблица. В соседнем кобинете у чувака была открыта веб страница с деревом постороенным на основе грохнутых данных. Решением стало написать html парсер для это последней сохранившейся копии. Это был мой единственный раз, с тех пор очень внимателен =)
Пару лет назад в запарке удалил не тестовую базу, а продакшен (они тогда были на одном сервере). Бэкап был не старше суток, но что делать с данными что поступили за прошедшее время? Там заказы были, мы их отправляли письмами, а копию этих писем слали себе на один ящик. Вот ночью и писал парсер этих писем, по ним и восстанавливал данные. Утром проект работал как обычно :-)
Если я случайно удаляю базу данных то беру бэкап и… СТОП! У вас что, нет бэкапа? О_о
А если бекап устарел? Он же не каждую сенкудочку делается, а тут БАЦ и фирма микропрограммы заказала у вас партию на миллиард Ваших программ =) Эх, столько денег потеряете
А если база большая, это ж сколько места надо! Просто обычно бэкап идет, например, раз в сутки, или в пол.
для mysql можно хранить diffы прошлого и этого дапма, сделанного со слейва. Правда, замороченнее.

А в firebird есть замечательная утилита nbackup, которая сама умеет делать разностные резервные копии. Мечта.

ну, и что? на моём RAID1 данные пишутся на оба диска одновременно. Так не бывает, чтобы на один записалось, а спустя разумное время со второго можно было считать старую версию
почему-то я думал что восстанавливают удаление данных по delete
1. Используйте репликацию
2. Настраивайте binlog-и на обоих — мастер и слейве
3. Делайте бекапы
3.1 базы с мастера (по возможности)
3.2 базы с реплики
3.3 раздела (lvm snapshot) с реплики (по желанию)
3.4 binlog'ов (по желанию)
3.5 останов реплики и полная копия файлов /var/lib/mysql (по желанию)
4. Старайтесь переодически проверять бекапы

Итого у нас будет больше вариантов при факапе.
Повторяетесь, имхо, 3.5 делается в пукте 3.3 с помощью read lock'a и ничего останавливать не нужно.
Бинлоги тоже имхо обязательно. Уже попадал в ситуацию (правда на Оракле) когда логи спасли — поломался один инкрементальный бекап, поэтому базу накатывали логами с предыдущего состояния — так что они лишними уж точно не будут.
Спасибо конечно за статью, но парсить вывод ls -l для получения цели ссылки… есть же readlink.
Вообще readlink может взять только один операнд — линку. А чтобы ему передать список все равно его нужно где-то брать, т.е. делать ls или цикл по *. А это не так удобно помещается в one-liner, особенно когда нужно сделать бэклинк.
Я понимаю что так короче, но парсить вывод, предназначенный для пользователя — дурной тон.
«rm -rf /var/lib/mysql/*»

и вы таки хотите сказать, что _сервер_ позволит удалить его открытые файлы?
может быть тогда стоит задуматься о смене mysql на что-то нормальное, что не позволяет таких фокусов?

а по существу: «дропнули базу в продакшене? меняем работу и больше НИКОГДА не тестимся на продакшн базах».
если бэкапы БД делаются нормально (ежечасно или чаще), даже почка останется при себе :)

еще более по существу: перед обновлением чего-либо учимся делать бэкап и проверять, что из него можно подняться. бэкап может быть как в виде бэкапа, так и в виде отключенного «запасного сервера» (зеркало и тп).
и вы таки хотите сказать, что _сервер_ позволит удалить его открытые файлы?

Сразу видно, что вы никогда не работали на *nix. Сначала изучите ОС, а потом пишите такие комментарии.

«Сразу видно, что вы никогда не работали на *nix»

я всегда считал, что правильная ОС контролирует необходимые ей ресурсы.

«Сначала изучите ОС»

буду рад получить от вас ссылку, описывающую поведение ОС в данной ситуации. почитаю с удовольствием.
ОС, в том числе и *nix, безусловно, контролирует ресурсы. Но есть такая вещь как модель поведения. Так вот, в Windows и *nix модель поведения в ситуации «удалить открытый файл» отличается. Корнями всё уходит в устройство файловой системы: в Windows изначально поддерживалась только FAT, а там у каждый файл мог «находиться» только в одном каталоге. В этом случае системный вызов удаления файла мог означать только одно — удалить данные насовсем. Поэтому Windows запрещает удалять открытые файлы. В *nix изначально поддерживались множественные ссылки на файл из разных каталогов и поэтому системного вызова «удалить файл» как такового нет, есть «удалить ссылку на файл», а данные удаляются после удаления последней ссылки и закрытия файла. Поэтому удавление открытого файла разрешено: ссылка на файл будет удалена из каталога, но программа, владеющая дескриптором, может продолжать с ним работать.

Процесс может удалить связь файла в то время, как другому процессу нужно, чтобы файл оставался открытым. (Даже процесс, удаляющий связь, может быть процессом, выполнившим это открытие).

— Морис Дж. Бах. Архитектура операционной системы Unix, 1986
UFO just landed and posted this here
«воопщет можно каантрол зэт всегда ножать!!»*секретарша*
Sign up to leave a comment.

Articles

Change theme settings