X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fpostgresql.c;h=e46a47110ad7978d5154796aaed4d7b0dbefea2c;hb=6518cae7c97b5bb1ac3e1d1eca841fe41b5cb656;hp=15d4666b9eaf910c2d91f80ce2552291eb9d6e45;hpb=5131a49ad0584aa22282aacf72b6e4ca75356bae;p=collectd.git diff --git a/src/postgresql.c b/src/postgresql.c index 15d4666b..e46a4711 100644 --- a/src/postgresql.c +++ b/src/postgresql.c @@ -170,14 +170,14 @@ static char *def_queries[] = { }; static int def_queries_num = STATIC_ARRAY_SIZE (def_queries); -static c_psql_database_t *databases = NULL; -static size_t databases_num = 0; +static c_psql_database_t **databases = NULL; +static size_t databases_num = 0; -static udb_query_t **queries = NULL; -static size_t queries_num = 0; +static udb_query_t **queries = NULL; +static size_t queries_num = 0; -static c_psql_writer_t *writers = NULL; -static size_t writers_num = 0; +static c_psql_writer_t *writers = NULL; +static size_t writers_num = 0; static int c_psql_begin (c_psql_database_t *db) { @@ -220,17 +220,25 @@ static int c_psql_commit (c_psql_database_t *db) static c_psql_database_t *c_psql_database_new (const char *name) { - c_psql_database_t *db; + c_psql_database_t **tmp; + c_psql_database_t *db; - db = (c_psql_database_t *)realloc (databases, - (databases_num + 1) * sizeof (*db)); + db = (c_psql_database_t *)malloc (sizeof(*db)); if (NULL == db) { log_err ("Out of memory."); return NULL; } - databases = db; - db = databases + databases_num; + tmp = (c_psql_database_t **)realloc (databases, + (databases_num + 1) * sizeof (*databases)); + if (NULL == tmp) { + log_err ("Out of memory."); + sfree (db); + return NULL; + } + + databases = tmp; + databases[databases_num] = db; ++databases_num; db->conn = NULL; @@ -324,7 +332,9 @@ static void c_psql_database_delete (void *data) sfree (db->service); /* don't care about freeing or reordering the 'databases' array - * this is done in 'shutdown' */ + * this is done in 'shutdown'; also, don't free the database instance + * object just to make sure that in case anybody accesses it before + * shutdown won't segfault */ return; } /* c_psql_database_delete */ @@ -371,9 +381,6 @@ static int c_psql_check_connection (c_psql_database_t *db) c_psql_connect (db); } - /* "ping" */ - PQclear (PQexec (db->conn, "SELECT 42;")); - if (CONNECTION_OK != PQstatus (db->conn)) { PQreset (db->conn); @@ -514,6 +521,12 @@ static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q, if (PGRES_TUPLES_OK != PQresultStatus (res)) { pthread_mutex_lock (&db->db_lock); + if ((CONNECTION_OK != PQstatus (db->conn)) + && (0 == c_psql_check_connection (db))) { + PQclear (res); + return c_psql_exec_query (db, q, prep_area); + } + log_err ("Failed to execute SQL query: %s", PQerrorMessage (db->conn)); log_info ("SQL query was: %s", @@ -762,7 +775,7 @@ static char *values_to_sqlarray (const data_set_t *ds, const value_list_t *vl, if (ds->ds[i].type == DS_TYPE_GAUGE) status = ssnprintf (str_ptr, str_len, - ",%f", vl->values[i].gauge); + ","GAUGE_FORMAT, vl->values[i].gauge); else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); @@ -900,10 +913,10 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl, if ((PGRES_COMMAND_OK != PQresultStatus (res)) && (PGRES_TUPLES_OK != PQresultStatus (res))) { + PQclear (res); + if ((CONNECTION_OK != PQstatus (db->conn)) && (0 == c_psql_check_connection (db))) { - PQclear (res); - /* try again */ res = PQexecParams (db->conn, writer->statement, STATIC_ARRAY_SIZE (params), NULL, @@ -912,6 +925,7 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl, if ((PGRES_COMMAND_OK == PQresultStatus (res)) || (PGRES_TUPLES_OK == PQresultStatus (res))) { + PQclear (res); success = 1; continue; } @@ -932,6 +946,8 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl, pthread_mutex_unlock (&db->db_lock); return -1; } + + PQclear (res); success = 1; } @@ -953,17 +969,17 @@ static int c_psql_flush (cdtime_t timeout, __attribute__((unused)) const char *ident, user_data_t *ud) { - c_psql_database_t *dbs = databases; + c_psql_database_t **dbs = databases; size_t dbs_num = databases_num; size_t i; if ((ud != NULL) && (ud->data != NULL)) { - dbs = ud->data; + dbs = (void *)&ud->data; dbs_num = 1; } for (i = 0; i < dbs_num; ++i) { - c_psql_database_t *db = dbs + i; + c_psql_database_t *db = dbs[i]; /* don't commit if the timeout is larger than the regular commit * interval as in that case all requested data has already been @@ -983,7 +999,7 @@ static int c_psql_shutdown (void) plugin_unregister_read_group ("postgresql"); for (i = 0; i < databases_num; ++i) { - c_psql_database_t *db = databases + i; + c_psql_database_t *db = databases[i]; if (db->writers_num > 0) { char cb_name[DATA_MAX_NAME_LEN]; @@ -998,6 +1014,8 @@ static int c_psql_shutdown (void) plugin_unregister_flush (cb_name); plugin_unregister_write (cb_name); } + + sfree (db); } udb_query_free (queries, queries_num); @@ -1024,17 +1042,19 @@ static int config_query_param_add (udb_query_t *q, oconfig_item_t *ci) data = udb_query_get_user_data (q); if (NULL == data) { - data = (c_psql_user_data_t *) smalloc (sizeof (*data)); + data = malloc (sizeof (*data)); if (NULL == data) { log_err ("Out of memory."); return -1; } memset (data, 0, sizeof (*data)); data->params = NULL; + data->params_num = 0; + + udb_query_set_user_data (q, data); } - tmp = (c_psql_param_t *) realloc (data->params, - (data->params_num + 1) * sizeof (c_psql_param_t)); + tmp = realloc (data->params, (data->params_num + 1) * sizeof (*data->params)); if (NULL == tmp) { log_err ("Out of memory."); return -1; @@ -1058,8 +1078,6 @@ static int config_query_param_add (udb_query_t *q, oconfig_item_t *ci) } data->params_num++; - udb_query_set_user_data (q, data); - return (0); } /* config_query_param_add */ @@ -1143,7 +1161,7 @@ static int c_psql_config_writer (oconfig_item_t *ci) writers = tmp; writer = writers + writers_num; - ++writers_num; + memset (writer, 0, sizeof (*writer)); writer->name = sstrdup (ci->values[0].value.string); writer->statement = NULL; @@ -1163,10 +1181,10 @@ static int c_psql_config_writer (oconfig_item_t *ci) if (status != 0) { sfree (writer->statement); sfree (writer->name); - sfree (writer); return status; } + ++writers_num; return 0; } /* c_psql_config_writer */