aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-06-06 21:06:56 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2016-06-06 21:06:56 +0300
commit363bfa3d008da517ca284f9e83bfa5183f977e24 (patch)
tree5705f739a022bcf2633b5c68d3bbdc785facacf7
parentd0c73a249dd7719923612c6b3a23cfeb8c8720d0 (diff)
downloadmysqlstat-363bfa3d008da517ca284f9e83bfa5183f977e24.tar.gz
mysqlstat-363bfa3d008da517ca284f9e83bfa5183f977e24.tar.bz2
Reimplement replication OIDs as a table. Implement process list OIDs.
-rw-r--r--configure.ac2
-rw-r--r--src/MYSQL-STAT-MIB.txt352
-rw-r--r--src/Makefile.am8
-rw-r--r--src/mysqlstat.c509
-rw-r--r--src/mysqlstat_mib.mib2c384
5 files changed, 885 insertions, 370 deletions
diff --git a/configure.ac b/configure.ac
index 16d4eed..de177fd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,13 +12,13 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mysqlstat. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ(2.69)
-AC_INIT([mysqlstat], 0.0.90, [gray@gnu.org])
+AC_INIT([mysqlstat], 0.0.91, [gray@gnu.org])
AC_CONFIG_SRCDIR(src/mysqlstat_mib.mib2c)
AM_CONFIG_HEADER(config.h)
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_SYSTEM
diff --git a/src/MYSQL-STAT-MIB.txt b/src/MYSQL-STAT-MIB.txt
index 1580837..8fbc0e6 100644
--- a/src/MYSQL-STAT-MIB.txt
+++ b/src/MYSQL-STAT-MIB.txt
@@ -15,25 +15,96 @@ IMPORTS
OBJECT-GROUP, MODULE-COMPLIANCE
FROM SNMPv2-CONF
InetAddress, InetAddressType, InetPortNumber
FROM INET-ADDRESS-MIB;
mysql MODULE-IDENTITY
- LAST-UPDATED "201606060944Z"
+ LAST-UPDATED "201606061638Z"
ORGANIZATION "Gray Software"
CONTACT-INFO "Sergey Poznyakoff <gray@gnu.org>"
DESCRIPTION
"This MIB module defines objects for MySQL statistics."
- REVISION "201606060944Z"
+ REVISION "201606061638Z"
DESCRIPTION
"First revision."
::= { enterprises 9163 101 }
replication OBJECT IDENTIFIER ::= { mysql 1 }
-replStatus OBJECT IDENTIFIER ::= { replication 1 }
-replConfig OBJECT IDENTIFIER ::= { replication 2 }
+processList OBJECT IDENTIFIER ::= { mysql 2 }
+
+--
+-- Replication Slave Status
+--
+
+replSlaveStatusTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF ReplSlaveStatusEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A table of replication status. On replication slave,
+ it contains a single row, describing the current
+ status."
+ ::= { replication 1 }
+
+replSlaveStatusEntry OBJECT-TYPE
+ SYNTAX ReplSlaveStatusEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "An entry describing slave status."
+ INDEX { replSlaveIndex }
+ ::= { replSlaveStatusTable 1 }
+
+ReplSlaveStatusEntry ::= SEQUENCE {
+ replSlaveIndex Integer32,
+ replSlaveIOState ThreadStatusString,
+ replMasterLogFile DisplayString,
+ replReadMasterLogPos Counter32,
+ replRelayLogFile DisplayString,
+ replRelayLogPos Counter32,
+ replRelayMasterLogFile DisplayString,
+ replSlaveIORunning SlaveRunningState,
+ replSlaveSQLRunning TruthValue,
+ replLastSQLErrno Integer32,
+ replLastSQLError SQLErrorString,
+ replLastIOErrno Integer32,
+ replLastIOError SQLErrorString,
+ replExecMasterLogPos Counter32,
+ replRelayLogSpace Counter64,
+ replSecondsBehindMaster TimeStamp,
+ replMasterHost DisplayString,
+ replMasterUser DisplayString,
+ replMasterPort Integer32,
+ replConnectRetry TimeStamp,
+ replReplicateDoDB DisplayString,
+ replReplicateIgnoreDB DisplayString,
+ replReplicateDoTable DisplayString,
+ replReplicateIgnoreTable DisplayString,
+ replReplicateWildDoTable DisplayString,
+ replReplicateWildIgnoreTable DisplayString,
+ replSkipCounter Counter32,
+ replUntilCondition DisplayString,
+ replUntilLogFile DisplayString,
+ replUntilLogPos DisplayString,
+ replMasterServerId Integer32,
+ replMasterSSLAllowed DisplayString,
+ replMasterSSLCAFile DisplayString,
+ replMasterSSLCAPath DisplayString,
+ replMasterSSLCert DisplayString,
+ replMasterSSLCipher DisplayString,
+ replMasterSSLKey DisplayString,
+ replMasterSSLVerifyServerCert TruthValue
+}
+
+replSlaveIndex OBJECT-TYPE
+ SYNTAX Integer32 (0..65535)
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A number uniquely identifying slave status row."
+ ::= { replSlaveStatusEntry 1 }
ThreadStatusString ::= TEXTUAL-CONVENTION
DISPLAY-HINT "128t"
STATUS current
DESCRIPTION "A string representing thread status."
SYNTAX OCTET STRING (SIZE (0..128))
@@ -43,58 +114,58 @@ replSlaveIOState OBJECT-TYPE
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Describes what the thread is doing: trying to connect
to the master, waiting for events from the master,
reconnecting to the master, etc."
- ::= { replStatus 1 }
+ ::= { replSlaveStatusEntry 2 }
replMasterLogFile OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The name of the master binary log file from which the
I/O thread is currently reading."
- ::= { replStatus 2 }
+ ::= { replSlaveStatusEntry 3 }
replReadMasterLogPos OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The position in the current master binary log file up
to which the I/O thread has read."
- ::= { replStatus 3 }
+ ::= { replSlaveStatusEntry 4 }
replRelayLogFile OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The name of the relay log file from which the SQL
thread is currently reading and executing."
- ::= { replStatus 4 }
+ ::= { replSlaveStatusEntry 5 }
replRelayLogPos OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The position in the current relay log file up to
which the SQL thread has read and executed."
- ::= { replStatus 5 }
+ ::= { replSlaveStatusEntry 6 }
replRelayMasterLogFile OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The name of the master binary log file containing the
most recent event executed by the SQL thread."
- ::= { replStatus 6 }
+ ::= { replSlaveStatusEntry 7 }
SlaveRunningState ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION
"Represents slave I/O thread state."
SYNTAX INTEGER { yes(1), no(2), connecting(3) }
@@ -104,30 +175,30 @@ replSlaveIORunning OBJECT-TYPE
SYNTAX SlaveRunningState
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether the I/O thread is started and has connected
successfully to the master."
- ::= { replStatus 7 }
+ ::= { replSlaveStatusEntry 8 }
replSlaveSQLRunning OBJECT-TYPE
SYNTAX TruthValue
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether the SQL thread is started."
- ::= { replStatus 8 }
+ ::= { replSlaveStatusEntry 9 }
replLastSQLErrno OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The error code of the last error that caused the SQL
thread to stop."
- ::= { replStatus 9 }
+ ::= { replSlaveStatusEntry 10 }
SQLErrorString ::= TEXTUAL-CONVENTION
DISPLAY-HINT "1024t"
STATUS current
DESCRIPTION "A string representing SQL error."
SYNTAX OCTET STRING (SIZE (0..1024))
@@ -136,152 +207,152 @@ replLastSQLError OBJECT-TYPE
SYNTAX SQLErrorString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The error message describing the last error that
caused the SQL thread to stop."
- ::= { replStatus 10 }
+ ::= { replSlaveStatusEntry 11 }
replLastIOErrno OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The error code of the last error that caused the IO
thread to stop."
- ::= { replStatus 11 }
+ ::= { replSlaveStatusEntry 12 }
replLastIOError OBJECT-TYPE
SYNTAX SQLErrorString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The error message describing the last error that
caused the IO thread to stop."
- ::= { replStatus 12 }
+ ::= { replSlaveStatusEntry 13 }
replExecMasterLogPos OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The position in the current master binary log file to
which the SQL thread has read and executed, marking
the start of the next transaction or event to be
processed."
- ::= { replStatus 13 }
+ ::= { replSlaveStatusEntry 14 }
replRelayLogSpace OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total combined size of all existing relay log
files."
- ::= { replStatus 14 }
+ ::= { replSlaveStatusEntry 15 }
replSecondsBehindMaster OBJECT-TYPE
SYNTAX TimeStamp
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"This field is an indication of how `late' the slave
is. Basically, it reflects the time difference in
seconds between the slave SQL thread and the slave
I/O thread."
- ::= { replStatus 15 }
+ ::= { replSlaveStatusEntry 16 }
replMasterHost OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The master host that the slave is connected to."
- ::= { replConfig 1 }
+ ::= { replSlaveStatusEntry 17 }
replMasterUser OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The user name of the account used to connect to the
master."
- ::= { replConfig 2 }
+ ::= { replSlaveStatusEntry 18 }
replMasterPort OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The port used to connect to the master."
- ::= { replConfig 3 }
+ ::= { replSlaveStatusEntry 19 }
replConnectRetry OBJECT-TYPE
SYNTAX TimeStamp
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of seconds between connect retries."
- ::= { replConfig 4 }
+ ::= { replSlaveStatusEntry 20 }
replReplicateDoDB OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The list of databases to replicate."
- ::= { replConfig 5 }
+ ::= { replSlaveStatusEntry 21 }
replReplicateIgnoreDB OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The list of databases to exclude from replication."
- ::= { replConfig 6 }
+ ::= { replSlaveStatusEntry 22 }
replReplicateDoTable OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The list of tables to replicate."
- ::= { replConfig 7 }
+ ::= { replSlaveStatusEntry 23 }
replReplicateIgnoreTable OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The list of tables to exclude from replication."
- ::= { replConfig 8 }
+ ::= { replSlaveStatusEntry 24 }
replReplicateWildDoTable OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The lists of table name patterns to replicate."
- ::= { replConfig 9 }
+ ::= { replSlaveStatusEntry 25 }
replReplicateWildIgnoreTable OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The lists of table name patterns to exclude from replication."
- ::= { replConfig 10 }
+ ::= { replSlaveStatusEntry 26 }
replSkipCounter OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The current value of the `sql_slave_skip_counter'
system variable."
- ::= { replConfig 11 }
+ ::= { replSlaveStatusEntry 27 }
replUntilCondition OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
@@ -294,38 +365,38 @@ replUntilCondition OBJECT-TYPE
* `Master' if the slave is reading until a given
position in the master's binary log
* `Relay' if the slave is reading until a given
position in its relay log."
- ::= { replConfig 12 }
+ ::= { replSlaveStatusEntry 28 }
replUntilLogFile OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The log file name at which the SQL thread stops executing."
- ::= { replConfig 13 }
+ ::= { replSlaveStatusEntry 29 }
replUntilLogPos OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The position in replUntilLogFile at
which the SQL thread stops executing."
- ::= { replConfig 14 }
+ ::= { replSlaveStatusEntry 30 }
replMasterServerId OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"ID of the master server."
- ::= { replConfig 15 }
+ ::= { replSlaveStatusEntry 31 }
replMasterSSLAllowed OBJECT-TYPE
SYNTAX DisplayString
-- FIXME: special syntax for it?
MAX-ACCESS read-only
STATUS current
@@ -336,63 +407,262 @@ replMasterSSLAllowed OBJECT-TYPE
* `No' if an SSL connection to the master is not
permitted.
* `Ignored' if an SSL connection is permitted but the
slave server does not have SSL support enabled."
- ::= { replConfig 16 }
+ ::= { replSlaveStatusEntry 32 }
replMasterSSLCAFile OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"File name of the Master CA file."
- ::= { replConfig 17 }
+ ::= { replSlaveStatusEntry 33 }
replMasterSSLCAPath OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Path to look for SSL CA files."
- ::= { replConfig 18 }
+ ::= { replSlaveStatusEntry 34 }
replMasterSSLCert OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"File name of the master SSL certificate file."
- ::= { replConfig 19 }
+ ::= { replSlaveStatusEntry 35 }
replMasterSSLCipher OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"SSL ciphersuites in use."
- ::= { replConfig 20 }
+ ::= { replSlaveStatusEntry 36 }
replMasterSSLKey OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"File name of the master key file."
- ::= { replConfig 21 }
+ ::= { replSlaveStatusEntry 37 }
replMasterSSLVerifyServerCert OBJECT-TYPE
SYNTAX TruthValue
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether to verify server SSL certificate."
- ::= { replConfig 22 }
+ ::= { replSlaveStatusEntry 38 }
+
+--
+-- Table of Replication Slave Servers
+--
+
+-- replSlaveCount OBJECT-TYPE
+-- SYNTAX Counter32
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Number of active replication slaves."
+-- ::= { replSlave 1 }
+
+-- replSlaveTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF ReplSlaveEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "A table of active replication slaves."
+-- ::= { replSlave 2 }
+
+-- replSlaveEntry OBJECT-TYPE
+-- SYNTAX ReplSlaveEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "An entry (conceptual row) describing a replication
+-- slave server."
+-- INDEX { replSlaveIndex }
+-- ::= { replSlaveTable 1 }
+
+-- ReplSlaveEntry ::= SEQUENCE {
+-- replSlaveIndex Integer32,
+-- replSlaveHost DisplayString,
+-- replSlaveUser DisplayString,
+-- replSlaveCommand DisplayString,
+-- replSlaveState DisplayString,
+-- replSlaveTime TimeStamp,
+-- replSlaveInfo DisplayString
+-- }
+
+-- replSlaveIndex OBJECT-TYPE
+-- SYNTAX Integer32 (0..65535)
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "A number uniquely identifying each slave server."
+-- ::= { replSlaveEntry 1 }
+
+-- replSlaveHost OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Hostname of the server."
+-- ::= { replSlaveEntry 2 }
+
+-- replSlaveUser OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "User name used by that server."
+-- ::= { replSlaveEntry 3 }
+
+-- replSlaveCommand OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Command being run."
+-- ::= { replSlaveEntry 4 }
+
+-- replSlaveState OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "State of the connection."
+-- ::= { replSlaveEntry 5 }
+
+-- replSlaveTime OBJECT-TYPE
+-- SYNTAX TimeStamp
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Timestamp of the last status change."
+-- ::= { replSlaveEntry 6 }
+
+-- replSlaveInfo OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Additional info about the connection."
+-- ::= { replSlaveEntry 7 }
+
+--
+-- Process List
+--
+
+processListTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF ProcessListEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A table of active threads."
+ ::= { processList 2 }
+
+processListEntry OBJECT-TYPE
+ SYNTAX ProcessListEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A conceptual row of process list table."
+ INDEX { processIndex }
+ ::= { processListTable 1 }
+
+ProcessListEntry ::= SEQUENCE {
+ processIndex Integer32,
+ processID Integer32,
+ processUser DisplayString,
+ processHost DisplayString,
+ processDatabase DisplayString,
+ processCommand DisplayString,
+ processTime TimeStamp,
+ processState DisplayString,
+ processInfo DisplayString
+}
+
+processIndex OBJECT-TYPE
+ SYNTAX Integer32 (0..65535)
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A number uniquely identifying each process."
+ ::= { processListEntry 1 }
+
+processID OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Thread ID."
+ ::= { processListEntry 2 }
+processUser OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Connecting user."
+ ::= { processListEntry 3 }
+processHost OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Remote hostname or IP."
+ ::= { processListEntry 4 }
+
+processDatabase OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Database name."
+ ::= { processListEntry 5 }
+
+processCommand OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Command being processed."
+ ::= { processListEntry 6 }
+
+processTime OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Running time of the thread."
+ ::= { processListEntry 7 }
+
+processState OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Process state."
+ ::= { processListEntry 8 }
+
+processInfo OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Information about the process."
+ ::= { processListEntry 9 }
END
-- Local variables:
-- eval: (add-hook 'write-file-hooks 'time-stamp)
-- time-stamp-start: "\\(LAST-UPDATED\\|REVISION\\) *\""
-- time-stamp-end: "\""
diff --git a/src/Makefile.am b/src/Makefile.am
index 6463177..0b1ae43 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,18 +17,20 @@
dlmoddir=@DLMODDIR@
dlmod_LTLIBRARIES = mysqlstat.la
mysqlstat_la_SOURCES = \
mysqlstat.c\
mysqlstat.h\
- mysqlstat_mib.c
+ mysqlstat_mib.c\
+ mysqlstat_mib.h
BUILT_SOURCES = \
- mysqlstat_mib.c
+ mysqlstat_mib.c\
+ mysqlstat_mib.h
-mysqlstat_mib.c: mysqlstat_mib.mib2c MYSQL-STAT-MIB.txt
+mysqlstat_mib.c mysqlstat_mib.h: mysqlstat_mib.mib2c MYSQL-STAT-MIB.txt
.mib2c.c:
MIBDIRS=${top_srcdir}/src:${NET_SNMP_MIBDIRS} MIBS="+MYSQL-STAT-MIB" \
mib2c -c $< -f $@ mysql
#NET_SNMP_INCLUDES = `$(NET_SNMP_CONFIG) --cflags`
diff --git a/src/mysqlstat.c b/src/mysqlstat.c
index 3e89424..938439a 100644
--- a/src/mysqlstat.c
+++ b/src/mysqlstat.c
@@ -1,7 +1,7 @@
-/* This file is part of Mysqlstat -*- autoconf -*-
+/* This file is part of Mysqlstat
* Copyright (C) 2014-2016 Sergey Poznyakoff
*
* Mysqlstat is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
@@ -16,21 +16,22 @@
*/
#include <mysqlstat.h>
#include <mysql/mysql.h>
#undef NDEBUG
#include <assert.h>
+#include "mysqlstat_mib.h"
static char *config_file = CONFDIR "/mysqlstat.cnf";
struct mysqlstat_connection {
MYSQL mysql;
};
static void *
-xalloc(size_t s)
+xmalloc(size_t s)
{
void *p = malloc(s);
assert(p != NULL);
return p;
}
@@ -62,13 +63,13 @@ mysqlstat_connect(void)
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",
+ snmp_log(LOG_ERR, "can't connect to MySQL: %s\n",
mysql_error(&conn->mysql));
free(conn);
conn = NULL;
}
return conn;
}
@@ -79,286 +80,354 @@ mysqlstat_disconnect(mysqlstat_connection_t conn)
if (!conn)
return;
mysql_close(&conn->mysql);
free(conn);
}
-struct syment {
- char *name;
- char *value;
-};
-
-static unsigned int hash_size[] = {
- 7, 17, 37, 101, 229, 487, 1009, 2039, 4091, 8191, 16411
-};
+unsigned mysqlstat_cache_timeout = CACHE_TIMEOUT;
-/* |max_rehash| keeps the number of entries in |hash_size| table. */
-static unsigned int max_rehash = sizeof(hash_size) / sizeof(hash_size[0]);
+#define __cat2__(a,b) a ## b
+#define ASSIGN_STRING(e,m,s) \
+ do { \
+ if (s) { \
+ (e)->__cat2__(m,_len) = strlen(s); \
+ (e)->m = xmalloc((e)->__cat2__(m,_len)); \
+ memcpy((e)->m, s, (e)->__cat2__(m,_len)); \
+ } else { \
+ (e)->__cat2__(m,_len) = 0; \
+ (e)->m = NULL; \
+ } \
+ } while (0)
-struct hashtab {
- uint32_t hc;
- struct syment *tab;
-};
-
-static void
-syment_free(struct syment *ent)
-{
- free(ent->name);
- ent->name = NULL;
- free(ent->value);
- ent->value = NULL;
-}
+#define ASSIGN_ROW(e,m,r) ASSIGN_STRING(e,m,(r)[__cat2__(FI_,m)])
-static int
-syment_matches(struct syment *ent, char const *name)
-{
- if (!ent->name)
- return 0;
- return strcmp(ent->name, name) == 0;
-}
+#define STREQ(pat,str) (strcmp(#pat, str) == 0)
-static uint32_t
-hash_string(const char *name, uint32_t hashsize)
+
+static long
+val_Slave_IO_Running(char const *val)
{
- unsigned i;
-
- for (i = 0; *name; name++) {
- i <<= 1;
- i ^= *(unsigned char*) name;
- }
- return i % hashsize;
+ if (strcmp(val, "Yes") == 0)
+ return 1;
+ else if (strcmp(val, "No") == 0)
+ return 2;
+ else if (strcmp(val, "Connected") == 0)
+ return 3;
+ return 4;
}
-static uint32_t
-find_insert_pos(struct hashtab *ht, struct syment *ent)
+static long
+val_bool(char const *val)
{
- uint32_t i;
- uint32_t pos = hash_string(ent->name, hash_size[ht->hc]);
-
- for (i = pos; ht->tab[i].name; ) {
- i = (i + 1) % hash_size[ht->hc];
- if (i == pos)
- /* FIXME: Error message? */
- abort();
- }
- return i;
+ if (strcmp(val, "Yes") == 0)
+ return 1;
+ return 2;
}
static void
-rehash(struct hashtab *ht)
+store_slave_status_row(struct replSlaveStatusTable_entry *ent,
+ char const *name, char const *value)
{
- struct syment *oldtab = ht->tab;
- uint32_t i, n;
-
- assert(ht->hc + 1 < max_rehash);
- n = hash_size[ht->hc];
- ++ht->hc;
- ht->tab = xcalloc(hash_size[ht->hc], sizeof(ht->tab[0]));
- for (i = 0; i < n; i++) {
- if (oldtab[i].name)
- ht->tab[find_insert_pos(ht, &oldtab[i])] = oldtab[i];
+ if (STREQ(Slave_IO_State, name)) {
+ ASSIGN_STRING(ent, replSlaveIOState, value);
+ } else if (STREQ(Master_Host, name)) {
+ ASSIGN_STRING(ent, replMasterHost, value);
+ } else if (STREQ(Master_User, name)) {
+ ASSIGN_STRING(ent, replMasterUser, value);
+ } else if (STREQ(Master_Port, name)) {
+ ent->replMasterPort = strtoul(value, NULL, 10);
+ } else if (STREQ(Connect_Retry, name)) {
+ ent->replConnectRetry = strtoul(value, NULL, 10);
+ } else if (STREQ(Master_Log_File, name)) {
+ ASSIGN_STRING(ent, replMasterLogFile, value);
+ } else if (STREQ(Read_Master_Log_Pos, name)) {
+ ent->replReadMasterLogPos = strtoul(value, NULL, 10);
+ } else if (STREQ(Relay_Log_File, name)) {
+ ASSIGN_STRING(ent, replRelayLogFile, value);
+ } else if (STREQ(Relay_Log_Pos, name)) {
+ ent->replRelayLogPos = strtoul(value, NULL, 10);
+ } else if (STREQ(Relay_Master_Log_File, name)) {
+ ASSIGN_STRING(ent, replMasterLogFile, value);
+ } else if (STREQ(Slave_IO_Running, name)) {
+ ent->replSlaveIORunning = val_Slave_IO_Running(value);
+ } else if (STREQ(Slave_SQL_Running, name)) {
+ ent->replSlaveSQLRunning = val_bool(value);
+ } else if (STREQ(Replicate_Do_DB, name)) {
+ ASSIGN_STRING(ent, replReplicateDoDB, value);
+ } else if (STREQ(Replicate_Ignore_DB, name)) {
+ ASSIGN_STRING(ent, replReplicateIgnoreDB, value);
+ } else if (STREQ(Replicate_Do_Table, name)) {
+ ASSIGN_STRING(ent, replReplicateDoTable, value);
+ } else if (STREQ(Replicate_Ignore_Table, name)) {
+ ASSIGN_STRING(ent, replReplicateIgnoreTable, value);
+ } else if (STREQ(Replicate_Wild_Do_Table, name)) {
+ ASSIGN_STRING(ent, replReplicateWildDoTable, value);
+ } else if (STREQ(Replicate_Wild_Ignore_Table, name)) {
+ ASSIGN_STRING(ent, replReplicateWildIgnoreTable, value);
+ } else if (STREQ(Last_IO_Errno, name)) {
+ ent->replLastIOErrno = strtoul(value, NULL, 10);
+ } else if (STREQ(Last_IO_Error, name)) {
+ ASSIGN_STRING(ent, replLastIOError, value);
+ } else if (STREQ(Last_SQL_Errno, name)) {
+ ent->replLastSQLErrno = strtoul(value, NULL, 10);
+ } else if (STREQ(Last_SQL_Error, name)) {
+ ASSIGN_STRING(ent, replLastSQLError, value);
+ } else if (STREQ(Skip_Counter, name)) {
+ ent->replSkipCounter = strtoul(value, NULL, 10);
+ } else if (STREQ(Exec_Master_Log_Pos, name)) {
+ ent->replExecMasterLogPos = strtoul(value, NULL, 10);
+ } else if (STREQ(Relay_Log_Space, name)) {
+ uint64_t n = strtoull(value, NULL, 10);
+ ent->replRelayLogSpace.high = n >> 32;
+ ent->replRelayLogSpace.low = n & 0xffffffff;
+ } else if (STREQ(Until_Condition, name)) {
+ ASSIGN_STRING(ent, replUntilCondition, value);
+ } else if (STREQ(Until_Log_File, name)) {
+ ASSIGN_STRING(ent, replUntilLogFile, value);
+ } else if (STREQ(Until_Log_Pos, name)) {
+ ASSIGN_STRING(ent, replUntilLogPos, value);
+ } else if (STREQ(Master_SSL_Allowed, name)) {
+ ASSIGN_STRING(ent, replMasterSSLAllowed, value);
+ } else if (STREQ(Master_SSL_CA_File, name)) {
+ ASSIGN_STRING(ent, replMasterSSLCAFile, value);
+ } else if (STREQ(Master_SSL_CA_Path, name)) {
+ ASSIGN_STRING(ent, replMasterSSLCAPath, value);
+ } else if (STREQ(Master_SSL_Cert, name)) {
+ ASSIGN_STRING(ent, replMasterSSLCert, value);
+ } else if (STREQ(Master_SSL_Cipher, name)) {
+ ASSIGN_STRING(ent, replMasterSSLCipher, value);
+ } else if (STREQ(Master_SSL_Key, name)) {
+ ASSIGN_STRING(ent, replMasterSSLKey, value);
+ } else if (STREQ(Seconds_Behind_Master, name)) {
+ ent->replSecondsBehindMaster = strtoul(value, NULL, 10) * 100;
+ } else if (STREQ(Master_SSL_Verify_Server_Cert, name)) {
+ ent->replMasterSSLVerifyServerCert = val_bool(value);
}
- free(oldtab);
}
-static void
-hashtab_remove(struct hashtab *ht, char const *name)
+int
+replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic)
{
- uint32_t pos, i, j, r;
+ mysqlstat_connection_t conn;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ MYSQL_FIELD *fields;
+ unsigned int num_fields, i;
+ netsnmp_tdata *table = (netsnmp_tdata *) vmagic;
+ struct replSlaveStatusTable_entry *ent;
+ netsnmp_tdata_row *data_row;
- pos = hash_string(name, hash_size[ht->hc]);
- for (i = pos; ht->tab[i].name;) {
- if (syment_matches(&ht->tab[i], name))
- break;
- i = (i + 1) % hash_size[ht->hc];
- if (i == pos)
- return;// ENOENT
- }
+ conn = mysqlstat_connect();
+ if (!conn)
+ return SNMP_ERR_NOSUCHNAME;
- syment_free(&ht->tab[i]);
-
- for (;;) {
- ht->tab[i].name = ht->tab[i].value = NULL;
- j = i;
-
- do {
- i = (i + 1) % hash_size[ht->hc];
- if (!ht->tab[i].name)
- return;
- r = hash_string(ht->tab[i].name, hash_size[ht->hc]);
- } while ((j < r && r <= i)
- || (i < j && j < r) || (r <= i && i < j));
- ht->tab[j] = ht->tab[i];
+ DEBUGMSGTL(("mysqlstat", "Getting slave status\n"));
+ if (mysql_query(&conn->mysql, "SHOW SLAVE STATUS")) {
+ snmp_log(LOG_ERR, "can't get slave status: %s\n",
+ mysql_error(&conn->mysql));
+ mysqlstat_disconnect(conn);
+ return SNMP_ERR_NOSUCHNAME;
}
-}
-static char const *
-hashtab_lookup(struct hashtab *ht, char const *name)
-{
- uint32_t pos, i;
-
- pos = hash_string(name, hash_size[ht->hc]);
- for (i = pos; ht->tab[i].name;) {
- if (syment_matches(&ht->tab[i], name))
- return ht->tab[i].value;
- i = (i + 1) % hash_size[ht->hc];
- if (i == pos)
- break;
+ res = mysql_store_result(&conn->mysql);
+ if (mysql_num_rows(res) < 1) {
+ snmp_log(LOG_INFO, "empty slave status\n");
+ return 0;
}
- return NULL;
-}
-static void
-hashtab_install(struct hashtab *ht, char const *name, char const *value)
-{
- uint32_t i, pos;
- struct syment *ent;
-
- if (!value)
- value = "";
- DEBUGMSGTL(("mysqlstat", "%s = %s\n", name, value));
- pos = hash_string(name, hash_size[ht->hc]);
- for (i = pos; ht->tab[i].name;) {
- if (syment_matches(&ht->tab[i], name)) {
- free(ht->tab[i].value);
- ht->tab[i].value = xstrdup(value);
- return;
- }
- i = (i + 1) % hash_size[ht->hc];
- if (i == pos) {
- rehash(ht);
- i = pos = hash_string(name, hash_size[ht->hc]);
- }
+ num_fields = mysql_num_fields(res);
+ fields = mysql_fetch_fields(res);
+ row = mysql_fetch_row(res);
+
+ ent = SNMP_MALLOC_TYPEDEF(struct replSlaveStatusTable_entry);
+ if (!ent) {
+ mysqlstat_disconnect(conn);
+ return SNMP_ERR_GENERR;
}
- ht->tab[i].name = xstrdup(name);
- ht->tab[i].value = xstrdup(value);
-}
+ data_row = netsnmp_tdata_create_row();
+ if (!data_row) {
+ SNMP_FREE(ent);
+ mysqlstat_disconnect(conn);
+ return SNMP_ERR_GENERR;
+ }
+ data_row->data = ent;
+ ent->replSlaveIndex = 0;
+ netsnmp_tdata_row_add_index(data_row, ASN_INTEGER,
+ &ent->replSlaveIndex,
+ sizeof(ent->replSlaveIndex));
-void
-hashtab_clear(struct hashtab *ht)
-{
- unsigned i, hs;
+ netsnmp_tdata_add_row(table, data_row);
+
+ for (i = 0; i < num_fields; i++)
+ store_slave_status_row (ent, fields[i].name, row[i]);
- hs = hash_size[ht->hc];
- for (i = 0; i < hs; i++) {
- syment_free(&ht->tab[i]);
- }
+ mysql_free_result(res);
+ mysqlstat_disconnect(conn);
+ return 0;
}
-static struct hashtab *
-hashtab_create(void)
+void
+replSlaveStatusTable_entry_free(void *data)
{
- struct hashtab *ht = xalloc(sizeof(*ht));
- ht->hc = 0;
- ht->tab = xcalloc(hash_size[ht->hc], sizeof(ht->tab[0]));
- return ht;
+ struct replSlaveStatusTable_entry *ent = data;
+ free(ent->replSlaveIOState);
+ free(ent->replMasterLogFile);
+ free(ent->replRelayLogFile);
+ free(ent->replRelayMasterLogFile);
+ free(ent->replLastSQLError);
+ free(ent->replLastIOError);
+ free(ent->replMasterHost);
+ free(ent->replMasterUser);
+ free(ent->replReplicateDoDB);
+ free(ent->replReplicateIgnoreDB);
+ free(ent->replReplicateDoTable);
+ free(ent->replReplicateIgnoreTable);
+ free(ent->replReplicateWildDoTable);
+ free(ent->replReplicateWildIgnoreTable);
+ free(ent->replUntilCondition);
+ free(ent->replUntilLogFile);
+ free(ent->replUntilLogPos);
+ free(ent->replMasterSSLAllowed);
+ free(ent->replMasterSSLCAFile);
+ free(ent->replMasterSSLCAPath);
+ free(ent->replMasterSSLCert);
+ free(ent->replMasterSSLCipher);