Procházet zdrojové kódy

- reordered included header files for better detection of missing headers
- disable automatic database reconnects, they do not work with pre-compiled
statements
- error/info/log message cleanup
- auto_reconnect module parameter removed
- introduced new module parameter retries which controls the number of
times queries are tried to execute on server on failures

Jan Janak před 17 roky
rodič
revize
a201f9aee7

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 269 - 347
modules/db_mysql/my_cmd.c


+ 13 - 13
modules/db_mysql/my_cmd.h

@@ -36,24 +36,24 @@
 struct my_cmd {
 	db_drv_t gen;
 
-	str query;
+	str sql_cmd; /**< Database command represented in SQL language */
 	int next_flag;
-	MYSQL_STMT* st;
+	MYSQL_STMT* st; /**< MySQL pre-compiled statement handle */
+
+	/** This is the sequential number of the last
+	 * connection reset last time the command was
+	 * uploaded to the server. If the reset number
+	 * in the corresponding my_con structure is higher
+	 * than the number in this variable then we need
+	 * to upload the command again, because the
+	 * the connection was reconnected meanwhile.
+	 */
+	unsigned int last_reset;
 };
 
 int my_cmd(db_cmd_t* cmd);
 
-/* Runtime execution function for DB_GET */
-int my_cmd_read(db_res_t* res, db_cmd_t* cmd);
-
-/* Runtime execution function for DB_PUT and DB_DEL */
-int my_cmd_write(db_res_t* res, db_cmd_t* cmd);
-
-/* Runtime execution function for DB_UPD */
-int my_cmd_update(db_res_t* res, db_cmd_t* cmd);
-
-/* Raw SQL query */
-int my_cmd_sql(db_res_t* res, db_cmd_t* cmd);
+int my_cmd_exec(db_res_t* res, db_cmd_t* cmd);
 
 int my_cmd_first(db_res_t* res);
 

+ 32 - 35
modules/db_mysql/my_con.c

@@ -26,14 +26,17 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "my_con.h"
+
+#include "mysql_mod.h"
+#include "my_uri.h"
+
 #include "../../mem/mem.h"
 #include "../../dprint.h"
 #include "../../ut.h"
+
 #include <string.h>
 #include <time.h>
-#include "mysql_mod.h"
-#include "my_uri.h"
-#include "my_con.h"
 
 
 /*
@@ -47,45 +50,34 @@ static void my_con_free(db_con_t* con, struct my_con* payload)
 	 * to it in the connection pool
 	 */
 	if (db_pool_remove((db_pool_entry_t*)payload) == 0) return;
-
+	
 	db_pool_entry_free(&payload->gen);
 	if (payload->con) pkg_free(payload->con);
 	pkg_free(payload);
 }
 
 
-static int my_con_connect(db_con_t* con)
+int my_con_connect(db_con_t* con)
 {
 	struct my_con* mcon;
 	struct my_uri* muri;
-#if MYSQL_VERSION_ID >= 50013 
-	my_bool my_auto_reconnect;
-#endif
-
-
+	
 	mcon = DB_GET_PAYLOAD(con);
 	muri = DB_GET_PAYLOAD(con->uri);
-
+	
 	/* Do not reconnect already connected connections */
 	if (mcon->flags & MY_CONNECTED) return 0;
 
-	DBG("my_con_connect: Connecting to %.*s:%.*s\n",
+	DBG("mysql: Connecting to %.*s:%.*s\n",
 		con->uri->scheme.len, ZSW(con->uri->scheme.s),
 		con->uri->body.len, ZSW(con->uri->body.s));
 
-#if MYSQL_VERSION_ID >= 50013 
-	my_auto_reconnect = 1;
-	if (my_client_ver >= 50013) {
-		if (mysql_options(mcon->con, MYSQL_OPT_RECONNECT , 
-						  (char*)&my_auto_reconnect))
-			WARN("mysql: failed to set MYSQL_OPT_RECONNECT\n");
-	}
-#endif
 	if (my_connect_to) {
 		if (mysql_options(mcon->con, MYSQL_OPT_CONNECT_TIMEOUT, 
 						  (char*)&my_connect_to))
 			WARN("mysql: failed to set MYSQL_OPT_CONNECT_TIMEOUT\n");
 	}
+
 #if MYSQL_VERSION_ID >= 40101 
 	if ((my_client_ver >= 50025) || 
 		((my_client_ver >= 40122) && 
@@ -105,24 +97,29 @@ static int my_con_connect(db_con_t* con)
 	
 	if (!mysql_real_connect(mcon->con, muri->host, muri->username, 
 							muri->password, muri->database, muri->port, 0, 0)) {
-		LOG(L_ERR, "my_con_connect: %s\n", mysql_error(mcon->con));
+		LOG(L_ERR, "mysql: %s\n", mysql_error(mcon->con));
 		return -1;
 	}
 	
-	/* Enable reconnection explicitly */
-	mcon->con->reconnect = 1;
-	
-	DBG("my_con_connect: Connection type is %s\n", mysql_get_host_info(mcon->con));
-	DBG("my_con_connect: Protocol version is %d\n", mysql_get_proto_info(mcon->con));
-	DBG("my_con_connect: Server version is %s\n", mysql_get_server_info(mcon->con));
+	DBG("mysql: Connection type is %s\n", mysql_get_host_info(mcon->con));
+	DBG("mysql: Protocol version is %d\n", mysql_get_proto_info(mcon->con));
+	DBG("mysql: Server version is %s\n", mysql_get_server_info(mcon->con));
 
-	mcon->timestamp = time(0);
 	mcon->flags |= MY_CONNECTED;
+
+	/* Increase the variable that keeps track of number of connects performed
+	 * on this connection. The mysql module uses the variable to determine
+	 * when a pre-compiled command needs to be uploaded to the server again.
+	 * If the number in the my_con structure is large than the number kept
+	 * in my_cmd then it means that we have to upload the command to the server
+	 * again because the connection was reconnected meanwhile.
+	 */
+	mcon->resets++;
 	return 0;
 }
 
 
-static void my_con_disconnect(db_con_t* con)
+void my_con_disconnect(db_con_t* con)
 {
 	struct my_con* mcon;
 
@@ -130,7 +127,7 @@ static void my_con_disconnect(db_con_t* con)
 
 	if ((mcon->flags & MY_CONNECTED) == 0) return;
 
-	DBG("my_con_disconnect: Disconnecting from %.*s:%.*s\n",
+	DBG("mysql: Disconnecting from %.*s:%.*s\n",
 		con->uri->scheme.len, ZSW(con->uri->scheme.s),
 		con->uri->body.len, ZSW(con->uri->body.s));
 
@@ -149,7 +146,7 @@ int my_con(db_con_t* con)
 	 */
 	ptr = (struct my_con*)db_pool_get(con->uri);
 	if (ptr) {
-		DBG("my_con: Connection to %.*s:%.*s found in connection pool\n",
+		DBG("mysql: Connection to %.*s:%.*s found in connection pool\n",
 			con->uri->scheme.len, ZSW(con->uri->scheme.s),
 			con->uri->body.len, ZSW(con->uri->body.s));
 		goto found;
@@ -157,7 +154,7 @@ int my_con(db_con_t* con)
 
 	ptr = (struct my_con*)pkg_malloc(sizeof(struct my_con));
 	if (!ptr) {
-		LOG(L_ERR, "my_con: No memory left\n");
+		LOG(L_ERR, "mysql: No memory left\n");
 		goto error;
 	}
 	memset(ptr, '\0', sizeof(struct my_con));
@@ -165,19 +162,19 @@ int my_con(db_con_t* con)
 
 	ptr->con = (MYSQL*)pkg_malloc(sizeof(MYSQL));
 	if (!ptr->con) {
-		LOG(L_ERR, "my_con: No enough memory\n");
+		LOG(L_ERR, "mysql: No enough memory\n");
 		goto error;
 	}
 	mysql_init(ptr->con);
 
 	uri = DB_GET_PAYLOAD(con->uri);
-	DBG("my_con: Creating new connection to: %.*s:%.*s\n",
+	DBG("mysql: Creating new connection to: %.*s:%.*s\n",
 		con->uri->scheme.len, ZSW(con->uri->scheme.s),
 		con->uri->body.len, ZSW(con->uri->body.s));
 
 	/* Put the newly created mysql connection into the pool */
 	db_pool_put((struct db_pool_entry*)ptr);
-	DBG("my_con: Connection stored in connection pool\n");
+	DBG("mysql: Connection stored in connection pool\n");
 
  found:
 	/* Attach driver payload to the db_con structure and set connect and

+ 13 - 3
modules/db_mysql/my_con.h

@@ -40,14 +40,21 @@ enum my_flags {
 	MY_CONNECTED = 1
 };
 
-struct my_con {
+typedef struct my_con {
 	/* Generic part of the structure */
 	db_pool_entry_t gen;
 
 	MYSQL* con;
 	unsigned int flags;
-	time_t timestamp;
-};
+	
+	/* We keep the number of connection resets in this variable,
+	 * this variable is incremented each time the module performs
+	 * a re-connect on the connection. This is used by my_cmd
+	 * related functions to check if a pre-compiled command needs
+	 * to be uploaded to the server before executing it.
+	 */
+	unsigned int resets;
+} my_con_t;
 
 
 /*
@@ -56,4 +63,7 @@ struct my_con {
  */
 int my_con(db_con_t* con);
 
+int my_con_connect(db_con_t* con);
+void my_con_disconnect(db_con_t* con);
+
 #endif /* _MY_CON_H */

+ 5 - 3
modules/db_mysql/my_fld.c

@@ -26,11 +26,13 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <string.h>
+#include "my_fld.h"
+
 #include "../../mem/mem.h"
 #include "../../dprint.h"
 #include "../../db/db_gen.h"
-#include "my_fld.h"
+
+#include <string.h>
 
 
 static void my_fld_free(db_fld_t* fld, struct my_fld* payload)
@@ -48,7 +50,7 @@ int my_fld(db_fld_t* fld, char* table)
 
 	res = (struct my_fld*)pkg_malloc(sizeof(struct my_fld));
 	if (res == NULL) {
-		ERR("No memory left\n");
+		ERR("mysql: No memory left\n");
 		return -1;
 	}
 	memset(res, '\0', sizeof(struct my_fld));

+ 9 - 5
modules/db_mysql/my_res.c

@@ -26,12 +26,15 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <mysql/mysql.h>
+#include "my_res.h"
+
+#include "my_cmd.h"
+
 #include "../../mem/mem.h"
 #include "../../dprint.h"
 #include "../../db/db_gen.h"
-#include "my_cmd.h"
-#include "my_res.h"
+
+#include <mysql/mysql.h>
 
 
 void my_res_free(db_res_t* res, struct my_res* payload)
@@ -41,7 +44,8 @@ void my_res_free(db_res_t* res, struct my_res* payload)
 	mcmd = DB_GET_PAYLOAD(res->cmd);
 
 	if (mcmd->st && mysql_stmt_free_result(mcmd->st)) {
-		ERR("Error while freeing MySQL result: %s\n", mysql_stmt_error(mcmd->st));
+		ERR("mysql: Error while freeing MySQL result: %d, %s\n", 
+			mysql_stmt_errno(mcmd->st), mysql_stmt_error(mcmd->st));
 	}
 
 	db_drv_free(&payload->gen);
@@ -60,7 +64,7 @@ int my_res(db_res_t* res)
 
 	mr = (struct my_res*)pkg_malloc(sizeof(struct my_res));
 	if (mr == NULL) {
-		ERR("No memory left\n");
+		ERR("mysql: No memory left\n");
 		return -1;
 	}
 	if (db_drv_init(&mr->gen, my_res_free) < 0) goto error;

+ 6 - 4
modules/db_mysql/my_uri.c

@@ -28,13 +28,15 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <stdlib.h>
-#include <string.h>
+#include "my_uri.h"
+
 #include "../../dprint.h"
 #include "../../mem/mem.h"
 #include "../../ut.h"
 #include "../../db/db_gen.h"
-#include "my_uri.h"
+
+#include <stdlib.h>
+#include <string.h>
 
 
 /* compare s1 & s2  with a function f (which should return 0 if ==);
@@ -259,7 +261,7 @@ int my_uri(db_uri_t* uri)
 
 	res = (struct my_uri*)pkg_malloc(sizeof(struct my_uri));
 	if (res == NULL) {
-		ERR("No memory left\n");
+		ERR("mysql: No memory left\n");
 		goto error;
 	}
 	memset(res, '\0', sizeof(struct my_uri));

+ 23 - 21
modules/db_mysql/mysql_mod.c

@@ -37,20 +37,22 @@
  *  @{
  */
  
-#include "../../sr_module.h"
-#include "../../db/db.h"
+#include "mysql_mod.h"
+
 #include "my_uri.h"
 #include "my_con.h"
 #include "my_cmd.h"
 #include "my_fld.h"
 #include "my_res.h"
-#include "mysql_mod.h"
 
-int ping_interval = 5 * 60; /* Default is 5 minutes */
-int auto_reconnect = 1;     /* Default is enabled */
+#include "../../sr_module.h"
+#include "../../db/db.h"
+
+int my_ping_interval = 5 * 60; /* Default is 5 minutes */
 unsigned int my_connect_to = 2; /* 2 s by default */
 unsigned int my_send_to = 0; /*  enabled only for mysql >= 5.25  */
 unsigned int my_recv_to = 0; /* enabled only for mysql >= 5.25 */
+unsigned int my_retries = 1;    /* Number of retries when command fails */
 
 unsigned long my_client_ver = 0;
 
@@ -66,19 +68,19 @@ MODULE_VERSION
  * MySQL database module interface
  */
 static cmd_export_t cmds[] = {
-	{"db_ctx",         (cmd_function)NULL,  0, 0, 0},
-	{"db_con",         (cmd_function)my_con,  0, 0, 0},
-	{"db_uri",         (cmd_function)my_uri,  0, 0, 0},
-	{"db_cmd",         (cmd_function)my_cmd,  0, 0, 0},
-	{"db_put",         (cmd_function)my_cmd_write, 0, 0, 0},
-	{"db_del",         (cmd_function)my_cmd_write, 0, 0, 0},
-	{"db_get",         (cmd_function)my_cmd_read, 0, 0, 0},
-	{"db_upd",         (cmd_function)my_cmd_update, 0, 0, 0},
-	{"db_sql",         (cmd_function)my_cmd_sql, 0, 0, 0},
-	{"db_res",         (cmd_function)my_res,  0, 0, 0},
-	{"db_fld",         (cmd_function)my_fld,  0, 0, 0},
-	{"db_first",       (cmd_function)my_cmd_first, 0, 0, 0},
-	{"db_next",        (cmd_function)my_cmd_next,  0, 0, 0},
+	{"db_ctx",   (cmd_function)NULL,  0, 0, 0},
+	{"db_con",   (cmd_function)my_con,  0, 0, 0},
+	{"db_uri",   (cmd_function)my_uri,  0, 0, 0},
+	{"db_cmd",   (cmd_function)my_cmd,  0, 0, 0},
+	{"db_put",   (cmd_function)my_cmd_exec, 0, 0, 0},
+	{"db_del",   (cmd_function)my_cmd_exec, 0, 0, 0},
+	{"db_get",   (cmd_function)my_cmd_exec, 0, 0, 0},
+	{"db_upd",   (cmd_function)my_cmd_exec, 0, 0, 0},
+	{"db_sql",   (cmd_function)my_cmd_exec, 0, 0, 0},
+	{"db_res",   (cmd_function)my_res,  0, 0, 0},
+	{"db_fld",   (cmd_function)my_fld,  0, 0, 0},
+	{"db_first", (cmd_function)my_cmd_first, 0, 0, 0},
+	{"db_next",  (cmd_function)my_cmd_next,  0, 0, 0},
 	{0, 0, 0, 0, 0}
 };
 
@@ -87,11 +89,11 @@ static cmd_export_t cmds[] = {
  * Exported parameters
  */
 static param_export_t params[] = {
-	{"ping_interval", PARAM_INT, &ping_interval},
-	{"auto_reconnect", PARAM_INT, &auto_reconnect},
+	{"ping_interval",   PARAM_INT, &my_ping_interval},
 	{"connect_timeout", PARAM_INT, &my_connect_to},
-	{"send_timeout", PARAM_INT, &my_send_to},
+	{"send_timeout",    PARAM_INT, &my_send_to},
 	{"receive_timeout", PARAM_INT, &my_recv_to},
+	{"retries",         PARAM_INT, &my_retries},
 	{0, 0, 0}
 };
 

+ 3 - 4
modules/db_mysql/mysql_mod.h

@@ -40,14 +40,13 @@
  *  @ingroup DB-API
  */
 /** @{ */
-extern int ping_interval;
-extern int auto_reconnect;
-
+extern int my_ping_interval;
 extern unsigned int my_connect_to;
 extern unsigned int my_send_to;
 extern unsigned int my_recv_to;
-
 extern unsigned long my_client_ver;
+extern unsigned int my_retries;
+
 /** @} */
 
 #endif /* _MYSQL_MOD_H */

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů