@@ -34,7 +34,7 @@ class InfoLoggerDispatchSQLImpl
3434 int customMessageProcess (std::shared_ptr<InfoLoggerMessageList> msg);
3535
3636 private:
37- MYSQL db; // handle to mysql db
37+ MYSQL *db = NULL ; // handle to mysql db
3838 MYSQL_STMT* stmt = NULL ; // prepared insertion query
3939 MYSQL_BIND bind[INFOLOG_FIELDS_MAX]; // parameters bound to variables
4040
@@ -50,6 +50,7 @@ class InfoLoggerDispatchSQLImpl
5050 unsigned long long msgDroppedCount = 0 ; // counter for number of messages dropped (DB unavailable, etc)
5151
5252 int connectDB (); // function to connect to database
53+ int disconnectDB (); // disconnect/cleanup DB connection
5354};
5455
5556void InfoLoggerDispatchSQLImpl::start ()
@@ -58,12 +59,6 @@ void InfoLoggerDispatchSQLImpl::start()
5859 // log DB params
5960 theLog->info (" Using DB %s@%s:%s" , theConfig->dbUser .c_str (), theConfig->dbHost .c_str (), theConfig->dbName .c_str ());
6061
61- // init mysql lib
62- if (mysql_init (&db) == NULL ) {
63- theLog->error (" mysql_init() failed" );
64- throw __LINE__;
65- }
66-
6762 // prepare insert query from 1st protocol definition
6863 // e.g. INSERT INTO messages(severity,level,timestamp,hostname,rolename,pid,username,system,facility,detector,partition,run,errcode,errLine,errsource) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) */
6964 nFields = 0 ;
@@ -118,11 +113,7 @@ InfoLoggerDispatchSQL::InfoLoggerDispatchSQL(ConfigInfoLoggerServer* config, Sim
118113
119114void InfoLoggerDispatchSQLImpl::stop ()
120115{
121- if (dbIsConnected) {
122- mysql_stmt_close (stmt);
123- theLog->info (" DB disconnected" );
124- }
125- mysql_close (&db);
116+ disconnectDB ();
126117 theLog->info (" DB thread insert count = %llu, dropped msg count = %llu" , insertCount, msgDroppedCount);
127118}
128119
@@ -150,27 +141,39 @@ int InfoLoggerDispatchSQLImpl::connectDB()
150141 return 1 ;
151142 }
152143 dbLastConnectTry = now;
153- if (mysql_real_connect (&db, theConfig->dbHost .c_str (), theConfig->dbUser .c_str (), theConfig->dbPassword .c_str (), theConfig->dbName .c_str (), 0 , NULL , 0 )) {
144+
145+ if (db == NULL ) {
146+ // init mysql handle
147+ db = mysql_init (db);
148+ if (db == NULL ) {
149+ theLog->error (" mysql_init() failed" );
150+ return 1 ;
151+ }
152+ }
153+
154+ if (mysql_real_connect (db, theConfig->dbHost .c_str (), theConfig->dbUser .c_str (), theConfig->dbPassword .c_str (), theConfig->dbName .c_str (), 0 , NULL , 0 )) {
154155 theLog->info (" DB connected" );
155156 dbIsConnected = 1 ;
156157 dbConnectTrials = 0 ;
157158 } else {
158159 if (dbConnectTrials == 0 ) { // log only first attempt
159- theLog->error (" DB connection failed: %s" , mysql_error (& db));
160+ theLog->error (" DB connection failed: %s" , mysql_error (db));
160161 }
161162 dbConnectTrials++;
162163 return 1 ;
163164 }
164165
165166 // create prepared insert statement
166- stmt = mysql_stmt_init (& db);
167+ stmt = mysql_stmt_init (db);
167168 if (stmt == NULL ) {
168- theLog->error (" mysql_stmt_init() failed: %s" , mysql_error (&db));
169+ theLog->error (" mysql_stmt_init() failed: %s" , mysql_error (db));
170+ disconnectDB ();
169171 return -1 ;
170172 }
171173
172174 if (mysql_stmt_prepare (stmt, sql_insert.c_str (), sql_insert.length ())) {
173- theLog->error (" mysql_stmt_prepare() failed: %s\n " , mysql_error (&db));
175+ theLog->error (" mysql_stmt_prepare() failed: %s" , mysql_error (db));
176+ disconnectDB ();
174177 return -1 ;
175178 }
176179
@@ -195,13 +198,31 @@ int InfoLoggerDispatchSQLImpl::connectDB()
195198 }
196199 }
197200 if (errline) {
201+ disconnectDB ();
198202 return -1 ;
199203 }
200204 }
201205
202206 return 0 ;
203207}
204208
209+ int InfoLoggerDispatchSQLImpl::disconnectDB ()
210+ {
211+ if (stmt != NULL ) {
212+ mysql_stmt_close (stmt);
213+ stmt = NULL ;
214+ }
215+ if (db != NULL ) {
216+ mysql_close (db);
217+ db = NULL ;
218+ }
219+ if (dbIsConnected) {
220+ theLog->info (" DB disconnected" );
221+ }
222+ dbIsConnected = 0 ;
223+ return 0 ;
224+ }
225+
205226int InfoLoggerDispatchSQLImpl::customLoop ()
206227{
207228 int err = connectDB ();
@@ -266,24 +287,19 @@ int InfoLoggerDispatchSQLImpl::customMessageProcess(std::shared_ptr<InfoLoggerMe
266287
267288 // update bind variables
268289 if (mysql_stmt_bind_param (stmt, bind)) {
269- theLog->error (" mysql_stmt_bind() failed: %s\n " , mysql_error (&db));
270- mysql_stmt_close (stmt);
271- mysql_close (&db);
272- theLog->info (" DB disconnected" );
290+ theLog->error (" mysql_stmt_bind() failed: %s" , mysql_error (db));
291+ disconnectDB ();
273292 msgDroppedCount++;
274293 return -1 ;
275294 }
276295
277296 // Do the insertion
278297 if (mysql_stmt_execute (stmt)) {
279- theLog->error (" mysql_stmt_exec() failed: %s\n " , mysql_error (&db));
280- mysql_stmt_close (stmt);
281- mysql_close (&db);
282- theLog->info (" DB disconnected" );
298+ theLog->error (" mysql_stmt_exec() failed: %s" , mysql_error (db));
283299 // retry with new connection - usually it means server was down
284- dbIsConnected = 0 ;
300+ disconnectDB () ;
285301 msgDroppedCount++;
286- break ;
302+ return - 1 ;
287303 }
288304
289305 insertCount++;
0 commit comments