Помилка 2006 під назвою MySQL Sever has gone away означає відмову сервера в з'єднанні навіть за умови, що він запущений. Відомо всього три причини, чому помилка з'являється. Перша причина - сервер перевантажений. Час очікування закінчився. Друга причина - клієнт надіслав занадто хворий пакет. Третя - сервер не був до кінця проініціалізований. Далі детально розглянемо, з яких причин з'являється помилка і як з нею боротися.
Зазвичай помилка з'являється під час спроби підключитися до бази даних за допомогою PHP, консольного клієнта, а також у разі використання PhpMyAdmin:
Давайте далі розглянемо кожну ситуацію окремо.
Як було сказано на початку статті, одна з можливих причин - закінчення часу очікування. Може бути так, що сервер був перевантажений і не справляється з навантаженням - обробкою всіх з'єднань. Щоб зрозуміти, наскільки довго виконуються серверні запити, можна скористатися будь-яким консольним клієнтом і підключитися до сервера. Якщо вам вдасться це зробити, виконайте будь-який запит. Якщо на обробку запитів йде занадто багато часу, оптимізувати MySQL можна за допомогою спеціального скрипта MySQLTuner. Зазвичай збільшується розмір пулу рушія InnoDB шляхом встановлення параметра innodb_buffer_pool_size
. Оптимальне значення визначається за допомогою наведеного вище скрипта.
Якщо це 800 мегабайт (може бути й інший розмір), прописуємо:
$ sudo vi /etc/mysql/my.cnf
innodb_buffer_pool_size=800M
Існує й інший спосіб розв'язання проблеми. Для цього збільшують час відповіді від сервера. Щоб виконати це завдання, необхідно змінити параметр wait_timeout
. Це час у секундах, протягом якого треба чекати відповіді від сервера.
Наприклад:
wait_timeout=500
Вносячи зміни, не забуваємо далі перезавантажити сервер:
$ sudo systemctl restart mysql
або:
$ sudo systemctl restart mariadb
Коли клієнт користувача створює занадто велику кількість пакетів, сервер видасть саме цю помилку. Доступний розмір пакета (максимальне значення) можна збільшити за допомогою параметра max_allowed_packet
.
Наприклад:
$ sudo vi /etc/mysql/my.cnf
max_allowed_packet=128M
Окремо зверніть увагу на клієнт, адже якщо він надсилає багато запитів, то ви явно щось робить не так. Як мінімум не варто генерувати запити до MySQL за допомогою циклів for
.
Якщо ви вирішите розгорнути MySQL або MariaDB у Docker, то будьте готові зіткнутися з подібною помилкою. Початкова ініціалізація контейнера вимагає трохи більше вільного часу. Якщо не дати контейнеру завершити ініціалізацію, спершу зупинивши його і запустивши, то база даних буде завжди повертати таку помилку. Рішення - потрібно повністю видалити дані контейнера з базою даних.
Робиться це так:
$ docker-compose down
або:
$ docker rm mysql-container
Далі треба видалити сховище (volume) з некоректно проініціалізованою базою. Але на початку перегляньте список усіх сховищ:
$ docker volume ls
Після видаляємо:
$ docker volume rm volume_name
Тепер можете запустити ініціалізацію застосунку, тільки дочекайтеся, поки сервер баз даних повідомить, що він готовий, і ви зможете до нього підключитися.