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\]")