Я случайно сбросил базу данных MySQL на моем сервере. Есть ли способы восстановить удаленную базу данных?
Я случайно сбросил базу данных MySQL на моем сервере. Есть ли способы восстановить удаленную базу данных?
Ответы:
Если вы будете действовать быстро, есть большая вероятность вернуть вашу базу данных. Вероятность выше для InnoDB, для MyISAM она ненулевая, но близкая.
Дело в том, что когда MySQL выполняет DROP TABLE или DROP DATABASE (что по сути то же самое), InnoDB не стирает данные. Страницы с данными все еще на диске.
В зависимости от настройки innodb_file_per_table процесс восстановления отличается. Если innodb_file_per_table выключен (по умолчанию до 5.5), то удаленная таблица остается в ibdata1. Если innodb_file_per_table включен (по умолчанию на 5.5), то удаленная таблица была в соответствующем файле .ibd. MySQL удаляет этот файл при удалении таблицы.
Самое первое, что нужно сделать, это остановить любые возможные записи, чтобы ваша таблица не была перезаписана. Если innodb_file_per_table выключен, этого достаточно, чтобы остановить MySQL (kill -9 еще лучше, но сначала убедитесь, что вы убили safe_mysqld). Если innodb_file_per_table включен, то размонтировать раздел, где MySQL хранит свои данные. Если datadir находится в корневом разделе, я рекомендую завершить работу сервера или, по крайней мере, сделать образ диска. Позвольте мне повторить, цель состоит в том, чтобы предотвратить перезаписывание удаленной таблицы MySQL или операционной системой.
Существует инструмент, позволяющий работать со страницами InnoDB на низком уровне, инструментарий восстановления данных TwinDB . Я буду использовать это, чтобы проиллюстрировать восстановление.
Вам нужно взять носитель с удаленной таблицей (либо ibdata1, либо образ диска) и найти на нем страницы InnoDB. Инструмент stream_parser из инструментария делает это.
./stream_parser -f /path/to/disk/image
Он будет сканировать файл, находить страницы InnoDB и сортировать их по типу и index_id. index_id - это идентификатор, который InnoDB использует для ссылки на индекс. Таблица хранится в индексе PRIMARY. Чтобы узнать, какой index_id является вашей удаленной таблицей, вам нужно восстановить словарь InnoDB .
Словарь InnoDB хранится в файле ibdat1. Вам нужно сканировать файл ibdata1 так же, как указано выше:
./stream_parser -f /var/lib/mysql/ibdata1
Теперь вам нужно получить записи из таблиц словаря InnoDB SYS_TABLES и SYS_INDEXES (скажем, ваша таблица sakila.actor):
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor
000000000B28 2A000001430D4D SYS_TABLES "sakila/actor" 158 4 1 0 0 "" 0
158 это table_id, запомни это.
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158
000000000B28 2A000001430BCA SYS_INDEXES 158 376 "PRIMARY" 1 3 0 4294967295
000000000B28 2A000001430C3C SYS_INDEXES 158 377 "idx\_actor\_last\_name" 1 0 0 4294967295
Итак, index_id вашей удаленной таблицы (sakila.actor) - 376.
Теперь вы можете извлекать записи удаленной таблицы из InnoDB index_id 376. У вас должна быть структура таблицы удаленной таблицы, а именно инструкция CREATE TABLE, с которой таблица была создана. Где это можно взять? Либо из старого бэкапа, либо из другого места. Также возможно восстановить структуру из словаря InnoDB, но я не буду описывать ее в этом ответе. Давайте просто предположим, что у вас это есть.
./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t actor.sql > dump.tsv 2> load_cmd.sql
c_parser выводит записи как дамп, разделенный табуляцией, в стандартный вывод. Дамп может быть загружен командой LOAD DATA. c_parser печатает его в stderr.
Подробности смотрите в постах:
Там нет простого способа сломать это для вас. Неважно, если вы сбросили БД через phpmyadmin или командную строку. Это прошло.
Человеческая ошибка - одна из причин иметь хороший резервный режим.
Я не религиозен, но я помолюсь, надеясь, что это не слишком важно.
Зависит от вашей настройки. Восстановление возможно, если вы правильно настроили свою систему. Если у вас есть резервная копия, вы можете восстановить ее. и затем примените двоичные журналы к точке непосредственно перед тем, как вы уронили таблицу.
http://dev.mysql.com/doc/refman/5.5/en/mysqlbinlog.html
Я предлагаю вам сделать это на другом сервере, после восстановления таблицы вы можете использовать mysqldump для ее извлечения и импорта обратно на рабочий сервер. Это не будет быстрое восстановление, но вы можете восстановить данные.
Если вы не знаете, что делаете, я бы предложил заключить контракт на поддержку с одной из консалтинговых компаний mysql (вероятно, Pythian, Percona, Palamino - лучшие) и попросить их помочь вам в этом.
желаю тебе удачи