Восстановление поврежденных таблиц InnoDB в MySQL: параметр innodb_force_recovery
- MySQL аварийно падает при старте с ошибкой
Assertion failureилиInnoDB: Database page corruption on diskв error.log. - Процесс mysqld уходит в циклический рестарт (crash loop) под управлением systemd.
- Ошибки чтения конкретных табличных пространств
.ibdпри выполнении SELECT или транзакций.
1. Бэкап поврежденных файлов перед восстановлением
cp -r /var/lib/mysql /var/lib/mysql_corrupted_backup2. Итеративный подбор innodb_force_recovery
Добавьте параметр в секцию [mysqld] файла /etc/mysql/my.cnf (начиная со значения 1):
[mysqld]
innodb_force_recovery = 1Градация уровней восстановления:
- 1 (SRV_FORCE_IGNORE_CORRUPT): пропуск поврежденных страниц при сканировании.
- 2 (SRV_FORCE_NO_BACKGROUND): отключение фоновых потоков очистки (purge threads).
- 3 (SRV_FORCE_NO_TRX_UNDO): отказ от отката незавершенных транзакций после краша.
- 4 (SRV_FORCE_NO_IBUF_MERGE): запрет слияния буфера вставок (Insert Buffer merge).
- 5 (SRV_FORCE_NO_UNDO_LOG_SCAN): игнорирование журналов Undo при запуске.
- 6 (SRV_FORCE_NO_LOG_REDO): игнорирование журналов Redo (максимальный режим, возможна потеря последних транзакций).
3. Запуск MySQL и экспорт данных через mysqldump
systemctl start mysqld
mysqldump --all-databases --single-transaction --quick > /backup/full_dump_recovered.sql4. Пересоздание инстанса БД
После успешного дампа удалите старый каталог данных, инициализируйте новую базу и отключите аварийный режим:
systemctl stop mysqld
rm -rf /var/lib/mysql/*
mysqld --initialize --user=mysql
# Удалите строку innodb_force_recovery из my.cnf
systemctl start mysqld
mysql < /backup/full_dump_recovered.sql Частые вопросы (FAQ)
Можно ли выполнять операции записи (INSERT/UPDATE), когда включен innodb_force_recovery?
При значениях innodb_force_recovery >= 4 движок InnoDB автоматически переводится в режим read-only. Попытки записи будут отклонены с ошибкой ER_CANT_LOCK.
Что делать, если mysqldump зависает на конкретной таблице?
Исключите поврежденную таблицу с помощью опции --ignore-table=<db>.<table>, восстановите остальные базы данных, а сбойную таблицу выгрузите постранично или восстановите из последнего регулярного бэкапа.