Рассмотрим как исправить таблицы InnoDB добавлением директивы innodb force recovery
MySQL поддерживает два основных движка: MyISAM и InnoDB, InnoDB используется гораздо чаще (о том как определить движок). При серьезных проблемах в работе сервера — при нехватке оперативной памяти или закончившемся месте на диске таблицы сервера баз данных могут оказаться поврежденными. Таблицы MyISAM исправляются при помощи утилиты myisamchk, восстановление же InnoDB обычно занимает несколько больше времени.
innodb force recovery и восстановление MySQL из SQL дампа
Основная опция позволяющая выполнить восстановление и дополнительные (о них ниже) добавляются в файл /etc/mysql/my.cnf или один из файлов подключаемых в /etc/mysql/my.cnf. Секция файла должна называться [mysqld]
mcedit /etc/mysql/my.cnf
[mysqld]
innodb_force_recovery = 1
Параметру innodb_force_recovery ставится в соответствие числовое значение от 1 до 6. С увеличением значения MySQL становится менее чувствителен к целостности данных. Часть данных при этом модифицируется механизмами MySQL.
За счет директивы сервер баз данных становится возможным запустить. Вероятность успешности запуска возрастает с ростом индекса, также возрастают потери данных (всё чем MySQL считает допустимым пренебречь при старте).
В случае если служба запустилась с опцией innodb_force_recovery = 1 часто можно остановиться. Убрать опцию из конфигурационного файла и запустить mysql ещё раз. При запуске с опцией могут быть исправлены повреждения таблиц если они незначительные, если без опции mysql потом запускается, значит всё в порядке.
Если со значением 1 сервис не стартует — нужно:
- создать бэкап datadir (стандартный путь /var/lib/mysql )
- увеличивать значение параметра с 2 до 6 каждый раз пробуя запустить службу
Когда она запустится понадобится создать SQL дамп поврежденных таблиц или базы целиком, удалить таблицы/базу, убрать опцию, запустить MySQL баз базы/таблиц в нормальном режиме, загрузить созданные SQL дампы или дамп в базу при необходимости её предварительно создав. Подробнее процесс расписан ниже.
Дополнительные параметры
Если в логах сервера баз данных встречаются такие сообщения:
InnoDB: Waiting for the background threads to start
В конфигурационный файл необходимо также добавить
innodb_purge_threads=0
Также лучше временно сменить порт, на котором работает MySQL чтобы к службе не поступали запросы во время восстановления
port = 3307
Когда MySQL запущен важно учитывать что в режиме восстановления сервис работает с данными в read only, никакие обновления до БД доходить не будут. Оставлять службу в таком виде нельзя.
Выясним какие таблицы повреждены и создадим SQL дамп
Проверяем таблицы и ищем Corrupted
mysqlcheck --all-databases
Создаем дамп всех поврежденных таблиц (составляем их список если таблиц много):
mysqldump database_name table_name > database.table.sql
Затем удаляем:
drop table database.table;
В режиме восстановления мы создали дампы, которые загрузим в MySQL когда он будет запущен в нормальном режиме.
При сравнительно небольшой базе данных можно для экономии времени не создавать SQL дампы отдельных таблиц, а сделать сразу для всей базы mysqldump database > database.sql, потом удалить базу и загрузить sql дамп
Восстанавливаем данные MySQL
Снова заходим в /etc/mysql/my.cnf и удаляем директивы innodb_purge_threads=0 (если она добавлялась), проверяем что задан порт 3306, удаляем параметр innodb_force_recovery.
Перезапускаем MySQL
systemctl restart mysql
Теперь можно загрузить поврежденные ранее таблицы, дампы которых сделали ранее в режиме восстановления.
Для каждого файла с SQL дампом таблицы БД database_name выполняе
Если один SQL дамп со всей базой, то одна команда:
mysql database < database.table.sql
В /etc/mysql/my.cnf меняем порт на тот, на котором сервер баз данных работал ранее. и перезапускаем вновь
systemctl restart mysql
Проверяем статус, убеждаемся в том что служба работает в нормальном режиме, без опции, которая добавлялась.
Проверяем всё ли работает, если да, то размещаем SQL дампы в каком-то каталоге. Удаляем его содержимое через несколько дней.
После того как все описанные шаги проделаны MySQL должен вновь работать нормально, а все таблицы InnoDB будут исправлены. Об опции есть информация в документации MySQL