summaryrefslogtreecommitdiffabout
path: root/src/mysqlstat.c
Side-by-side diff
Diffstat (limited to 'src/mysqlstat.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/mysqlstat.c220
1 files changed, 149 insertions, 71 deletions
diff --git a/src/mysqlstat.c b/src/mysqlstat.c
index 938439a..2ffd0dd 100644
--- a/src/mysqlstat.c
+++ b/src/mysqlstat.c
@@ -56,18 +56,22 @@ mysqlstat_connect(void)
{
- struct mysqlstat_connection *conn;
+ static struct mysqlstat_connection *conn;
my_bool t = 1;
- conn = xcalloc(1, sizeof(*conn));
- mysql_init(&conn->mysql);
- if (access(config_file, F_OK) == 0)
- mysql_options(&conn->mysql, MYSQL_READ_DEFAULT_FILE,
- config_file);
- mysql_options(&conn->mysql, MYSQL_READ_DEFAULT_GROUP, "mysqlstat");
- mysql_options(&conn->mysql, MYSQL_OPT_RECONNECT, &t);
- if (!mysql_real_connect(&conn->mysql, NULL, NULL, NULL, NULL, 0,
- NULL, 0)) {
- snmp_log(LOG_ERR, "can't connect to MySQL: %s\n",
- mysql_error(&conn->mysql));
- free(conn);
- conn = NULL;
+ if (!conn) {
+ conn = xcalloc(1, sizeof(*conn));
+ mysql_init(&conn->mysql);
+ if (access(config_file, F_OK) == 0)
+ mysql_options(&conn->mysql, MYSQL_READ_DEFAULT_FILE,
+ config_file);
+ mysql_options(&conn->mysql,
+ MYSQL_READ_DEFAULT_GROUP, "mysqlstat");
+ mysql_options(&conn->mysql, MYSQL_OPT_RECONNECT, &t);
+ if (!mysql_real_connect(&conn->mysql,
+ NULL, NULL, NULL, NULL, 0,
+ NULL, 0)) {
+ snmp_log(LOG_ERR, "can't connect to MySQL: %s\n",
+ mysql_error(&conn->mysql));
+ free(conn);
+ conn = NULL;
+ }
}
@@ -75,11 +79,2 @@ mysqlstat_connect(void)
}
-
-void
-mysqlstat_disconnect(mysqlstat_connection_t conn)
-{
- if (!conn)
- return;
- mysql_close(&conn->mysql);
- free(conn);
-}
@@ -103,3 +98,94 @@ unsigned mysqlstat_cache_timeout = CACHE_TIMEOUT;
#define STREQ(pat,str) (strcmp(#pat, str) == 0)
+
+struct process_list {
+ time_t ts;
+ MYSQL_RES *res;
+ uint32_t total;
+ uint32_t active;
+ uint32_t slaves;
+ uint32_t itr;
+};
+
+enum {
+ FI_processID,
+ FI_processUser,
+ FI_processHost,
+ FI_processDatabase,
+ FI_processCommand,
+ FI_processTime,
+ FI_processState,
+ FI_processInfo
+};
+static int
+get_process_list(struct process_list **p)
+{
+ static struct process_list plist;
+ time_t now;
+
+ now = time(NULL);
+ if (!plist.res || now - plist.ts >= mysqlstat_cache_timeout) {
+ mysqlstat_connection_t conn;
+ unsigned i;
+
+ if (plist.res) {
+ mysql_free_result(plist.res);
+ plist.res = NULL;
+ plist.total = plist.active = plist.slaves = 0;
+ }
+ DEBUGMSGTL(("mysqlstat", "Getting process list\n"));
+
+ conn = mysqlstat_connect();
+ if (!conn)
+ return SNMP_ERR_GENERR;
+
+ if (mysql_query(&conn->mysql, "SHOW PROCESSLIST")) {
+ snmp_log(LOG_ERR, "can't get slave process list: %s\n",
+ mysql_error(&conn->mysql));
+ return SNMP_ERR_NOSUCHNAME;
+ }
+ plist.res = mysql_store_result(&conn->mysql);
+ plist.ts = now;
+
+ plist.total = mysql_num_rows(plist.res);
+ for (i = 0; i < plist.total; i++) {
+ MYSQL_ROW row;
+
+ mysql_data_seek(plist.res, i);
+ row = mysql_fetch_row(plist.res);
+ if (!row[FI_processState]
+ || STREQ(Sleep, row[FI_processState]))
+ continue;
+ if (row[FI_processCommand]
+ && strcmp(row[FI_processCommand], "Binlog Dump") == 0)
+ plist.slaves++;
+ else
+ plist.active++;
+ }
+ }
+ *p = &plist;
+ return 0;
+}
+
+MYSQL_ROW
+process_next(struct process_list *p)
+{
+ MYSQL_ROW row;
+ if (p->itr >= p->total)
+ return NULL;
+ mysql_data_seek(p->res, p->itr);
+ ++p->itr;
+ return mysql_fetch_row(p->res);
+}
+
+MYSQL_ROW
+process_first(struct process_list **state)
+{
+ struct process_list *p;
+ if (get_process_list(&p))
+ return NULL;
+ p->itr = 0;
+ *state = p;
+ return process_next(p);
+}
@@ -226,3 +312,2 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic)
mysql_error(&conn->mysql));
- mysqlstat_disconnect(conn);
return SNMP_ERR_NOSUCHNAME;
@@ -232,3 +317,3 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic)
if (mysql_num_rows(res) < 1) {
- snmp_log(LOG_INFO, "empty slave status\n");
+ /* snmp_log(LOG_INFO, "empty slave status\n"); */
return 0;
@@ -242,3 +327,2 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic)
if (!ent) {
- mysqlstat_disconnect(conn);
return SNMP_ERR_GENERR;
@@ -249,3 +333,2 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic)
SNMP_FREE(ent);
- mysqlstat_disconnect(conn);
return SNMP_ERR_GENERR;
@@ -261,6 +344,5 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic)
for (i = 0; i < num_fields; i++)
- store_slave_status_row (ent, fields[i].name, row[i]);
+ store_slave_status_row(ent, fields[i].name, row[i]);
mysql_free_result(res);
- mysqlstat_disconnect(conn);
return 0;
@@ -297,14 +379,2 @@ replSlaveStatusTable_entry_free(void *data)
-
-enum {
- FI_processID,
- FI_processUser,
- FI_processHost,
- FI_processDatabase,
- FI_processCommand,
- FI_processTime,
- FI_processState,
- FI_processInfo
-};
-
static void
@@ -329,4 +399,9 @@ process_list_add(netsnmp_tdata *table_data, long idx, MYSQL_ROW mysql_row)
ent->processID = strtol(mysql_row[FI_processID], NULL, 10);
+
ASSIGN_ROW(ent, processUser, mysql_row);
- ASSIGN_ROW(ent, processHost, mysql_row);
+
+ ent->processHost_len = strcspn(mysql_row[FI_processHost], ":");
+ ent->processHost = xmalloc(ent->processHost_len);
+ memcpy(ent->processHost, mysql_row[FI_processHost], ent->processHost_len);
+
ASSIGN_ROW(ent, processDatabase, mysql_row);
@@ -348,35 +423,10 @@ processListTable_load(netsnmp_cache *cache, void *vmagic)
{
- mysqlstat_connection_t conn;
- MYSQL_RES *res;
- unsigned int num_rows, i;
+ struct process_list *p;
netsnmp_tdata *table = (netsnmp_tdata *) vmagic;
+ MYSQL_ROW row;
+ uint32_t i;
- DEBUGMSGTL(("mysqlstat", "Getting process list\n"));
-
- conn = mysqlstat_connect();
- if (!conn)
- return SNMP_ERR_GENERR;
-
- if (mysql_query(&conn->mysql, "SHOW PROCESSLIST")) {
- snmp_log(LOG_ERR, "can't get slave process list: %s\n",
- mysql_error(&conn->mysql));
- mysqlstat_disconnect(conn);
- return SNMP_ERR_NOSUCHNAME;
- }
-
- res = mysql_store_result(&conn->mysql);
- num_rows = mysql_num_rows(res);
-
- for (i = 0; i < num_rows; i++) {
- MYSQL_ROW row;
-
- mysql_data_seek(res, i);
- row = mysql_fetch_row(res);
-
+ for (row = process_first(&p), i = 0; row; row = process_next(p), i++) {
process_list_add(table, i, row);
}
-
- mysql_free_result(res);
- mysqlstat_disconnect(conn);
-
return 0;
@@ -395,2 +445,30 @@ processListTable_entry_free(void *data)
+uint32_t
+process_total_count(void)
+{
+ struct process_list *p;
+ if (get_process_list(&p))
+ return 0;
+ return p->total;
+}
+
+uint32_t
+process_active_count(void)
+{
+ struct process_list *p;
+ if (get_process_list(&p))
+ return 0;
+ return p->active;
+}
+
+uint32_t
+process_slave_count(void)
+{
+ struct process_list *p;
+ if (get_process_list(&p))
+ return 0;
+ return p->slaves;
+}
+
+
#if 0

Return to:

Send suggestions and report system problems to the System administrator.