Пример #1
0
static int mysql_read (user_data_t *ud)
{
	mysql_database_t *db;
	MYSQL     *con;
	MYSQL_RES *res;
	MYSQL_ROW  row;
	char      *query;

	derive_t qcache_hits          = 0;
	derive_t qcache_inserts       = 0;
	derive_t qcache_not_cached    = 0;
	derive_t qcache_lowmem_prunes = 0;
	gauge_t qcache_queries_in_cache = NAN;

	gauge_t threads_running   = NAN;
	gauge_t threads_connected = NAN;
	gauge_t threads_cached    = NAN;
	derive_t threads_created = 0;

	unsigned long long traffic_incoming = 0ULL;
	unsigned long long traffic_outgoing = 0ULL;

	if ((ud == NULL) || (ud->data == NULL))
	{
		ERROR ("mysql plugin: mysql_database_read: Invalid user data.");
		return (-1);
	}

	db = (mysql_database_t *) ud->data;

	/* An error message will have been printed in this case */
	if ((con = getconnection (db)) == NULL)
		return (-1);

	query = "SHOW STATUS";
	if (mysql_get_server_version (con) >= 50002)
		query = "SHOW GLOBAL STATUS";

	res = exec_query (con, query);
	if (res == NULL)
		return (-1);

	while ((row = mysql_fetch_row (res)))
	{
		char *key;
		unsigned long long val;

		key = row[0];
		val = atoll (row[1]);

		if (strncmp (key, "Com_", 
			          strlen ("Com_")) == 0)
		{
			if (val == 0ULL)
				continue;

			/* Ignore `prepared statements' */
			if (strncmp (key, "Com_stmt_", strlen ("Com_stmt_")) != 0)
				counter_submit ("mysql_commands", 
						key + strlen ("Com_"), 
						val, db);
		}
		else if (strncmp (key, "Handler_", 
				        strlen ("Handler_")) == 0)
		{
			if (val == 0ULL)
				continue;

			counter_submit ("mysql_handler", 
					key + strlen ("Handler_"), 
					val, db);
		}
		else if (strncmp (key, "Qcache_",
       				        strlen ("Qcache_")) == 0)
		{
			if (strcmp (key, "Qcache_hits") == 0)
				qcache_hits = (derive_t) val;
			else if (strcmp (key, "Qcache_inserts") == 0)
				qcache_inserts = (derive_t) val;
			else if (strcmp (key, "Qcache_not_cached") == 0)
				qcache_not_cached = (derive_t) val;
			else if (strcmp (key, "Qcache_lowmem_prunes") == 0)
				qcache_lowmem_prunes = (derive_t) val;
			else if (strcmp (key, "Qcache_queries_in_cache") == 0)
				qcache_queries_in_cache = (gauge_t) val;
		}
		else if (strncmp (key, "Bytes_", 
				        strlen ("Bytes_")) == 0)
		{
			if (strcmp (key, "Bytes_received") == 0)
				traffic_incoming += val;
			else if (strcmp (key, "Bytes_sent") == 0)
				traffic_outgoing += val;
		}
		else if (strncmp (key, "Threads_", 
       				        strlen ("Threads_")) == 0)
		{
			if (strcmp (key, "Threads_running") == 0)
				threads_running = (gauge_t) val;
			else if (strcmp (key, "Threads_connected") == 0)
				threads_connected = (gauge_t) val;
			else if (strcmp (key, "Threads_cached") == 0)
				threads_cached = (gauge_t) val;
			else if (strcmp (key, "Threads_created") == 0)
				threads_created = (derive_t) val;
		}
		else if (strncmp (key, "Table_locks_",
					strlen ("Table_locks_")) == 0)
		{
			counter_submit ("mysql_locks",
					key + strlen ("Table_locks_"),
					val, db);
		}
	}
	mysql_free_result (res); res = NULL;

	if ((qcache_hits != 0)
			|| (qcache_inserts != 0)
			|| (qcache_not_cached != 0)
			|| (qcache_lowmem_prunes != 0))
	{
		derive_submit ("cache_result", "qcache-hits",
				qcache_hits, db);
		derive_submit ("cache_result", "qcache-inserts",
				qcache_inserts, db);
		derive_submit ("cache_result", "qcache-not_cached",
				qcache_not_cached, db);
		derive_submit ("cache_result", "qcache-prunes",
				qcache_lowmem_prunes, db);

		gauge_submit ("cache_size", "qcache",
				qcache_queries_in_cache, db);
	}

	if (threads_created != 0)
	{
		gauge_submit ("threads", "running",
				threads_running, db);
		gauge_submit ("threads", "connected",
				threads_connected, db);
		gauge_submit ("threads", "cached",
				threads_cached, db);

		derive_submit ("total_threads", "created",
				threads_created, db);
	}

	traffic_submit  (traffic_incoming, traffic_outgoing, db);

	if (db->master_stats)
		mysql_read_master_stats (db, con);

	if ((db->slave_stats) || (db->slave_notif))
		mysql_read_slave_stats (db, con);

	return (0);
} /* int mysql_read */
Пример #2
0
static int mysql_read_wsrep_stats (mysql_database_t *db, MYSQL *con)
{
    MYSQL_RES *res;
    MYSQL_ROW  row;

    const char *query;
    struct {
        const char *key;
        const char *type;
        int ds_type;
    } metrics[] = {

        { "wsrep_apply_oooe",                "operations",   DS_TYPE_DERIVE },
        { "wsrep_apply_oool",                "operations",   DS_TYPE_DERIVE },
        { "wsrep_causal_reads",              "operations",   DS_TYPE_DERIVE },
        { "wsrep_commit_oooe",               "operations",   DS_TYPE_DERIVE },
        { "wsrep_commit_oool",               "operations",   DS_TYPE_DERIVE },
        { "wsrep_flow_control_recv",         "operations",   DS_TYPE_DERIVE },
        { "wsrep_flow_control_sent",         "operations",   DS_TYPE_DERIVE },
        { "wsrep_flow_control_paused",       "operations",   DS_TYPE_DERIVE },
        { "wsrep_local_bf_aborts",           "operations",   DS_TYPE_DERIVE },
        { "wsrep_local_cert_failures",       "operations",   DS_TYPE_DERIVE },
        { "wsrep_local_commits",             "operations",   DS_TYPE_DERIVE },
        { "wsrep_local_replays",             "operations",   DS_TYPE_DERIVE },
        { "wsrep_received",                  "operations",   DS_TYPE_DERIVE },
        { "wsrep_replicated",                "operations",   DS_TYPE_DERIVE },

        { "wsrep_received_bytes",            "total_bytes",  DS_TYPE_DERIVE },
        { "wsrep_replicated_bytes",          "total_bytes",  DS_TYPE_DERIVE },

        { "wsrep_apply_window",              "gauge",        DS_TYPE_GAUGE },
        { "wsrep_commit_window",             "gauge",        DS_TYPE_GAUGE },

        { "wsrep_cluster_size",              "gauge",        DS_TYPE_GAUGE },
        { "wsrep_cert_deps_distance",        "gauge",        DS_TYPE_GAUGE },

        { "wsrep_local_recv_queue",          "queue_length", DS_TYPE_GAUGE },
        { "wsrep_local_send_queue",          "queue_length", DS_TYPE_GAUGE },

        { NULL,                              NULL,           0}

    };

    query = "SHOW GLOBAL STATUS LIKE 'wsrep_%'";

    res = exec_query (con, query);
    if (res == NULL)
        return (-1);

    row = mysql_fetch_row (res);
    if (row == NULL)
    {
        ERROR ("mysql plugin: Failed to get wsrep statistics: "
               "`%s' did not return any rows.", query);
        mysql_free_result (res);
        return (-1);
    }

    while ((row = mysql_fetch_row (res)))
    {
        int i;
        char *key;
        unsigned long long val;

        key = row[0];
        val = atoll (row[1]);

        for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++)
            ;

        if (metrics[i].key == NULL)
            continue;

        switch (metrics[i].ds_type) {
        case DS_TYPE_GAUGE:
            gauge_submit(metrics[i].type, key, (gauge_t)val, db);
            break;
        case DS_TYPE_DERIVE:
            derive_submit(metrics[i].type, key, (derive_t)val, db);
            break;
        }
    }

    mysql_free_result(res);
    return (0);
} /* mysql_read_wsrep_stats */
Пример #3
0
static int mysql_read (user_data_t *ud)
{
    mysql_database_t *db;
    MYSQL      *con;
    MYSQL_RES  *res;
    MYSQL_ROW   row;
    const char *query;

    derive_t qcache_hits          = 0;
    derive_t qcache_inserts       = 0;
    derive_t qcache_not_cached    = 0;
    derive_t qcache_lowmem_prunes = 0;
    gauge_t qcache_queries_in_cache = NAN;

    gauge_t threads_running   = NAN;
    gauge_t threads_connected = NAN;
    gauge_t threads_cached    = NAN;
    derive_t threads_created = 0;

    unsigned long long traffic_incoming = 0ULL;
    unsigned long long traffic_outgoing = 0ULL;
    unsigned long mysql_version = 0ULL;

    if ((ud == NULL) || (ud->data == NULL))
    {
        ERROR ("mysql plugin: mysql_database_read: Invalid user data.");
        return (-1);
    }

    db = (mysql_database_t *) ud->data;

    /* An error message will have been printed in this case */
    if ((con = getconnection (db)) == NULL)
        return (-1);

    mysql_version = mysql_get_server_version(con);

    query = "SHOW STATUS";
    if (mysql_version >= 50002)
        query = "SHOW GLOBAL STATUS";

    res = exec_query (con, query);
    if (res == NULL)
        return (-1);

    while ((row = mysql_fetch_row (res)))
    {
        char *key;
        unsigned long long val;

        key = row[0];
        val = atoll (row[1]);

        if (strncmp (key, "Com_",
                     strlen ("Com_")) == 0)
        {
            if (val == 0ULL)
                continue;

            /* Ignore `prepared statements' */
            if (strncmp (key, "Com_stmt_", strlen ("Com_stmt_")) != 0)
                counter_submit ("mysql_commands",
                                key + strlen ("Com_"),
                                val, db);
        }
        else if (strncmp (key, "Handler_",
                          strlen ("Handler_")) == 0)
        {
            if (val == 0ULL)
                continue;

            counter_submit ("mysql_handler",
                            key + strlen ("Handler_"),
                            val, db);
        }
        else if (strncmp (key, "Qcache_",
                          strlen ("Qcache_")) == 0)
        {
            if (strcmp (key, "Qcache_hits") == 0)
                qcache_hits = (derive_t) val;
            else if (strcmp (key, "Qcache_inserts") == 0)
                qcache_inserts = (derive_t) val;
            else if (strcmp (key, "Qcache_not_cached") == 0)
                qcache_not_cached = (derive_t) val;
            else if (strcmp (key, "Qcache_lowmem_prunes") == 0)
                qcache_lowmem_prunes = (derive_t) val;
            else if (strcmp (key, "Qcache_queries_in_cache") == 0)
                qcache_queries_in_cache = (gauge_t) val;
        }
        else if (strncmp (key, "Bytes_",
                          strlen ("Bytes_")) == 0)
        {
            if (strcmp (key, "Bytes_received") == 0)
                traffic_incoming += val;
            else if (strcmp (key, "Bytes_sent") == 0)
                traffic_outgoing += val;
        }
        else if (strncmp (key, "Threads_",
                          strlen ("Threads_")) == 0)
        {
            if (strcmp (key, "Threads_running") == 0)
                threads_running = (gauge_t) val;
            else if (strcmp (key, "Threads_connected") == 0)
                threads_connected = (gauge_t) val;
            else if (strcmp (key, "Threads_cached") == 0)
                threads_cached = (gauge_t) val;
            else if (strcmp (key, "Threads_created") == 0)
                threads_created = (derive_t) val;
        }
        else if (strncmp (key, "Table_locks_",
                          strlen ("Table_locks_")) == 0)
        {
            counter_submit ("mysql_locks",
                            key + strlen ("Table_locks_"),
                            val, db);
        }
        else if (db->innodb_stats && strncmp (key, "Innodb_", strlen ("Innodb_")) == 0)
        {
            /* buffer pool */
            if (strcmp (key, "Innodb_buffer_pool_pages_data") == 0)
                gauge_submit ("mysql_bpool_pages", "data", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_pages_dirty") == 0)
                gauge_submit ("mysql_bpool_pages", "dirty", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_pages_flushed") == 0)
                counter_submit ("mysql_bpool_counters", "pages_flushed", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_pages_free") == 0)
                gauge_submit ("mysql_bpool_pages", "free", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_pages_misc") == 0)
                gauge_submit ("mysql_bpool_pages", "misc", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_pages_total") == 0)
                gauge_submit ("mysql_bpool_pages", "total", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_read_ahead_rnd") == 0)
                counter_submit ("mysql_bpool_counters", "read_ahead_rnd", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_read_ahead") == 0)
                counter_submit ("mysql_bpool_counters", "read_ahead", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_read_ahead_evicted") == 0)
                counter_submit ("mysql_bpool_counters", "read_ahead_evicted", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_read_requests") == 0)
                counter_submit ("mysql_bpool_counters", "read_requests", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_reads") == 0)
                counter_submit ("mysql_bpool_counters", "reads", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_write_requests") == 0)
                counter_submit ("mysql_bpool_counters", "write_requests", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_bytes_data") == 0)
                gauge_submit ("mysql_bpool_bytes", "data", val, db);
            else if (strcmp (key, "Innodb_buffer_pool_bytes_dirty") == 0)
                gauge_submit ("mysql_bpool_bytes", "dirty", val, db);

            /* data */
            if (strcmp (key, "Innodb_data_fsyncs") == 0)
                counter_submit ("mysql_innodb_data", "fsyncs", val, db);
            else if (strcmp (key, "Innodb_data_read") == 0)
                counter_submit ("mysql_innodb_data", "read", val, db);
            else if (strcmp (key, "Innodb_data_reads") == 0)
                counter_submit ("mysql_innodb_data", "reads", val, db);
            else if (strcmp (key, "Innodb_data_writes") == 0)
                counter_submit ("mysql_innodb_data", "writes", val, db);
            else if (strcmp (key, "Innodb_data_written") == 0)
                counter_submit ("mysql_innodb_data", "written", val, db);

            /* double write */
            else if (strcmp (key, "Innodb_dblwr_writes") == 0)
                counter_submit ("mysql_innodb_dblwr", "writes", val, db);
            else if (strcmp (key, "Innodb_dblwr_pages_written") == 0)
                counter_submit ("mysql_innodb_dblwr", "written", val, db);

            /* log */
            else if (strcmp (key, "Innodb_log_waits") == 0)
                counter_submit ("mysql_innodb_log", "waits", val, db);
            else if (strcmp (key, "Innodb_log_write_requests") == 0)
                counter_submit ("mysql_innodb_log", "write_requests", val, db);
            else if (strcmp (key, "Innodb_log_writes") == 0)
                counter_submit ("mysql_innodb_log", "writes", val, db);
            else if (strcmp (key, "Innodb_os_log_fsyncs") == 0)
                counter_submit ("mysql_innodb_log", "fsyncs", val, db);
            else if (strcmp (key, "Innodb_os_log_written") == 0)
                counter_submit ("mysql_innodb_log", "written", val, db);

            /* pages */
            else if (strcmp (key, "Innodb_pages_created") == 0)
                counter_submit ("mysql_innodb_pages", "created", val, db);
            else if (strcmp (key, "Innodb_pages_read") == 0)
                counter_submit ("mysql_innodb_pages", "read", val, db);
            else if (strcmp (key, "Innodb_pages_written") == 0)
                counter_submit ("mysql_innodb_pages", "written", val, db);

            /* row lock */
            else if (strcmp (key, "Innodb_row_lock_time") == 0)
                counter_submit ("mysql_innodb_row_lock", "time", val, db);
            else if (strcmp (key, "Innodb_row_lock_waits") == 0)
                counter_submit ("mysql_innodb_row_lock", "waits", val, db);

            /* rows */
            else if (strcmp (key, "Innodb_rows_deleted") == 0)
                counter_submit ("mysql_innodb_rows", "deleted", val, db);
            else if (strcmp (key, "Innodb_rows_inserted") == 0)
                counter_submit ("mysql_innodb_rows", "inserted", val, db);
            else if (strcmp (key, "Innodb_rows_read") == 0)
                counter_submit ("mysql_innodb_rows", "read", val, db);
            else if (strcmp (key, "Innodb_rows_updated") == 0)
                counter_submit ("mysql_innodb_rows", "updated", val, db);
        }
        else if (strncmp (key, "Select_", strlen ("Select_")) == 0)
        {
            counter_submit ("mysql_select", key + strlen ("Select_"),
                            val, db);
        }
        else if (strncmp (key, "Sort_", strlen ("Sort_")) == 0)
        {
            if (strcmp (key, "Sort_merge_passes") == 0)
                counter_submit ("mysql_sort_merge_passes", NULL, val, db);
            else if (strcmp (key, "Sort_rows") == 0)
                counter_submit ("mysql_sort_rows", NULL, val, db);
            else if (strcmp (key, "Sort_range") == 0)
                counter_submit ("mysql_sort", "range", val, db);
            else if (strcmp (key, "Sort_scan") == 0)
                counter_submit ("mysql_sort", "scan", val, db);

        }
        else if (strncmp (key, "Slow_queries", strlen ("Slow_queries")) == 0)
        {
            counter_submit ("mysql_slow_queries", NULL , val, db);
        }
    }
    mysql_free_result (res);
    res = NULL;

    if ((qcache_hits != 0)
            || (qcache_inserts != 0)
            || (qcache_not_cached != 0)
            || (qcache_lowmem_prunes != 0))
    {
        derive_submit ("cache_result", "qcache-hits",
                       qcache_hits, db);
        derive_submit ("cache_result", "qcache-inserts",
                       qcache_inserts, db);
        derive_submit ("cache_result", "qcache-not_cached",
                       qcache_not_cached, db);
        derive_submit ("cache_result", "qcache-prunes",
                       qcache_lowmem_prunes, db);

        gauge_submit ("cache_size", "qcache",
                      qcache_queries_in_cache, db);
    }

    if (threads_created != 0)
    {
        gauge_submit ("threads", "running",
                      threads_running, db);
        gauge_submit ("threads", "connected",
                      threads_connected, db);
        gauge_submit ("threads", "cached",
                      threads_cached, db);

        derive_submit ("total_threads", "created",
                       threads_created, db);
    }

    traffic_submit  (traffic_incoming, traffic_outgoing, db);

    if (mysql_version >= 50600 && db->innodb_stats)
        mysql_read_innodb_stats (db, con);

    if (db->master_stats)
        mysql_read_master_stats (db, con);

    if ((db->slave_stats) || (db->slave_notif))
        mysql_read_slave_stats (db, con);

    if (db->wsrep_stats)
        mysql_read_wsrep_stats (db, con);

    return (0);
} /* int mysql_read */
Пример #4
0
static int mysql_read_innodb_stats (mysql_database_t *db, MYSQL *con)
{
    MYSQL_RES *res;
    MYSQL_ROW  row;

    const char *query;
    struct {
        const char *key;
        const char *type;
        int ds_type;
    } metrics[] = {
        { "metadata_mem_pool_size",          "bytes",        DS_TYPE_GAUGE },
        { "lock_deadlocks",                  "mysql_locks",  DS_TYPE_DERIVE },
        { "lock_timeouts",                   "mysql_locks",  DS_TYPE_DERIVE },
        { "lock_row_lock_current_waits",     "mysql_locks",  DS_TYPE_DERIVE },
        { "buffer_pool_size",                "bytes",        DS_TYPE_GAUGE },

        { "buffer_pool_reads",               "operations",   DS_TYPE_DERIVE },
        { "buffer_pool_read_requests",       "operations",   DS_TYPE_DERIVE },
        { "buffer_pool_write_requests",      "operations",   DS_TYPE_DERIVE },
        { "buffer_pool_wait_free",           "operations",   DS_TYPE_DERIVE },
        { "buffer_pool_read_ahead",          "operations",   DS_TYPE_DERIVE },
        { "buffer_pool_read_ahead_evicted",  "operations",   DS_TYPE_DERIVE },

        { "buffer_pool_pages_total",         "gauge",        DS_TYPE_GAUGE },
        { "buffer_pool_pages_misc",          "gauge",        DS_TYPE_GAUGE },
        { "buffer_pool_pages_data",          "gauge",        DS_TYPE_GAUGE },
        { "buffer_pool_bytes_data",          "gauge",        DS_TYPE_GAUGE },
        { "buffer_pool_pages_dirty",         "gauge",        DS_TYPE_GAUGE },
        { "buffer_pool_bytes_dirty",         "gauge",        DS_TYPE_GAUGE },
        { "buffer_pool_pages_free",          "gauge",        DS_TYPE_GAUGE },

        { "buffer_pages_created",            "operations",   DS_TYPE_DERIVE },
        { "buffer_pages_written",            "operations",   DS_TYPE_DERIVE },
        { "buffer_pages_read",               "operations",   DS_TYPE_DERIVE },
        { "buffer_data_reads",               "operations",   DS_TYPE_DERIVE },
        { "buffer_data_written",             "operations",   DS_TYPE_DERIVE },

        { "os_data_reads",                   "operations",   DS_TYPE_DERIVE },
        { "os_data_writes",                  "operations",   DS_TYPE_DERIVE },
        { "os_data_fsyncs",                  "operations",   DS_TYPE_DERIVE },
        { "os_log_bytes_written",            "operations",   DS_TYPE_DERIVE },
        { "os_log_fsyncs",                   "operations",   DS_TYPE_DERIVE },
        { "os_log_pending_fsyncs",           "operations",   DS_TYPE_DERIVE },
        { "os_log_pending_writes",           "operations",   DS_TYPE_DERIVE },

        { "trx_rseg_history_len",            "gauge",        DS_TYPE_GAUGE },

        { "log_waits",                       "operations",   DS_TYPE_DERIVE },
        { "log_write_requests",              "operations",   DS_TYPE_DERIVE },
        { "log_writes",                      "operations",   DS_TYPE_DERIVE },
        { "adaptive_hash_searches",          "operations",   DS_TYPE_DERIVE },

        { "file_num_open_files",             "gauge",        DS_TYPE_GAUGE },

        { "ibuf_merges_insert",              "operations",   DS_TYPE_DERIVE },
        { "ibuf_merges_delete_mark",         "operations",   DS_TYPE_DERIVE },
        { "ibuf_merges_delete",              "operations",   DS_TYPE_DERIVE },
        { "ibuf_merges_discard_insert",      "operations",   DS_TYPE_DERIVE },
        { "ibuf_merges_discard_delete_mark", "operations",   DS_TYPE_DERIVE },
        { "ibuf_merges_discard_delete",      "operations",   DS_TYPE_DERIVE },
        { "ibuf_merges_discard_merges",      "operations",   DS_TYPE_DERIVE },
        { "ibuf_size",                       "bytes",        DS_TYPE_GAUGE },

        { "innodb_activity_count",           "gauge",        DS_TYPE_GAUGE },
        { "innodb_dblwr_writes",             "operations",   DS_TYPE_DERIVE },
        { "innodb_dblwr_pages_written",      "operations",   DS_TYPE_DERIVE },
        { "innodb_dblwr_page_size",          "gauge",        DS_TYPE_GAUGE },

        { "innodb_rwlock_s_spin_waits",      "operations",   DS_TYPE_DERIVE },
        { "innodb_rwlock_x_spin_waits",      "operations",   DS_TYPE_DERIVE },
        { "innodb_rwlock_s_spin_rounds",     "operations",   DS_TYPE_DERIVE },
        { "innodb_rwlock_x_spin_rounds",     "operations",   DS_TYPE_DERIVE },
        { "innodb_rwlock_s_os_waits",        "operations",   DS_TYPE_DERIVE },
        { "innodb_rwlock_x_os_waits",        "operations",   DS_TYPE_DERIVE },

        { "dml_reads",                       "operations",   DS_TYPE_DERIVE },
        { "dml_inserts",                     "operations",   DS_TYPE_DERIVE },
        { "dml_deletes",                     "operations",   DS_TYPE_DERIVE },
        { "dml_updates",                     "operations",   DS_TYPE_DERIVE },

        { NULL,                              NULL,           0}
    };

    query = "SELECT name, count, type FROM information_schema.innodb_metrics WHERE status = 'enabled'";

    res = exec_query (con, query);
    if (res == NULL)
        return (-1);

    while ((row = mysql_fetch_row (res)))
    {
        int i;
        char *key;
        unsigned long long val;

        key = row[0];
        val = atoll (row[1]);

        for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++)
            ;

        if (metrics[i].key == NULL)
            continue;

        switch (metrics[i].ds_type) {
        case DS_TYPE_COUNTER:
            counter_submit(metrics[i].type, key, (counter_t)val, db);
            break;
        case DS_TYPE_GAUGE:
            gauge_submit(metrics[i].type, key, (gauge_t)val, db);
            break;
        case DS_TYPE_DERIVE:
            derive_submit(metrics[i].type, key, (derive_t)val, db);
            break;
        }
    }

    mysql_free_result(res);
    return (0);
}