MySQL упал во время обновления сайта и не поднимается: сегфолт в фоновой очистке InnoDB и изоляция повреждённой базы

Что было. На Ubuntu 22.04 во время обновления CMS MySQL 8 упал. Клиенты получают Can't connect to local MySQL server through socket, каталог /var/run/mysqld появляется и тут же исчезает (сервер стартует и сразу падает). Перезагрузка и переустановка пакета не помогли. В журнале ошибок дамп стека: signal 11 (segmentation fault) в потоке фоновой очистки InnoDB (purge) и стандартная приписка «возможно, вы нашли ошибку, но это также может быть вызвано неисправным оборудованием».

Что сделал автор (подтверждено). Определил по стеку, какая база обрабатывалась в момент падения, остановил сервер, переместил каталог этой базы из /var/lib/mysql/ в сторону, запустил сервер. Остальные базы заработали. Повреждённую базу, поскольку это была рабочая копия для разработки, проще было переимпортировать из источника, чем восстанавливать.

Почему так работает. Фоновая очистка проходит по истории изменений всех таблиц; если в одной из них повреждённая страница, поток падает и роняет сервер. Убрав каталог базы, вы убираете и повреждённые страницы из обхода. Это грубый приём: база после этого «потеряна» для сервера (в словаре данных остаются ссылки, DROP DATABASE после возврата чистой копии их уберёт), но он даёт немедленно вернуть остальные сервисы.

Правильная последовательность для боевого сервера.

  1. Копия /var/lib/mysql на другой носитель.
  2. Проверить оборудование и файловую систему: dmesg -T | tail, smartctl, для виртуальной машины журнал событий хранилища у поставщика; повторяющиеся сегфолты в InnoDB это почти всегда диск или память, а не ошибка в СУБД.
  3. Попробовать поднять сервер с innodb_force_recovery = 1 (при необходимости 2–3), снять дамп проблемной базы (mysqldump --single-transaction --skip-lock-tables db), остановить, убрать параметр.
  4. Если дамп не снимается даже так: изолировать каталог базы как в исходной истории, поднять остальное, восстанавливать эту базу из резервной копии.
  5. После стабилизации: mysqlcheck --all-databases и включить регулярные дампы, если их не было.

Про «переустановку пакета». apt reinstall mysql-server не трогает каталог данных (и не должен), поэтому от повреждённых страниц не помогает, а вот конфиги может подменить. Не первая мера.

Про мигающий каталог /var/run/mysqld. Он создаётся при старте и удаляется при падении, это следствие, а не причина. Смотреть journalctl -u mysql -b и /var/log/mysql/error.log.

Сбои сервера описаны в документации MySQL.