Troubleshooting ‘MySQL server has gone away: packet too large’ Query Failure on Ubuntu 20.04 LTS
Resolve the 'MySQL server has gone away: packet too large' error on Ubuntu 20.04 LTS by adjusting MySQL, PHP-FPM, and application configurations to handle large queries and result sets.
Resolve the 'MySQL server has gone away: packet too large' error on Ubuntu 20.04 LTS by adjusting MySQL, PHP-FPM, and application configurations to handle large queries and result sets.
This guide addresses a common and often frustrating issue where your application or database client encounters a MySQL server has gone away error, specifically accompanied by the "packet too large" context. This typically happens when your database client or server tries to send/receive a data packet exceeding its configured maximum size, leading to an abrupt connection termination. For administrators running web applications on Ubuntu 20.04 LTS with a MySQL or MariaDB backend, this guide provides a step-by-step resolution.
Symptom & Error Signature
Users typically experience this error when executing large SQL queries, importing substantial datasets, or fetching extensive result sets. This can manifest as:
- Web application errors: A blank page, a generic "server error," or an explicit error message logged by the application.
- Failed cron jobs: Scripts performing data synchronization or batch operations terminate unexpectedly.
- Database client errors: Using the
mysqlcommand-line client or a GUI tool, the connection drops, or a query fails with the specific error.
Typical error messages you might encounter include:
1. PHP Application Error Log (e.g., in /var/log/phpX.X-fpm.log or application-specific logs):
[202X-XX-XX XX:XX:XX] production.ERROR: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away {"exception":"[object] (PDOException(code: 2006): SQLSTATE[HY000]: General error: 2006 MySQL server has gone away at /var/www/html/app/src/Database.php:123)"}
Or, more explicitly:
[202X-XX-XX XX:XX:XX] production.ERROR: Error: MySQL server has gone away (packet too large) during query execution.
2. MySQL Command-Line Client Error:
ERROR 2006 (HY000): MySQL server has gone away
3. General Application Log (Python, Node.js, etc.):
DB_ERROR: (2006, "MySQL server has gone away (packet too large)")
Root Cause Analysis
The "MySQL server has gone away" error, particularly with the "packet too large" indication, fundamentally points to a mismatch or misconfiguration in the maximum allowable packet size for data exchange between the MySQL client (your application) and the MySQL/MariaDB server.
Here's a breakdown of the underlying reasons:
max_allowed_packeton the MySQL/MariaDB Server: This is the most common culprit. Themax_allowed_packetserver variable defines the maximum size of a single packet or any generated/intermediate string, or any parameter sent by themysql_stmt_send_long_data()C API function. If a client attempts to send a query (e.g., a very largeINSERTorUPDATEstatement, or aBLOBfield) or the server tries to return a result set larger than this configured value, the connection is abruptly terminated.max_allowed_packeton the MySQL Client: While less common for applications (as they often inherit server settings or use a default that works), some client libraries or utilities (like themysqlcommand-line client) can also have their ownmax_allowed_packetsetting. If the client's setting is lower than what the server is configured for, or if the client tries to send data larger than its own limit, the connection will drop.PHP
memory_limit(for PHP Applications): When a PHP application fetches a very large result set from the database, the data must be held in the PHP script's memory. If the size of this data exceeds the configuredmemory_limitinphp.ini, PHP will terminate the script, which can manifest as a "MySQL server has gone away" error because the PHP process drops the database connection without proper closure.Network Issues or Timeouts (General "Gone Away"): While "packet too large" specifically points to the packet size, the broader "MySQL server has gone away" can also be caused by network connectivity issues, the server crashing, or connection timeouts (
wait_timeout,interactive_timeout). However, for this specific error (packet too large), these are usually secondary or unrelated.
Step-by-Step Resolution
To resolve the "MySQL server has gone away: packet too large" error, you'll primarily need to adjust configuration parameters on both your MySQL/MariaDB server and potentially your application's environment (e.g., PHP-FPM).
1. Adjust MySQL/MariaDB Server's max_allowed_packet
This is typically the most direct solution.
Check the current value: Connect to your MySQL/MariaDB server using the command-line client and check the current
max_allowed_packetsetting:mysql -u root -p -e "SHOW VARIABLES LIKE 'max_allowed_packet';"You will be prompted for your MySQL root password. The output will show the value in bytes (e.g.,
16777216for 16MB).Locate the MySQL/MariaDB configuration file: On Ubuntu 20.04 LTS, MySQL and MariaDB configuration files are usually located in
/etc/mysql/. Common files to modify include:/etc/mysql/my.cnf(main configuration)/etc/mysql/mysql.conf.d/mysqld.cnf(MySQL specific configuration)/etc/mysql/mariadb.conf.d/50-server.cnf(MariaDB specific server configuration)
It's best practice to check which file is actually being used by your server. Often, you'll find
!includedir /etc/mysql/conf.d/or!includedir /etc/mysql/mariadb.conf.d/inmy.cnf, meaning specific settings are in separate files. For server-wide settings,mysqld.cnf(MySQL) or50-server.cnf(MariaDB) are typically the correct places.Edit the configuration file: Open the relevant configuration file with a text editor (e.g.,
nanoorvim). For MariaDB, this might be/etc/mysql/mariadb.conf.d/50-server.cnf:sudo nano /etc/mysql/mariadb.conf.d/50-server.cnfLocate the
[mysqld]section and add or modify themax_allowed_packetdirective. A common value for web applications is64Mor128M, but you might need more depending on your data.# /etc/mysql/mariadb.conf.d/50-server.cnf or /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] # ... other settings ... max_allowed_packet = 64M # ... other settings ...Setting
max_allowed_packetto an excessively high value (e.g., several gigabytes) can make your server vulnerable to Denial of Service (DoS) attacks, as it could consume too much memory when handling large, malicious packets. Choose a value that accommodates your legitimate application needs without being overly generous.Restart the MySQL/MariaDB service: After saving the changes, you must restart the database service for them to take effect.
For MySQL 8.x:
sudo systemctl restart mysql.serviceFor MariaDB 10.x:
sudo systemctl restart mariadb.serviceVerify the change: Connect to your database again and confirm the
max_allowed_packetvalue:mysql -u root -p -e "SHOW VARIABLES LIKE 'max_allowed_packet';"The output should now reflect your new, larger value (e.g.,
67108864for 64MB).
2. Adjust PHP-FPM memory_limit (for PHP Applications)
If you're running a PHP application and dealing with large result sets, PHP's memory limit might be the bottleneck.
Determine your PHP version and
php.inilocation: Check the PHP version used by your FPM pool. Common paths on Ubuntu 20.04 are/etc/php/X.X/fpm/php.inifor the FPM handler and/etc/php/X.X/cli/php.inifor command-line scripts.To find the current
memory_limitandphp.inipath for PHP-FPM, you can create aphpinfo.phpfile in your web root (/var/www/html/info.php):<?php phpinfo(); ?>Access
http://your_domain/info.phpin your browser and search formemory_limitandLoaded Configuration File.Alternatively, for the CLI, run:
php -i | grep -E "Loaded Configuration File|memory_limit"Edit
php.ini: Open the appropriatephp.inifile for your PHP-FPM setup (e.g.,/etc/php/8.1/fpm/php.ini):sudo nano /etc/php/8.1/fpm/php.iniFind the
memory_limitdirective and increase its value. A typical starting point for applications dealing with large data might be256Mor512M.; Maximum amount of memory a script may consume (128MB) ; http://php.net/memory-limit memory_limit = 256MRestart PHP-FPM service: After saving the changes, restart the PHP-FPM service to apply them.
sudo systemctl restart php8.1-fpm.service(Replace
php8.1-fpm.servicewith your actual PHP-FPM version, e.g.,php7.4-fpm.service).While
max_allowed_packethandles the size of data exchanged with the database,memory_limitensures PHP has enough memory to process that data after it's received. Both can cause "MySQL server has gone away" if their limits are hit.
3. Review MySQL/MariaDB Server Timeouts (wait_timeout, interactive_timeout)
While not the primary cause of "packet too large," general "MySQL server has gone away" errors can be related to connection timeouts. If your large query takes a very long time, the connection might time out before the query completes.
Check current timeout values:
mysql -u root -p -e "SHOW VARIABLES LIKE 'wait_timeout';" mysql -u root -p -e "SHOW VARIABLES LIKE 'interactive_timeout';"These values are in seconds.
wait_timeoutapplies to non-interactive connections (e.g., web applications), whileinteractive_timeoutapplies to interactive clients (e.g.,mysqlCLI).Adjust timeout values (if necessary): If your queries consistently run longer than these timeouts, you might consider increasing them. Edit the same MySQL/MariaDB configuration file as in Step 1 (e.g.,
/etc/mysql/mariadb.conf.d/50-server.cnf):[mysqld] # ... wait_timeout = 3600 # 1 hour (default is 28800 seconds or 8 hours) interactive_timeout = 3600 # 1 hour (default is 28800 seconds or 8 hours)Restart the MySQL/MariaDB service:
sudo systemctl restart mysql.service # or mariadb.service
4. Client-side max_allowed_packet Configuration (Less Common for Web Apps)
In rare cases, your specific database client or ORM might have its own max_allowed_packet setting or require it to be set explicitly.
For the
mysqlcommand-line client: You can configure this in your user's~/.my.cnffile or the global/etc/mysql/my.cnfunder the[mysql]section:# ~/.my.cnf or /etc/mysql/my.cnf [mysql] max_allowed_packet = 64MThis ensures that when you use the
mysqlclient, it attempts to send/receive larger packets.For application-specific drivers: Consult your application's documentation or the specific database driver you are using (e.g., a Python
mysqlclientconnector, a Node.jsmysqlpackage) to see if there's an option to setmax_allowed_packetat the connection level. Most modern drivers will respect the server'smax_allowed_packetby default, but it's worth checking if issues persist.
5. Optimize Application Queries & Data Handling
The most robust and long-term solution is to optimize your application's database interactions to avoid hitting these packet size limits in the first place.
Break down large
INSERTstatements: Instead of a singleINSERTstatement with thousands of rows, break it into smaller batches. This is more resilient to network issues and less likely to exceed packet limits.-- Instead of: INSERT INTO my_table (col1, col2) VALUES (...), (...), (...), ...; -- Do: INSERT INTO my_table (col1, col2) VALUES (...), (...); INSERT INTO my_table (col1, col2) VALUES (...), (...); -- ... repeat in batchesUse
LOAD DATA INFILEfor bulk imports: For importing very large files (e.g., CSV, TSV),LOAD DATA INFILEis significantly more efficient and handles large datasets better than multipleINSERTstatements.LOAD DATA INFILE '/path/to/your/data.csv' INTO TABLE my_table FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY 'n' IGNORE 1 ROWS;Paginate large
SELECTqueries: When retrieving extensive result sets, implement pagination in your application to fetch data in smaller, manageable chunks. This reduces memory usage on both the server and client.SELECT * FROM my_table LIMIT 100 OFFSET 0; -- First 100 SELECT * FROM my_table LIMIT 100 OFFSET 100; -- Next 100While increasing
max_allowed_packetandmemory_limitcan provide immediate relief, optimizing your application's data handling is crucial for scalability, performance, and long-term stability. Excessive reliance on large packet sizes can indicate an inefficient application design.