Приходит уведомление в мониторинг, что дамп базы выполнен с ошибкой. База MySQL, размер дампа ~10ГБ. Так как размер позволяет, я бэкаплю её дампом несколько раз в день. Он проходит быстро, проблем не вызывает. Как настроен мониторинг, рассказывал отдельно.
Смотрю ошибку в логе дампа:
mysqldump: Error 1034: Index for table 'b_stat_session_data' is corrupt; try to repair it when dumping table `b_stat_session_data` at row: 329011В таблицу постоянно что-то пишется. Движок сайта по кронам сам её чистит. Судя по всему, что-то пошло не так. Сделал дамп без этой таблицы, добавив ключ
--ignore-table=dbname.b_stat_session_data. Потом сразу проверил более старые дампы и бэкап виртуалки. Всё на месте, можно разбираться.Первым делом хотел поднять копию виртуалки и попробовать разобраться там. Но, к сожалению, виртуалка очень большая. Восстанавливаться будет долго. Захотелось решить проблему здесь и сейчас, потому что было время и возможность. На первый взгляд она не особо критичная и грозит только потерей таблицы в худшем случае. Забегая вперёд скажу, что этот худший случай и произошёл.
Захожу в консоль mysql и смотрю:
> CHECK TABLE b_stat_session_data;Warning | InnoDB: The B-tree of index PRIMARY is corrupted. |Warning | InnoDB: Index IX_GUEST_MD5 is marked as corrupted |error | CorruptНичего хорошего. Пробую починить автоматически:
> OPTIMIZE TABLE b_stat_session_data;note | Table does not support optimize, doing recreate + analyze insteaderror | Got error 106 "Transport endpoint is already connected" from storage engine InnoDBstatus | Operation failedВ логе mariadb куча ошибок:
[ERROR] mariadbd: Index for table 'b_stat_session_data' is corrupt; try to repair itДля надёжности зажмурился и перезапустил службу mariadb. Перезапуск прошёл штатно, база поднялась, но таблица не ожила. Всё те же ошибки. Причём данные в неё, судя по всему, записывались.
Тут я немного приуныл, так как знаний не хватает решить проблему. Не понятна причина. Я узнал, что хранится в таблице и понял, что эти данные не представляют ценности и могут быть потеряны. Дальше поискал инфу в гугле и поговорил с chatgpt. Последний не предложил ничего нового из того, что я видел в гугле, но накидал неактуальных рекомендаций для движка MyISAM, хотя у меня InnoDB.
Нашёл следующие варианты решения проблемы:
1️⃣ Удалить и пересоздать все индексы.
2️⃣ Создать пустую таблицу с аналогичной структурой, скопировать туда данные, исходную удалить, новую таблицу переименовать.
3️⃣ Запустить сервер с активным параметром
innodb_force_recovery. 4️⃣ Пересобрать таблицу командой:
alter table b_stat_session_data engine = innodbСудя по отзывам, последняя команда будет выполняться очень долго. Третья может привести к долгому старту службы или ещё каким-то проблемам. Не хотелось запускать их на работающем сервере. Решил пересоздать индексы. Их там всего два, но один PRIMARY. Его нельзя просто взять и удалить. Вычитал на stackoverflow один совет. Зайти через phpmyadmin, убрать чекбокс Auto Increment на столбце с этим индексом, сохранить, потом зайти, вернуть AI. Возможно на живой таблице это и сработало бы, но у меня вылетела ошибка, ничего не сохранилось, таблица вообще умерла.
С этого момента некоторые юзеры начали получать ошибку MySQL Query Error! Дальше не стал экспериментировать, грохнул таблицу и создал заново. Структуру посмотрел в живом дампе. Всё сразу заработало, данные потекли в таблицу, дамп нормально создаётся.
Если у кого-то есть советы по теме, с удовольствием выслушаю. Ещё раз уточню, что стал делать опасные манипуляции, когда понял, что данные позволительно потерять. И я мог себе позволить простой в 10-15 минут.
#mysql
