Восстановление удаленных записей в mySQL из binlog
Monday, January 12th, 2009 | Linux, SQL, Shell | No Comments »Вчера я случайно удалил почти все записи из таблицы статистики просмотра видеозаписей Движущихся Картинок. Событие более чем печальное. До этого я предполагал, что восстановить удаленные записи практически невозможно. Оказалось, что можно. Если включены бинарные логи (для их включения в настройках mySQL надо указать параметр log-bin).
В результате некоторых раздумий получилась команда:
/usr/bin/mysqlbinlog --database=нужная_база_данных –start-datetime=”2008-01-01 00:00:00″ путь_ко_всем_binlog | tr “\t” ” ” | tr “\n” ” ” | tr “;”"\n” | grep “INSERT INTO \`побитая_таблица\`” > p.sql
Параметр start-datetime содержит в себе дату, с которой вынимаем логи. Можно еще указать время остановки (в моем случае это было неактуально).
Далее нужно указать не просто путь к логам, а все файлы логов (например, /var/lib/mysql/lalala-bin.*).
Несколько tr‘ов нужны потому, что запрос мой был многострочным, а надо было мне получать один запрос в одну строку.
В конечном счете в файле p.sql я получил нужные мне запросы. Единственное, что в конце строк не было точки с запятой. Это было исправное просто:
cat p.sql | sed "s/\"\)/\"\);/g" > p2.sq
Просто у меня каждый запрос оканчивался на ….”)
Когда я попытался скормить запросы mySQL’у оказалось, что из-за того, что были удалены не все записи, начались проблемы с уникальностью некоторых полей. Чтобы не копаться в дампе руками, сделал так:
cat p2.sql | sed "s/INSERT INTO/INSERT IGNORE INTO/g" > p3.sql
И уже p3.sql успешно скормил mySQL’у.
Отсюда выводы: во первых, всегда делайте бекапы (как можно чаще), и во вторых всегда включайте логирование.
P.S. Конечно же из binlog’ов можно вытащить все, что делалось с базой. И Восстановить то состояние, которое нужно.

