Site icon 8HOST.COM

Устранение неполадок в MySQL

MySQL – это реляционная система управления базами данных (РСУБД) с открытым исходным кодом, самая популярная в мире.

Конечно, при работе с любым программным обеспечением и новички, и опытные пользователи могут столкнуться с непонятными ошибками или проблемами, которые трудно диагностировать.

Этот мануал станет отправной точкой при диагностике настроек MySQL и устранении неполадок. Здесь мы рассмотрим общие проблемы, с которыми сталкиваются многие пользователи MySQL, и предоставим рекомендации по их устранению. Мы также предоставим ссылки на официальную документацию MySQL и другие мануалы, которые могут быть полезны в некоторых случаях.

Данный мануал выполнен на основе настройки, описанной в статье Установка MySQL в Ubuntu 18.04. Если вы используете другой дистрибутив, вы можете найти соответствующее руководство в нашем Информатории.

Начало работы в MySQL

Многие пользователи MySQL впервые сталкиваются с проблемой уже в процессе установки и настройки. Мануал Установка MySQL в Ubuntu 18.04 содержит инструкции по базовой конфигурации и может быть полезным для новичков в MySQL.

Причина, по которой некоторые пользователи сталкиваются с проблемами, заключается в том, что их приложениям требуются функции базы данных, доступные только в последних релизах, но версия MySQL в репозиториях по умолчанию некоторых дистрибутивов Linux (включая Ubuntu) не очень свежая. Потому разработчики MySQL поддерживают свой собственный репозиторий программного обеспечения, который вы можете использовать для установки последней версии и регулярного ее обновления. В мануале Установка последней версии MySQL в Ubuntu 18.04 содержатся инструкции о том, как это сделать.

Логи ошибок MySQL

Часто первопричину замедлений, сбоев или другого непредвиденного поведения MySQL можно определить, проанализировав логи ошибок. В системе Ubuntu этот лог по умолчанию находится в /var/log/mysql/error.log. Во многих случаях логи ошибок проще всего прочитать с помощью программы less, утилиты командной строки, которая позволяет просматривать файлы, но не редактировать их:

sudo less /var/log/mysql/error.log

Если MySQL работает не так, как ожидалось, вы можете ввести эту команду и получить больше информации об источнике проблемы, диагностировав ошибку на основе содержимого лога.

Сброс root пароля MySQL

Если вы установили пароль root для MySQL, но потому забыли его, вы можете заблокировать себе доступ к собственным данным в СУБД. Однако если у вас есть доступ к серверу, на котором размещена ваша БД, вы сможете сбросить пароль.

Процедура подробно описана в мануале Сброс root-пароля MySQL или MariaDB в Ubuntu 18.04.

Проблемы с запросами

Иногда пользователи сталкиваются с проблемами при отправке запросов. В некоторых системах баз данных, включая MySQL, операторы запроса должны заканчиваться точкой с запятой (;), как в следующем примере:

SHOW * FROM table_name;

Если вы забудете добавить точку с запятой в конец запроса, запрос будет продолжаться в новой строке. Завершите запрос, введя точку с запятой и нажав Enter.

Некоторые пользователи сталкиваются с тем, что запросы обрабатываются чрезвычайно медленно. Один из способов определить, какой оператор является причиной замедления, – включить и просмотреть лог медленных запросов MySQL. Для этого откройте файл mysqld.cnf, который используется для настройки параметров сервера MySQL. Этот файл обычно хранится в каталоге /etc/mysql/mysql.conf.d/:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

Просмотрите файл и найдите такой фрагмент:

. . .
#slow_query_log         = 1
#slow_query_log_file    = /var/log/mysql/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
. . .

Эти закомментированные директивы определяют стандартные параметры конфигурации MySQL для лога медленных запросов. Вот что делает каждая из них:

Раскомментируйте эти строки, удалив символы #. В результате вы получите:

. . .
slow_query_log = 1
slow_query_log_file = /var/log/mysql-slow.log
long_query_time = 2
log_queries_not_using_indexes
. . .

Примечание: В MySQL 8+ по умолчанию этих директив в файле mysqld.cnf нет. Вам нужно добавить в конец файла такие строки:

. . .
slow_query_log = 1

slow_query_log_file = /var/log/mysql-slow.log


long_query_time = 2


log_queries_not_using_indexes

После включения лога медленных запросов сохраните и закройте файл. Затем перезапустите MySQL:

sudo systemctl restart mysql

Эти параметры помогут найти проблемные операторы в логе медленных запросов. Вы можете сделать это с помощью less:

sudo less /var/log/mysql_slow.log

Определив запросы, вызывающие замедление, вы можете обратиться к мануалу Оптимизация запросов и таблиц MySQL и MariaDB, который поможет их оптимизировать.

Кроме того, MySQL включает оператор EXPLAIN, который предоставляет информацию о выполнении запросов. Эта страница из официальной документации MySQL рассказывает о том, как использовать EXPLAIN для выявления неэффективных запросов.

Базовые запросы описаны в мануале Запросы в MySQL.

Настройка удаленного доступа

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

Одна из наиболее распространенных проблем, с которыми сталкиваются пользователи при настройке удаленной базы данных MySQL, заключается в том, что их экземпляр настроен на прослушивание только локальных соединений. Это настройка по умолчанию для MySQL, но она не подходит для удаленной базы данных, поскольку MySQL не имеет возможности прослушивать внешний IP-адрес, по которому можно связаться с сервером. Чтобы изменить это, откройте файл mysqld.cnf:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

В файле найдите строку bind-address:

. . .
lc-messages-dir = /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = 127.0.0.1
. . .

По умолчанию это значение 127.0.0.1, что означает, что сервер будет слушать только локальные соединения. Вам нужно изменить эту директиву и указать внешний IP-адрес. В целях устранения неполадок вы можете установить в этой директиве IP-адрес с подстановочными символами *, :: или 0.0.0.0:

. . .
lc-messages-dir = /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = 0.0.0.0
. . .

Примечание: В MySQL 8+ директивы bind-address по умолчанию нет в файле mysqld.cnf. В этом случае добавьте в конец файла следующую выделенную строку:

. . .
[mysqld] pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
log-error       = /var/log/mysql/error.log
bind-address            = 0.0.0.0

Сохраните и закройте файл. Затем перезапустите MySQL:

sudo systemctl restart mysql

Теперь попробуйте получить удаленный доступ к БД.

mysql -u user -h database_server_ip -p

Если сейчас вы можете получить доступ к своей БД, это подтверждает, что проблема была в директиве bind-address и вы ее устранили. Однако обратите внимание, что настройка bind-address на 0.0.0.0 небезопасна, так как позволяет подключаться к вашему серверу с любого IP-адреса. Если же вы все еще не можете получить доступ к базе данных удаленно, проблема может быть вызвана чем-то другим. В любом случае вам может быть полезно обратиться к мануалу Настройка удаленной базы данных MySQL для оптимизации производительности сайта в Ubuntu 18.04.

MySQL внезапно останавливается или не может запуститься

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

Сначала попытайтесь запустить сервер MySQL:

sudo systemctl start mysql

Затем просмотрите логи ошибок, чтобы узнать, что именно вызывает сбой MySQL. Вы можете использовать less:

sudo less /var/log/mysql/error.log

Сообщения, которые указывают на недостаточный объем памяти – это обычно записи типа Out of memory или mmap can’t allocate.

Потенциально решить проблемы с памятью могут:

Обратите внимание: хотя обновление (увеличение) сервера является потенциальным решением проблем с памятью, делать это рекомендуется только после того, как вы изучите и взвесите все остальные варианты. Модернизированный сервер с большим количеством ресурсов будет стоить больше денег, поэтому изменение размера следует выполнять только в том случае, если это действительно лучший (или единственный) вариант. Документация MySQL предлагает ряд других решений по диагностике и предотвращению сбоев.

Поврежденные таблицы

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

Вот распространенные причины поврежденных таблиц:

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

Сначала остановите MySQL:

sudo systemctl stop mysql

Затем скопируйте все свои данные в новый каталог. В системах Ubuntu каталогом данных по умолчанию является /var/lib/mysql/:

cp -r /var/lib/mysql /var/lib/mysql_bkp

После создания резервной копии вы можете начать проверку таблицы на наличие повреждений. Если таблица использует механизм хранения MyISAM, вы можете проверить, не повреждена ли она, запустив CHECK TABLE из командной строки MySQL:

CHECK TABLE table_name;

В выводе этого оператора появится сообщение о том, повреждена она или нет. Если таблица MyISAM действительно повреждена, ее обычно можно исправить, выполнив REPAIR TABLE:

REPAIR TABLE table_name;

Если таблица успешно исправлена, вы увидите:

+--------------------------+--------+----------+----------+
| Table                    | Op     | Msg_type | Msg_text |
+--------------------------+--------+----------+----------+
| database_name.table_name | repair | status   | OK       |
+--------------------------+--------+----------+----------+

Если это не помогло исправить таблицу, в документации MySQL есть несколько альтернативных методов восстановления поврежденных таблиц.

Если поврежденная таблица использует механизм хранения InnoDB, процесс ее восстановления будет другим. InnoDB – это стандартный механизм хранения MySQL начиная с версии 5.5, он поддерживает автоматическую проверку и исправление ошибок. InnoDB проверяет наличие поврежденных страниц, отслеживая контрольные суммы на каждой странице, которую он читает, и если он находит несоответствие контрольной суммы, он автоматически останавливает сервер MySQL.

Необходимость исправления таблиц InnoDB возникает редко, поскольку InnoDB предоставляет механизм восстановления после сбоя, который может решить большинство проблем при перезапуске сервера. Однако если вы все же столкнулись с такой необходимостью, в документации MySQL рекомендуется использовать метод «Сброс и перезагрузка».

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

Имея это в виду, попробуйте перезапустить MySQL, чтобы увидеть, позволит ли это вам получить доступ к серверу:

sudo systemctl restart mysql

Если сервер по-прежнему недоступен, тогда может быть полезно включить опцию InnoDB force_recovery. Вы можете сделать это, отредактировав файл mysqld.cnf:

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, все еще могут быть повреждены, но благодаря функциям автоматического восстановления риск повреждения и сбоев таких таблиц значительно ниже.

Ошибки сокета

MySQL управляет соединениями с сервером базы данных с помощью файла сокета, особого файла, который упрощает связь между различными процессами. Файл сокета MySQL называется mysqld.sock, а в системах Ubuntu он обычно хранится в каталоге /var/run/mysqld/. Этот файл создается сервисом MySQL автоматически.

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

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

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

Одной из распространенных причин этой ошибки является то, что сервис MySQL изначально остановлен или не запускается. Это означает, что он не смог создать файл сокета. Чтобы выяснить, является ли это причиной возникновения ошибки, попробуйте запустить сервис через systemctl:

sudo systemctl start mysql

Затем попробуйте снова получить доступ к MySQL. Если вы все еще получаете ошибку сокета, проверьте расположение, в котором MySQL ищет файл сокета. Эта информация находится в файле mysqld.cnf:

sudo nano /etc/mysql/mysql.conf.d/mysql.cnf

Найдите параметр socket в разделе [mysqld]:

. . .
[mysqld] user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
. . .

Закройте этот файл, а затем убедитесь, что файл mysqld.sock существует, выполнив команду ls в каталоге, где MySQL будет его искать:

ls -a /var/run/mysqld/

Если файл сокета существует, вы увидите его в выводе этой команды:

.  ..  mysqld.pid  mysqld.sock  mysqld.sock.lock

Если файл не существует, возможно, причина в том, что MySQL пытается его создать, но не имеет соответствующих прав для этого. Вы можете убедиться в наличии необходимых привилегий, передав права собственности  на каталог пользователю и группе mysql:

sudo chown mysql:mysql /var/run/mysqld/

Затем убедитесь, что у пользователя mysql есть соответствующие права доступа к каталогу. 755 подойдет в большинстве случаев:

sudo chmod -R 755 /var/run/mysqld/

Перезапустите сервис MySQL, чтобы он мог снова попытаться создать файл сокета:

sudo systemctl restart mysql

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

Заключение

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

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

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