Как исправить поврежденные таблицы в MySQL
Введение
Иногда таблицы MySQL могут быть повреждены, что означает, что произошла ошибка, и данные, содержащиеся в них, не читаются. Попытки чтения из поврежденной таблицы обычно приводят к сбою сервера.
Некоторые распространенные причины поврежденных таблиц:
- Сервер MySQL останавливается в процессе записи.
- Внешняя программа изменяет таблицу, которая одновременно изменяется сервером.
- Компьютер неожиданно выключился.
- Отказ компьютерного оборудования.
- Где-то в коде MySQL обнаружена программная ошибка.
Если вы подозреваете, что одна из ваших таблиц повреждена, вам следует сделать резервную копию каталога данных, прежде чем устранять неполадки или пытаться исправить таблицу. Это поможет свести к минимуму риск потери данных.
Сначала остановите службу MySQL:
- sudo systemctl stop mysql
Примечание. На некоторых платформах, таких как Rocky Linux, служба MySQL может вместо этого называться mysqld
.
Затем скопируйте все свои данные в новый каталог резервного копирования. В системах Ubuntu каталог данных по умолчанию — /var/lib/mysql/
:
- cp -r /var/lib/mysql /var/lib/mysql_bkp
После создания резервной копии вы готовы приступить к изучению того, действительно ли таблица повреждена. Если таблица использует механизм хранения MyISAM, вы можете проверить, не повреждена ли она, перезапустив MySQL и выполнив инструкцию CHECK TABLE
из командной строки MySQL:
- sudo systemctl start mysql
- CHECK TABLE table_name;
В выводе этого оператора появится сообщение, сообщающее, повреждено оно или нет. Если таблица MyISAM действительно повреждена, ее обычно можно восстановить, выполнив оператор REPAIR TABLE
:
- REPAIR TABLE table_name;
Предполагая, что восстановление прошло успешно, вы увидите в выводе сообщение, подобное этому:
Output+--------------------------+--------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+--------------------------+--------+----------+----------+
| database_name.table_name | repair | status | OK |
+--------------------------+--------+----------+----------+
Однако, если таблица все еще повреждена, документация MySQL предлагает несколько альтернативных методов восстановления поврежденных таблиц.
С другой стороны, если поврежденная таблица использует механизм хранения InnoDB, то процесс ее восстановления будет другим. InnoDB является механизмом хранения данных по умолчанию в MySQL начиная с версии 8.0, и в нем предусмотрена автоматическая проверка на наличие повреждений и операции восстановления. InnoDB проверяет наличие поврежденных страниц, выполняя контрольные суммы на каждой странице, которую она читает, и если она находит несоответствие контрольной суммы, она автоматически останавливает сервер MySQL.
Редко возникает необходимость восстанавливать таблицы InnoDB, поскольку InnoDB имеет механизм восстановления после сбоя, который может решить большинство проблем при перезапуске сервера. Однако, если вы столкнулись с ситуацией, когда вам нужно восстановить поврежденную таблицу InnoDB, документация MySQL рекомендует использовать логическую резервную копию таблицы, которая сохранит структуру таблицы и данные в ней, и затем перезагрузите таблицу обратно в базу данных.
Имея это в виду, попробуйте перезапустить службу MySQL, чтобы узнать, позволит ли это вам получить доступ к серверу:
- sudo systemctl restart mysql
Если сервер по-прежнему поврежден или недоступен по другой причине, может быть полезно включить параметр InnoDB force_recovery
. Это можно сделать, отредактировав файл mysqld.cnf
. В системах Ubuntu и Debian этот файл обычно находится в etc/mysql
. В системах Red Hat и Rocky этот файл обычно находится в /etc/my.cnf.d
.
- sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
В разделе [mysqld]
добавьте следующую строку:
. . .
[mysqld]
. . .
innodb_force_recovery=1
Сохраните и закройте файл, а затем попробуйте снова перезапустить службу MySQL. Если вы можете успешно получить доступ к поврежденной таблице, используйте утилиту mysqldump
, чтобы сбросить данные таблицы в новый файл. Вы можете назвать этот файл как угодно, но здесь мы назовем его out.sql
:
- mysqldump database_name table_name > out.sql
Затем удалите таблицу из базы данных. Чтобы избежать повторного открытия приглашения MySQL, вы можете использовать следующий синтаксис:
- mysql -u user -p --execute="DROP TABLE database_name.table_name"
После этого восстановите таблицу с помощью только что созданного файла дампа:
- mysql -u user -p < out.sql
Обратите внимание, что механизм хранения InnoDB, как правило, более отказоустойчив, чем старый механизм MyISAM. Таблицы, использующие InnoDB, могут по-прежнему быть повреждены, но благодаря функциям автоматического восстановления риск повреждения таблиц и сбоев значительно ниже.