Comments 66
После одного такого фэйла — делал truncate на конкретную таблицу, но из головы вылетело, что на ней завязана почти вся база по внешним ключам, а on delete в большинстве мест был cascade (благо хоть бета-версия продукта была с ограниченным числом пользователей «из своих») — бэкап стал одним из главных шагов при разворачивании боевого окружения.
Народная мудрость:
Есть два типа администраторов — те, кто не делает бэкапы, и те, кто уже делает
На самом деле три типа:
1. не бекапятся
2. бекапятся
3. бекапятся и проверяют, что разбекапливается
1. не бекапятся
2. бекапятся
3. бекапятся и проверяют, что разбекапливается
4) кто делает архивы бэкапов.
И еще есть те, кто слышал, что надо бекапится, и по этому они бекапятся, но на тот же диск.
вообще-то, они не так уж и неправы
Резервные копии — это главным образом защита на случай случайной порчи данных по вине ПО или человека («человеческий фактор»). Там, базу убили и т. п.
А вот от сбоя диска («аппаратный фактор») по идее и защита должна быть другая — RAID.
Другое дело, что бекапы можно с грехом пополам использовать и для того, и для другого, но, в наиболее интересных случаях, базу разворачивать из бекапа долго, и поэтому как правило это неверное решение для защиты от сбоя аппаратуры. В моей практике был случай, когда dd диска с пропуском ошибок чтения и последующая проверка и починка ФС было эффективнее, чем разворачивание этих же данных из бекапов (бекапы, очевидно, были и были работоспособные).
Резервные копии — это главным образом защита на случай случайной порчи данных по вине ПО или человека («человеческий фактор»). Там, базу убили и т. п.
А вот от сбоя диска («аппаратный фактор») по идее и защита должна быть другая — RAID.
Другое дело, что бекапы можно с грехом пополам использовать и для того, и для другого, но, в наиболее интересных случаях, базу разворачивать из бекапа долго, и поэтому как правило это неверное решение для защиты от сбоя аппаратуры. В моей практике был случай, когда dd диска с пропуском ошибок чтения и последующая проверка и починка ФС было эффективнее, чем разворачивание этих же данных из бекапов (бекапы, очевидно, были и были работоспособные).
Третья группа на самом деле скорее 3.1. Просто 3 — это те кто ДУМАЮТ что бекап делаеться )
Третьим можно посочувствовать. Не каждому дано столько испытать.
Как показывает практика — каждому. Что прикольно, все руководства про делание бекапов твердят: «проверяйте их работоспособность», но никто не говорит, КАК это нужно делать :(
Те, кто делает и те, кто уже делает :)
Ух, представляю сколько адреналина будет выделено надпочечниками при прохождении этого пути джедая в первый раз.
а разве бд не принято удалять через drop database в интерпретаторе mysql? Пускай хоть и случайно… Если сравнивать удаление бд как и удаление файла — то тогда стоит применять те же процедуры по восстановлению, что и для обычных файлов(при помощи специальных утилит).
при «случайном» rm -rf /var/lib/mysql/* на мастере, все равно данные останутся на slave серверах. то есть физически все достаточно легко восстановимо. опять таки, slave (опуская его основную роль) — самый удобный способ бекапирования данных
а вот при случайном truncate или drop database, о которых говорилось выше, приходит упитанный песец…
а вот при случайном truncate или drop database, о которых говорилось выше, приходит упитанный песец…
Имхо, в данном случае самым эффективным для админа будет убить себя об стену во избежание повторных инцидентов и разборок с начальством )
Спасибо — сразу в закладки утащил.
Знакомая ситуация )
Знакомая ситуация )
А после DROP DATABASE есть какие-то варианты кроме искать работу, продавать почку? :)
Восстанавливаются файлы на диске. Через отмену транзакции диска в ext3.
Главное — быстро выключить сервер, желательно проводом из розетки.
Потом вытаскивается винт и всё восстанавливается. Потерь около 0.
Главное — быстро выключить сервер, желательно проводом из розетки.
Потом вытаскивается винт и всё восстанавливается. Потерь около 0.
Хм, интересно, а можно поподробнее?
carlo17.home.xs4all.nl/howto/undelete_ext3.html
С помощью вот этого в одной онлайн-игре при мне воскрешали состояние игры, когда в апдейт скрипт затесалась досадная опечатка после drop database;
С помощью вот этого в одной онлайн-игре при мне воскрешали состояние игры, когда в апдейт скрипт затесалась досадная опечатка после drop database;
Пробовал когда-то таким способом, не вышло. ext3grep и другие утилиты не восстановили ничего толкового. С онлайн играми там немного иначе, сервер у них держит часто всю базу в памяти и при его остановке сбрасывает кэш на диск, т.е. подставив рабочие таблички, возможно получить актуальные данные даже после полного дропа базы.
Что именно не вышло? DROP DATABASE имеет геморрой только если innodb, там придётся еще ручками транзакцию откатывать.
MyISAM (жалких 16 гигов) восстановились на ура :)
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 и т.д.
Для файлов ls -l /proc/2544/fd/ | grep /var/lib/mysql/ сделать cat каждого такого дескриптора в соответствующий для него файл. Чтобы было что-то типа cat /proc/2544/fd/13 > /var/lib/mysql/mysql/host.MYI и т.д.
Чтобы вытянуть данные напрямую из файлов, нужно знать структуру таблицы. А структуру таблицы без .frm файла — нужно или знать наизусть или иметь в бекапах.
При наличии бекапов — такой извращенный метод снимается с повестки дня. А без — ИМХО тогда уже лучше остановить и использовать тулзы типа debugfs для восстановления файлов на уровне ФС.
При наличии бекапов — такой извращенный метод снимается с повестки дня. А без — ИМХО тогда уже лучше остановить и использовать тулзы типа 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 генерировались, то повторить структуру будет не проблема. И есть еще шанс воспользоваться, например, бэкапом годовой давности — данные в нем будут уже не актуальные, но структура может быть с тех пор и не менялась.
Если так хочется вытаскивать из работающего mysqld, то лучше все-таки вместо симлинков из /proc в /var/lib/mysql вытащить туда содержимое, просто поменяв ln -s на cat > Это все-таки снижает риск потерять данные при восстановлении. Вы предложили очень хороший вариант, но его можно еще немного улучшить.
По поводу структур таблиц и .frm, кстати, все не так мрачно. Работающий mysqld держит для открытых таблиц их структуру и может ее показать через show create table dbname.tablename;
Плюс еще если таблицы через ORM или migration чего-нибудь типа Ruby on Rails генерировались, то повторить структуру будет не проблема. И есть еще шанс воспользоваться, например, бэкапом годовой давности — данные в нем будут уже не актуальные, но структура может быть с тех пор и не менялась.
Я не ратую за такой способ восстановления данных :) описал его чтобы другие знали что от него можно ожидать, а что нет. Вообще обязательно остановить application, чтобы внутри базы ничего не происходило.
Вот у меня во время эксперимента оно из кеша выпало похоже, так как ни show create ни describe не отработали (может наудалял лишнего)
Это должен быть какой-то очень стабильный проект :) Мне пока попадались проекты где с бекапом годовой давности можно сходить… почитать маны. И накатка дельты структуры не факт что пройдет гладко, но это уже к бекапам мало относится.
Работающий mysqld держит для открытых таблиц их структуру и может ее показать через show create table dbname.tablename;
Вот у меня во время эксперимента оно из кеша выпало похоже, так как ни show create ни describe не отработали (может наудалял лишнего)
бэкапом годовой давности
Это должен быть какой-то очень стабильный проект :) Мне пока попадались проекты где с бекапом годовой давности можно сходить… почитать маны. И накатка дельты структуры не факт что пройдет гладко, но это уже к бекапам мало относится.
> ни show create ни describe не отработали
Вероятно, существует разница, если указывать в show create table имя из БАЗА.ТАБЛИЦА, или сделать сначала USE БАЗА, а потом show create на TAБЛИЦА. Во втором случае mysqld видит у базы пустой листинг таблиц из-за отсутствия для таблиц файлов .frm, и выдает ошибку из-за того, что не может найти ее в листинге. А в первом случае он не пытаясь делать листинг для базы, а пытается взять данные из кэша таблиц, найдя по полному имени таблицы (БАЗА.ТАБЛИЦА)
Вероятно, существует разница, если указывать в show create table имя из БАЗА.ТАБЛИЦА, или сделать сначала USE БАЗА, а потом show create на TAБЛИЦА. Во втором случае mysqld видит у базы пустой листинг таблиц из-за отсутствия для таблиц файлов .frm, и выдает ошибку из-за того, что не может найти ее в листинге. А в первом случае он не пытаясь делать листинг для базы, а пытается взять данные из кэша таблиц, найдя по полному имени таблицы (БАЗА.ТАБЛИЦА)
Вот вы удалили базу данных и сразу на хабр, а тут эта статья!
Сделал один раз DELETE без условия, грохнулась одна важная таблица. В соседнем кобинете у чувака была открыта веб страница с деревом постороенным на основе грохнутых данных. Решением стало написать html парсер для это последней сохранившейся копии. Это был мой единственный раз, с тех пор очень внимателен =)
Пару лет назад в запарке удалил не тестовую базу, а продакшен (они тогда были на одном сервере). Бэкап был не старше суток, но что делать с данными что поступили за прошедшее время? Там заказы были, мы их отправляли письмами, а копию этих писем слали себе на один ящик. Вот ночью и писал парсер этих писем, по ним и восстанавливал данные. Утром проект работал как обычно :-)
Если я случайно удаляю базу данных то беру бэкап и… СТОП! У вас что, нет бэкапа? О_о
А если бекап устарел? Он же не каждую сенкудочку делается, а тут БАЦ и фирма микропрограммы заказала у вас партию на миллиард Ваших программ =) Эх, столько денег потеряете
Почему не каждую? raid-1 же.
А если база большая, это ж сколько места надо! Просто обычно бэкап идет, например, раз в сутки, или в пол.
ну, и что? на моём RAID1 данные пишутся на оба диска одновременно. Так не бывает, чтобы на один записалось, а спустя разумное время со второго можно было считать старую версию
почему-то я думал что восстанавливают удаление данных по delete
1. Используйте репликацию
2. Настраивайте binlog-и на обоих — мастер и слейве
3. Делайте бекапы
3.1 базы с мастера (по возможности)
3.2 базы с реплики
3.3 раздела (lvm snapshot) с реплики (по желанию)
3.4 binlog'ов (по желанию)
3.5 останов реплики и полная копия файлов /var/lib/mysql (по желанию)
4. Старайтесь переодически проверять бекапы
Итого у нас будет больше вариантов при факапе.
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 на что-то нормальное, что не позволяет таких фокусов?
а по существу: «дропнули базу в продакшене? меняем работу и больше НИКОГДА не тестимся на продакшн базах».
если бэкапы БД делаются нормально (ежечасно или чаще), даже почка останется при себе :)
еще более по существу: перед обновлением чего-либо учимся делать бэкап и проверять, что из него можно подняться. бэкап может быть как в виде бэкапа, так и в виде отключенного «запасного сервера» (зеркало и тп).
и вы таки хотите сказать, что _сервер_ позволит удалить его открытые файлы?
может быть тогда стоит задуматься о смене mysql на что-то нормальное, что не позволяет таких фокусов?
а по существу: «дропнули базу в продакшене? меняем работу и больше НИКОГДА не тестимся на продакшн базах».
если бэкапы БД делаются нормально (ежечасно или чаще), даже почка останется при себе :)
еще более по существу: перед обновлением чего-либо учимся делать бэкап и проверять, что из него можно подняться. бэкап может быть как в виде бэкапа, так и в виде отключенного «запасного сервера» (зеркало и тп).
и вы таки хотите сказать, что _сервер_ позволит удалить его открытые файлы?
Сразу видно, что вы никогда не работали на *nix. Сначала изучите ОС, а потом пишите такие комментарии.
«Сразу видно, что вы никогда не работали на *nix»
я всегда считал, что правильная ОС контролирует необходимые ей ресурсы.
«Сначала изучите ОС»
буду рад получить от вас ссылку, описывающую поведение ОС в данной ситуации. почитаю с удовольствием.
я всегда считал, что правильная ОС контролирует необходимые ей ресурсы.
«Сначала изучите ОС»
буду рад получить от вас ссылку, описывающую поведение ОС в данной ситуации. почитаю с удовольствием.
ОС, в том числе и *nix, безусловно, контролирует ресурсы. Но есть такая вещь как модель поведения. Так вот, в Windows и *nix модель поведения в ситуации «удалить открытый файл» отличается. Корнями всё уходит в устройство файловой системы: в Windows изначально поддерживалась только FAT, а там у каждый файл мог «находиться» только в одном каталоге. В этом случае системный вызов удаления файла мог означать только одно — удалить данные насовсем. Поэтому Windows запрещает удалять открытые файлы. В *nix изначально поддерживались множественные ссылки на файл из разных каталогов и поэтому системного вызова «удалить файл» как такового нет, есть «удалить ссылку на файл», а данные удаляются после удаления последней ссылки и закрытия файла. Поэтому удавление открытого файла разрешено: ссылка на файл будет удалена из каталога, но программа, владеющая дескриптором, может продолжать с ним работать.
— Морис Дж. Бах. Архитектура операционной системы Unix, 1986
Процесс может удалить связь файла в то время, как другому процессу нужно, чтобы файл оставался открытым. (Даже процесс, удаляющий связь, может быть процессом, выполнившим это открытие).
— Морис Дж. Бах. Архитектура операционной системы Unix, 1986
Пойду сделаю бэкап…
«воопщет можно каантрол зэт всегда ножать!!»*секретарша*
Sign up to leave a comment.
Случайно удалили продакшн базу? Что дальше?