Spec-Zone.ru › MySQL 8.4

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

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

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

На некоторых системах в журнале ошибок вы можете найти стек вызовов, где сервер mysqld завершился. Обратите внимание, что значения переменных, записанные в журнале ошибок, не всегда могут быть на 100% корректными.

Если вы обнаружили, что сервер mysqld завершается при запуске во время InnoDB восстановления, обратитесь к Раздел 17.20.2, «Отладка ошибок восстановления».

Многие неожиданные завершения работы сервера вызваны повреждёнными файлами данных или индексов. 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. Это гарантирует, что вы работаете из чистого состояния. См. Главу 7, Администрирование сервера MySQL.

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

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

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

  • Настройка MySQL для отладки значительно облегчает сбор информации о возможных ошибках, если что-то пойдет не так. Переконфигурируйте MySQL с параметром -DWITH_DEBUG=1 для CMake и затем перекомпилируйте. См. Раздел 7.9, «Отладка 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 (или другого отладчика). См. Раздел 7.9, «Отладка MySQL».

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

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

      backtrace
      info local
      up
      info local
      up
      info local
      

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

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

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

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

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

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

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

    Spec-Zone.ru

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