Доброго времени суток хабрачитатели. Совсем не давно на работе произошел инцидент который подпортил нервы и привел к длительным рассуждениям. Суть: при обновлении записи в БД mysql забыл прописать условие where и в результате изменились все записи в таблице.
Как этого можно было избежать:
- Всегда внимательно перечитывать запрос на рабочем сервере перед запуском (может спасти… но… может и не спасти)
- В конце обновляющих запросов всегда ставить limit 1, если не требуется обратное (Спасет, но дело привычки, к тому же все равно потом искать правленную строку).
- Использовать специальную утилиту типа phpmyadmin (пожалуй самое рационально, но не всегда доступное)
- Всегда делать дамп. (А это по идее обязательно даже при соблюдении остальных пунктов).
Вот если остался дамп, то мы спасены, и можем восстановить таблицу. Вот тут и начинается основная часть моей статьи- заметки.
Итак что у нас есть:
- Работающая база с неправильными данными
- Дамп правильной базы, без данных за определенный период (прошедший с момента создания дампа)
- Время в течении которого с базой продолжают работать, тем самым плодя ошибки и добавляя данные, которых нет в дампе.
Все омрачается еще и тем что база содержит внешние ключи, т.е. и ее id используются в других базах и она использует.
И вот наблюдая эту ситуацию я начинаю тихо впадать в истерику, ибо времени нет, а решение займет уйму времени, чтоб все корректно проделать и в итоге я могу потерять часть новых данных (это была таблица с заказами)
Но в итоге я собрался, подумал некоторое время и нашел решение, которое может помочь в подобных ситуациях.
Суть: Вместо перезаливки таблицы мы обновим ее значения используя старые данные из дампа.
Конкретно:
- Делаем копию дампа
- Редактируем копию дампа, удаляем данные о всех таблицах кроме нужной
- Заменяем все вхождения имени старой таблицы на новое (например temp_имя_старой таблицы)
- Загружаем исправленную копию дампа
- Выполняем запрос:
update имя_старой_таблицы t1 join имя_новой таблицы t2 on (t1.id=t2.id) set t1.имя_поля_некорректными данными=t2.имя_этого_самого поля во второй таблице; - Удаляем новую таблицу с измененным именем.
Итог:
Ключи не нарушены, старые данные восстановлены, новые данные если и повреждены, то имеют хотя бы часть информации, работа не была прервана, все выполнено довольно быстро.
Надеюсь эта история поможет кому-нибудь в подобной ситуации
Автор: zednight