Spec-Zone.ru › MySQL 5.7

B.3.3.3 Что делать, если MySQL постоянно вылетает из работы

Каждая версия MySQL тестируется на многих платформах перед выпуском. Это не означает, что в MySQL нет ошибок, но если они есть, их должно быть очень мало, и их трудно найти. Если у вас возникла проблема, всегда полезно попытаться выяснить, что именно вызывает сбой вашей системы, потому что у вас гораздо больше шансов быстро исправить проблему.

Сначала вы должны попытаться выяснить, связана ли проблема с тем, что сервер mysqld завершает работу или ваша проблема связана с клиентом. Вы можете проверить, как долго работает ваш сервер mysqld, выполнив команду mysqladmin version. Если сервер mysqld завершил работу и перезапустился, причину можно найти в журнале ошибок сервера. См. Раздел 5.4.2, «Журнал ошибок».

В некоторых системах в журнале ошибок можно найти трассировку стека, где сервер mysqld завершил работу, которую можно устранить с помощью программы resolve_stack_dump. См. Раздел 5.8, «Отладка MySQL». Обратите внимание, что значения переменных, записанные в журнале ошибок, не всегда могут быть на 100% корректными.

Многие неожиданные завершения работы сервера вызываются поврежденными файлами данных или файлами индексов. MySQL обновляет файлы на диске с помощью системного вызова write() после каждой SQL-команды и перед тем, как клиент получит уведомление о результате. (Это не относится к случаям, когда вы работаете с включенной системной переменной delay_key_write, в этом случае файлы данных записываются, но не файлы индексов.) Это означает, что содержимое файлов данных остается безопасным, даже если сервер mysqld завершит работу аварийно, потому что операционная система гарантирует, что невыгруженные данные будут записаны на диск. Вы можете принудительно заставить MySQL выгрузить все на диск после каждой SQL-команды, запустив сервер mysqld с опцией --flush.

Это означает, что обычно вы не должны получать поврежденные таблицы, если не происходит одно из следующих событий:

  • Сервер MySQL или хост сервера были остановлены в середине обновления.

  • Вы обнаружили ошибку в mysqld, которая привела к его аварийной остановке в середине обновления.

  • Некоторая внешняя программа манипулирует файлами данных или файлами индексов одновременно с mysqld, не заблокировав таблицу должным образом.

  • Вы используете несколько серверов mysqld с одной и той же директорией данных в системе, которая не поддерживает хорошие блокировки файловой системы (обычно это обрабатывает менеджер блокировок lockd), или вы запускаете несколько серверов с отключенной внешней блокировкой.

  • У вас есть поврежденный файл данных или файл индексов, содержащий очень поврежденные данные, которые сбили с толку mysqld.

  • Вы обнаружили ошибку в коде хранения данных. Это маловероятно, но теоретически возможно. В этом случае вы можете попробовать изменить движок хранения на другой, используя ALTER TABLE на исправленной копии таблицы.

Поскольку очень сложно понять, почему что-то вылетает из работы, сначала попробуйте проверить, не приводят ли действия, которые работают для других, к неожиданному выходу для вас. Попробуйте следующее:

  • Остановите сервер mysqld с помощью mysqladmin shutdown, запустите myisamchk --silent --force */*.MYI из каталога данных для проверки всех MyISAM таблиц и перезапустите mysqld. Это гарантирует, что вы работаете с чистым состоянием. См. главу 5, Администрирование сервера MySQL.

  • Запустите mysqld с включенным общим журналом запросов (см. раздел 5.4.3, «Общий журнал запросов»). Затем попытайтесь определить из информации, записанной в журнал, убивает ли какой-то конкретный запрос сервер. Примерно 95% всех ошибок связаны с определённым запросом. Обычно это один из последних запросов в файле журнала перед перезапуском сервера. См. раздел 5.4.3, «Общий журнал запросов». Если вы можете неоднократно убивать MySQL с помощью конкретного запроса, даже когда вы проверили все таблицы непосредственно перед его выполнением, значит, вы изолировали ошибку и должны отправить отчёт об ошибке. См. раздел 1.5, «Как сообщать об ошибках или проблемах».

  • Попробуйте создать тестовый случай, который можно использовать для воспроизведения проблемы. См. раздел 5.8, «Отладка MySQL».

  • Попробуйте сценарий fork_big.pl. (Он находится в каталоге tests дистрибутивов исходных кодов.)

  • Настройка MySQL для отладки значительно упрощает сбор информации о возможных ошибках, если что-то пойдёт не так. Переконфигурируйте MySQL с помощью параметра -DWITH_DEBUG=1 для CMake и затем перекомпилируйте. См. раздел 5.8, «Отладка MySQL».

  • Убедитесь, что на вашем операционной системе установлены последние исправления.

  • Используйте параметр --skip-external-locking для mysqld. На некоторых системах менеджер блокировок lockd не работает должным образом; параметр --skip-external-locking сообщает mysqld не использовать внешние блокировки. (Это означает, что вы не можете запустить два сервера mysqld в одном каталоге данных и что вы должны быть осторожны, если используете myisamchk. Тем не менее, может быть полезно попробовать этот параметр в качестве теста.)

  • Если mysqld кажется работающим, но не реагирует, попробуйте mysqladmin -u root processlist. Иногда mysqld не зависает, хотя и кажется невосприимчивым. Проблема может заключаться в том, что все подключения заняты, или может быть какая-то внутренняя проблема с блокировкой. mysqladmin -u root processlist обычно может установить подключение даже в таких случаях и может предоставить полезную информацию о текущем количестве подключений и их статусе.

  • Запустите команду mysqladmin -i 5 status или mysqladmin -i 5 -r status в отдельном окне, чтобы получить статистику во время выполнения других запросов.

  • Попробуйте следующее:

    1. Запустите mysqld из gdb (или другого отладчика). См. раздел 5.8, «Отладка MySQL».

    2. Запустите ваши тестовые скрипты.

    3. Выведите трассировку стека и локальные переменные на трёх нижних уровнях. В gdb вы можете сделать это с помощью следующих команд, когда mysqld упал внутри gdb:

      backtrace
      info local
      up
      info local
      up
      info local
      

      С помощью gdb вы также можете проверить, какие потоки существуют с помощью info threads и переключиться на определённый поток с помощью thread N, где N — идентификатор потока.

  • Попробуйте смоделировать ваше приложение с помощью скрипта Perl, чтобы заставить MySQL выйти или неправильно себя вести.

  • Отправьте обычный отчёт об ошибке. См. раздел 1.5, «Как сообщать об ошибках или проблемах». Будьте ещё более подробны, чем обычно. Так как MySQL используется многими людьми, сбой может быть вызван чем-то, что существует только на вашем компьютере (например, ошибкой, связанной с вашими системными библиотеками).

  • Если у вас есть проблема с таблицами, содержащими строки переменной длины, и вы используете только VARCHAR столбцы (а не BLOB или TEXT столбцы), вы можете попробовать изменить все VARCHAR на CHAR с помощью ALTER TABLE. Это заставляет MySQL использовать строки фиксированной длины. Строки фиксированной длины занимают немного больше места, но намного более устойчивы к повреждениям.

    Текущий код динамических строк используется уже несколько лет с очень небольшим количеством проблем, но строки переменной длины по своей природе более склонны к ошибкам, поэтому эта стратегия может быть хорошей идеей, чтобы проверить, помогает ли она.

  • Рассмотрите возможность аппаратных сбоев при диагностике проблем. Неисправное оборудование может быть причиной повреждения данных. Обращайте особое внимание на подсистемы памяти и дисков при устранении неполадок с аппаратным обеспечением.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/crashing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API