From 902ca440262ad20b3d4ebec7f81783f49be1bead Mon Sep 17 00:00:00 2001 From: Jordie <4343468+Jordie0608@users.noreply.github.com> Date: Sat, 1 Jun 2019 03:11:16 +1000 Subject: [PATCH] Queries attempt reconnection on mysql 2006 error (#44144) * queries attempt reconnection on mysql 2006 error * change failed connection cutoff to use timer --- code/controllers/subsystem/dbcore.dm | 32 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index ccbe8dc61ca..462ba609448 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -4,6 +4,7 @@ SUBSYSTEM_DEF(dbcore) wait = 1 MINUTES init_order = INIT_ORDER_DBCORE var/const/FAILED_DB_CONNECTION_CUTOFF = 5 + var/failed_connection_timeout = 0 var/schema_mismatch = 0 var/db_minor = 0 @@ -64,7 +65,11 @@ SUBSYSTEM_DEF(dbcore) if(IsConnected()) return TRUE - if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore. + if(failed_connection_timeout <= world.time) //it's been more than 5 seconds since we failed to connect, reset the counter + failed_connections = 0 + + if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect for 5 seconds. + failed_connection_timeout = world.time + 50 return FALSE if(!CONFIG_GET(flag/sql_enabled)) @@ -323,13 +328,15 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table if(!async) start_time = REALTIMEOFDAY Close() - query = connection.BeginQuery(sql) - if(!async) - timed_out = !query.WaitForCompletion() - else - in_progress = TRUE - UNTIL(query.IsComplete()) - in_progress = FALSE + timed_out = run_query(async) + if(query.GetErrorCode() == 2006) //2006 is the return code for "MySQL server has gone away" time-out error, meaning the connection has been lost to the server (if it's still alive) + log_sql("Executing query encountered returned a lost database connection (2006).") + SSdbcore.Disconnect() + if(SSdbcore.Connect()) //connection was restablished, reattempt the query + log_sql("Connection restablished") + timed_out = run_query(async) + else + log_sql("Executing query failed to restablish database connection.") skip_next_is_complete = TRUE var/error = QDELETED(query) ? "Query object deleted!" : query.GetError() last_error = error @@ -343,6 +350,15 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table log_query_debug("Query used: [sql]") slow_query_check() +/datum/DBQuery/proc/run_query(async) + query = connection.BeginQuery(sql) + if(!async) + . = !query.WaitForCompletion() + else + in_progress = TRUE + UNTIL(query.IsComplete()) + in_progress = FALSE + /datum/DBQuery/proc/slow_query_check() message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]")