MySQL — Восстановление таблиц Innodb
Шеф! Все пропало! База упала, данные пропали!
mysql> SELECT * FROM cheaters;
ERROR 1146 (42S02): TABLE 'helldb.cheaters' doesn't exist
mysql>
Или это может выглядеть вот так, при попытке забекапить базу mysqldump -ом:
Enter password:
mysqldump: Got error: 1146: Table 'helldb.cheaters' doesn't exist when using LOCK TABLES
[red@hellsrv ~]$
Перед любыми действиями с базой, обязательно сделайте ее бэкап!
Поскольку mysqldump в нашем случае не вариант, то на уровне файловой системы самое то. Для этого остановить сервер mysql:
И скопируйте сбойную базу в директорию где вы храните бэкапы:
Уже после бэкапа, беремся за восстановление всеми силами.
Судя по файликам, таблицы в InnoDB, для того чтобы восстановить эти таблицы нам нужны 2 вещи:
— узнать структуру таблиц
— иметь файлики с данными (имеется ввиду файлы на уровне файловой системы)
Особенность Innodb такова, что таблица на уровне файловой системы состоит из двух фалов:
Идея восстановления следующая:
1. узнать структуру «битой» таблицы
2. создать чистую базу
3. создать в ней таблицу нужной структуры (читай п.1)
4. скопировать данные в новую таблицу из старой
5. если данные окажутся битыми, можно попробовать восстановить их используя утилиту innochecksum
У меня есть новый сервер debnew с установленным Debian 8, в его официальных репах есть пакет с нужной нам утилитой для чтения структуры таблиц InnoDB из файлика frm.
Ставим нужный пакетик:
Используется она вот так:
Еще нюанс: на новом сервере я установил mariadb-server, запустил его и создал отдельную чистую базу. Туда по одной создавал таблицы и подливал данные с битых таблиц со старого сервера.
Для создания базы на новом сервере мне нужно было узнать какая кодировка была в старой базе. Это можно посмотреть на сервере с битой базой:
+----------------------------+------------------------+
| DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
+----------------------------+------------------------+
| cp1251 | cp1251_general_ci |
+----------------------------+------------------------+
1 ROW IN SET (0.00 sec)
mysql>
Создаем новую базу в mariadb:
Query OK, 1 ROW affected (0.00 sec)
MariaDB [(NONE)]>
Ну и дальше поехали таблички восстанавливать … одна за другой. Начну с простой таблички, чтоб много не писать.
Узнаем структуру:
# WARNING: Cannot generate character set or collation names without the --server option.
# CAUTION: The diagnostic mode is a best-effort parse of the .frm file. As such, it may not identify all of the components of the table correctly. This is especially true for damaged files. It will also not read the default values for the columns and the resulting statement may not be syntactically correct.
# Reading .frm file for articles.frm:
# The .frm file is a TABLE.
# CREATE TABLE Statement:
CREATE TABLE `articles` (
`id` int(10) unsigned NOT NULL comment 'Article ID',
`name` varchar(128) NOT NULL comment 'Article name',
PRIMARY KEY `PRIMARY` (`id`)
) ENGINE=InnoDB COMMENT 'Catalogue of articles';
#...done.
[red@debnew mysql_recovery]$
Берем командочку из предыдущего шага и создаем в чистой базе такую таблицу:
DATABASE changed
MariaDB [helldb]> CREATE TABLE `articles` (
-> `id` INT(10) UNSIGNED NOT NULL comment 'Article ID',
-> `name` VARCHAR(128) NOT NULL comment 'Article name',
-> PRIMARY KEY `PRIMARY` (`id`)
-> ) ENGINE=InnoDB COMMENT 'Catalogue of articles';
Query OK, 0 ROWS affected (0.30 sec)
MariaDB [helldb]>
Таблица с нужной структурой у нас есть, теперь нужно скопировать в нее данные. Они хранятся в файлике `table_name`.ibd, такой файлик автоматом создается во время создания таблицы (даже если она без данных). Вот он на новом сервере:
total 104
-rw-rw---- 1 mysql mysql 1094 Apr 9 17:07 articles.frm
-rw-rw---- 1 mysql mysql 98304 Apr 9 17:07 articles.ibd
-rw-rw---- 1 mysql mysql 65 Apr 9 17:05 db.opt
debnew:/home/mysql/helldb#
сначала нужно очистить тот файлик что у нас есть, потом подлить (на уровне FS) со старой базы, и импортнуть. Для этого в mysql консоли чистим новый пустой файл данных:
Query OK, 0 ROWS affected (0.04 sec)
MariaDB [helldb]>
файлик удалился, убедимся:
total 8
-rw-rw---- 1 mysql mysql 1094 Apr 9 17:07 articles.frm
-rw-rw---- 1 mysql mysql 65 Apr 9 17:05 db.opt
debnew:/home/mysql/helldb#
копируем имеющийся articles.idb с мертвой базы (можно из бекапа):
debnew:/home/mysql/helldb# chown mysql.mysql articles.ibd
пробуем импортировать данные, в mysql консоли:
Query OK, 0 ROWS affected, 1 warning (0.50 sec)
MariaDB [helldb]>
Ругани нету, проверяем есть ли что в таблице теперь:
+-----+-----------+
| id | name |
+-----+-----------+
| 333 | Gigabytes |
| 777 | Megabytes |
+-----+-----------+
2 ROWS IN SET (0.00 sec)
MariaDB [helldb]>
Отлично! Если есть еще сбойные таблицы, повторяем процедуру для других таблиц 🙂 После этого делаете mysqldump новой базы и заливаете его уже куда хотите 🙂
Хай щастить!
Комментов пока нет