diff options
-rw-r--r-- | conf/inter-server.conf | 12 | ||||
-rw-r--r-- | src/common/core.c | 2 | ||||
-rw-r--r-- | src/common/sql.c | 74 | ||||
-rw-r--r-- | src/common/sql.h | 1 |
4 files changed, 88 insertions, 1 deletions
diff --git a/conf/inter-server.conf b/conf/inter-server.conf index 70bf80e5c..523437007 100644 --- a/conf/inter-server.conf +++ b/conf/inter-server.conf @@ -56,6 +56,18 @@ log_db_db: ragnarok log_codepage: log_login_db: loginlog +// == MySQL Reconnect Settings +// =========================== +// - mysql_reconnect_type +// - 1: when mysql disconnects during runtime, the server tries to reconnect mysql_reconnect_count times and, +// -- if unsuccessful, the server is shut down +// - 2: when mysql disconnects during runtime it tries to reconnect indefinitely +mysql_reconnect_type:2 +// - mysql_reconnect_count +// - number of reconnect attempts the server should do when the database disconnects during runtime +// - only used when mysql_reconnect_type is 1 +mysql_reconnect_count:1 + // DO NOT CHANGE ANYTHING BEYOND THIS LINE UNLESS YOU KNOW YOUR DATABASE DAMN WELL // this is meant for people who KNOW their stuff, and for some reason want to change their // database layout. [CLOWNISIUS] diff --git a/src/common/core.c b/src/common/core.c index 1e3dbb3d7..bb536a255 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -11,6 +11,7 @@ #include "../common/timer.h" #include "../common/thread.h" #include "../common/mempool.h" +#include "../common/sql.h" #endif #include <stdio.h> @@ -319,6 +320,7 @@ int main (int argc, char **argv) display_title(); usercheck(); + Sql_Init(); rathread_init(); mempool_init(); db_init(); diff --git a/src/common/sql.c b/src/common/sql.c index 800aa89b0..96346d68c 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -15,7 +15,10 @@ #include <string.h>// strlen/strnlen/memcpy/memset #include <stdlib.h>// strtoul +void hercules_mysql_error_handler(unsigned int ecode); +int mysql_reconnect_type; +int mysql_reconnect_count; /// Sql handle struct Sql @@ -74,7 +77,7 @@ Sql* Sql_Malloc(void) self->lengths = NULL; self->result = NULL; self->keepalive = INVALID_TIMER; - + self->handle.reconnect = 1; return self; } @@ -266,12 +269,14 @@ int Sql_QueryV(Sql* self, const char* query, va_list args) if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); + hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } self->result = mysql_store_result(&self->handle); if( mysql_errno(&self->handle) != 0 ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); + hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } return SQL_SUCCESS; @@ -291,12 +296,14 @@ int Sql_QueryStr(Sql* self, const char* query) if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); + hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } self->result = mysql_store_result(&self->handle); if( mysql_errno(&self->handle) != 0 ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); + hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } return SQL_SUCCESS; @@ -639,6 +646,7 @@ int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args) if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_params = false; @@ -660,6 +668,7 @@ int SqlStmt_PrepareStr(SqlStmt* self, const char* query) if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_params = false; @@ -721,12 +730,14 @@ int SqlStmt_Execute(SqlStmt* self) mysql_stmt_execute(self->stmt) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_columns = false; if( mysql_stmt_store_result(self->stmt) )// store all the data { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } @@ -868,6 +879,7 @@ int SqlStmt_NextRow(SqlStmt* self) if( err ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); + hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } @@ -946,3 +958,63 @@ void SqlStmt_Free(SqlStmt* self) aFree(self); } } +/* receives mysql error codes during runtime (not on first-time-connects) */ +void hercules_mysql_error_handler(unsigned int ecode) { + static unsigned int retry = 1; + switch( ecode ) { + case 2003:/* Can't connect to MySQL (this error only happens here when failing to reconnect) */ + if( mysql_reconnect_type == 1 ) { + if( ++retry > mysql_reconnect_count ) { + ShowFatalError("MySQL has been unreachable for too long, %d reconnects were attempted. Shutting Down\n", retry); + exit(EXIT_FAILURE); + } + } + break; + } +} +void Sql_inter_server_read(const char* cfgName, bool first) { + int i; + char line[1024], w1[1024], w2[1024]; + FILE* fp; + + fp = fopen(cfgName, "r"); + if(fp == NULL) { + if( first ) { + ShowFatalError("File not found: %s\n", cfgName); + exit(EXIT_FAILURE); + } else + ShowError("File not found: %s\n", cfgName); + return; + } + + while(fgets(line, sizeof(line), fp)) { + i = sscanf(line, "%[^:]: %[^\r\n]", w1, w2); + if(i != 2) + continue; + + if(!strcmpi(w1,"mysql_reconnect_type")) { + mysql_reconnect_type = atoi(w2); + switch( mysql_reconnect_type ) { + case 1: + case 2: + break; + default: + ShowError("%s::mysql_reconnect_type is set to %d which is not valid, defaulting to 1...\n", cfgName, mysql_reconnect_type); + mysql_reconnect_type = 1; + break; + } + } else if(!strcmpi(w1,"mysql_reconnect_count")) { + mysql_reconnect_count = atoi(w2); + if( mysql_reconnect_count < 1 ) + mysql_reconnect_count = 1; + } else if(!strcmpi(w1,"import")) + Sql_inter_server_read(w2,false); + } + fclose(fp); + + return; +} + +void Sql_Init(void) { + Sql_inter_server_read("conf/inter-server.conf",true); +} diff --git a/src/common/sql.h b/src/common/sql.h index 898e2c778..a9d8c6136 100644 --- a/src/common/sql.h +++ b/src/common/sql.h @@ -339,6 +339,7 @@ void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned lo /// Frees a SqlStmt returned by SqlStmt_Malloc. void SqlStmt_Free(SqlStmt* self); +void Sql_Init(void); #endif /* _COMMON_SQL_H_ */ |