Opened 5 years ago
Last modified 7 months ago
#5932 assigned enhancement
wpdb should reconnect and retry query when "MySQL server has gone away"
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Priority: | normal | Milestone: | Future Release |
| Component: | Database | Version: | 3.0 |
| Severity: | normal | Keywords: | has-patch early |
| Cc: | andy |
Description
Using 2.3.3, here are the type of errors that crop up in error_log everyday.
[25-Jan-2008 08:37:35] WordPress database error MySQL server has gone away for query UPDATE wp_options SET option_value = '0' WHERE option_name = 'doing_cron' [25-Jan-2008 09:23:19] WordPress database error MySQL server has gone away for query UPDATE wp_options SET option_value = '0' WHERE option_name = 'doing_cron' [26-Jan-2008 00:03:54] WordPress database error MySQL server has gone away for query UPDATE wp_options SET option_value = '0' WHERE option_name = 'doing_cron' [26-Jan-2008 00:04:29] WordPress database error MySQL server has gone away for query SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_pingme' LIMIT 1 [26-Jan-2008 00:04:29] WordPress database error MySQL server has gone away for query SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_encloseme' LIMIT 1 [26-Jan-2008 00:04:29] WordPress database error MySQL server has gone away for query SELECT ID FROM wp_posts WHERE CHAR_LENGTH(TRIM(to_ping)) > 7 AND post_status = 'publish' [26-Jan-2008 00:05:09] WordPress database error MySQL server has gone away for query SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_pingme' LIMIT 1 [26-Jan-2008 00:05:09] WordPress database error MySQL server has gone away for query SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_encloseme' LIMIT 1 [26-Jan-2008 00:05:09] WordPress database error MySQL server has gone away for query SELECT ID FROM wp_posts WHERE CHAR_LENGTH(TRIM(to_ping)) > 7 AND post_status = 'publish' [26-Jan-2008 00:05:47] WordPress database error MySQL server has gone away for query SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_pingme' LIMIT 1 [26-Jan-2008 00:05:47] WordPress database error MySQL server has gone away for query SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_encloseme' LIMIT 1 [26-Jan-2008 00:05:47] WordPress database error MySQL server has gone away for query SELECT ID FROM wp_posts WHERE CHAR_LENGTH(TRIM(to_ping)) > 7 AND post_status = 'publish' .................
Attachments (7)
Change History (27)
comment:1
darkdragon — 5 years ago
- Milestone 2.3.4 deleted
- Resolution set to invalid
- Status changed from new to closed
This plugin is designed to help you deal with the "MySQL Server Has Gone Away" error.
- Cc andy added
- Component changed from General to Database
- Milestone set to Future Release
- Resolution invalid deleted
- Status changed from closed to reopened
- Version changed from 2.3.3 to 3.0
- Summary changed from WordPress database error MySQL server has gone away to wpdb should reconnect and retry query when "MySQL server has gone away"
WordPress should try to recover from certain kinds of errors from MySQL. This error in particular. There has been much written about this error, including variations in PHP versions.
I know errors of that kind from some sites as well, but I assume that this is a configuration issue.
I suggest to close as wontfix or invalid for the moment.
If you know of a configuration that fixes this then it's a configuration issue. Until then, your assumption is no reason to close this ticket.
Typically this error occurs when the mysql client connection has timed out due to inactivity. This is correct behavior and not necessarily within the power of the WP admin to configure.
It is also easy to recover from: identify the error code, reconnect, and retry the query. I have implemented this in wpdb-based scripts that commonly see deadlocks (another recoverable error). A do-while loop works well.
- Keywords reporter-feedback added; database error mysql server removed
Well, I'm willing to pick up the configuration argument.
Please provide steps to reproduce the problem so it's possible to look into this issue with more detail.
Write a script that does one query, then sleeps a while, then does another query. Increase the sleep time until the error appears.
comment:8
gazouteast — 3 years ago
This error also appears when wp_options has hit circa 100,000+ rows (on shared and VPS hosting) - I'm not sure if the limitation is from MySQL or simply a "query taking too long to get answer" issue.
Related - if a SQL table has crashed, MySQL has the ability to return that in the error, WP doesn't seem capable of returning that reason - might be worth a look see to check if could be added to verbosity?
comment:10
pento — 10 months ago
- Keywords has-patch added; reporter-feedback removed
This patch checks the connection whenever wpdb::query() is run. This will add a slight delay to each query (approximately the ping time to the MySQL server).
Here's a testing snippet.
global $wpdb; $wpdb->query( 'SET SESSION wait_timeout = 10;' ); echo $wpdb->get_var( 'select id from wp_posts limit 1;' ); sleep( 12 ); echo $wpdb->get_var( 'select id from wp_posts limit 1,1;' );
comment:11
scribu — 10 months ago
Checking the connection before every single query seems wasteful to me.
Ideally, it would work like this:
- Do query.
- Check some flag that says if the query actually reached the server.
- Re-connect, if needed.
comment:12
pento — 10 months ago
A little wasteful.
I'll have another pass and see what the code looks like when reconnecting after a query failed because the server went away.
comment:13
pento — 10 months ago
Patch 3 does the check after a query fails with error 2006 (server gone away).
I also added a 1 second sleep between connection retries, to give the server 5 seconds to come back.
comment:14
scribu — 10 months ago
- Owner anonymous deleted
- Status changed from reopened to assigned
Now that's more like it. :)
I think the actual connection logic, i.e. mysql_connect() + $this->select() should be moved to a helper method, as it's probably duplicated currently.
comment:15
pento — 10 months ago
Good point, patch 4 makes wpdb::db_connect() more generic so the code duplication can be removed.
Also, the way diff created that patch is kind of weird.
comment:16
nacin — 10 months ago
- Keywords needs-refresh added
- Milestone changed from Future Release to 3.5
- Owner set to pento
I'm game for this.
I discussed with pento how we could clean up check-connection.4.diff's while() loop a bit. Otherwise, looks interesting and good.
comment:17
pento — 10 months ago
- Keywords needs-refresh removed
Cleaned up the loop in wpdb::check_connection(), per discussion with nacin.
comment:18
nacin — 8 months ago
The db_connect() call inside check_connection() doesn't pass $allow_bail = false, as I imagine it is supposed to.
comment:19
pento — 8 months ago
New patch adds the correct parameter, updated to patch cleanly against trunk.
comment:20
scribu — 7 months ago
- Keywords early added
- Milestone changed from 3.5 to Future Release
- Type changed from defect (bug) to enhancement
I think it's too late in the cycle to mess with such a critical component.

Not a WordPress error. Please check the mysql server settings to increase either the timeout or the amount of connections that can be made to the mysql server. If you are on a shared host, then consider either WP-Cache or WP Super Cache.