diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml
new file mode 100644
index 0000000..39bbcb2
--- /dev/null
+++ b/.github/workflows/pythonapp.yml
@@ -0,0 +1,37 @@
+# This workflow will install Python dependencies, run tests and lint with a single version of Python
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: Python application
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: [3.5, 3.6]
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v1
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ # TODO: Add requirements.txt instead
+ pip install PyMySQL
+ - name: Lint with flake8
+ run: |
+ pip install flake8
+ # stop the build if there are Python syntax errors or undefined names
+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+ # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
+ flake8 . --count --exit-zero --max-complexity=19 --max-line-length=127 --statistics
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..598ae79
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/.vscode
diff --git a/README.md b/README.md
index df02a08..e07bc7c 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ Pulls most of the same metrics as the Percona Monitoring Plugins for Cacti. Coll
Most MySQL monitoring plugins fetch a lot of information by parsing the output of `SHOW ENGINE INNODB STATUS`. This plugin prefers InnoDB statistics from `SHOW GLOBAL STATUS`. Percona Server and MariaDB provide most of these InnoDB metrics on `SHOW GLOBAL STATUS`.
-Requires the Python MySQLdb package. (`python-mysqldb` on Debian)
+Requires the Python `pymysql` package.
## Installation
1. Place mysql.py in your CollectD python plugins directory
@@ -187,6 +187,7 @@ Collected from `SHOW VARIABLES`:
variables.thread_cache_size
variables.thread_concurrency
variables.tmp_table_size
+ variables.read_only
### MySQL Processes
@@ -296,6 +297,30 @@ TBD:
hash_index_cells_used
additional_pool_alloc
+### InnoDB metrics from information_schema
+
+**Warning: This is only available in MariaDB >= 10.x and MySQL >= 5.6.**
+
+Collected by parsing the output of `SELECT COUNT from INFORMATION_SCHEMA.INNODB_METRICS where name ='os_log_bytes_written';`:
+
+ mysql plugin: Sending value: innodb/os_log_bytes_written=263167952896
+
+To get the metadata lock information:
+
+ mysql plugin: Sending value: innodb/lock=0
+
+- MariaDB: https://mariadb.com/kb/en/metadata-lock-info-plugin/
+- MySQL: https://dev.mysql.com/doc/refman/5.7/en/metadata-locks-table.html
+
+
+### Database size
+
+Collected by parsing the output of `SELECT table_schema 'db_name', Round(Sum(data_length + index_length) / 1024 / 1024, 0) 'db_size_mb' FROM information_schema.tables WHERE table_schema not in ('mysql', 'information_schema', 'performance_schema', 'heartbeat') GROUP BY table_schema;`:
+
+ db_size/databasename=14907
+
+The Database size is in MB.
+
### Master/Slave Status
@@ -310,6 +335,13 @@ From `SHOW SLAVE STATUS`:
slave.slave_stopped - 1 when the slave is stopped, 0 when it's running
slave.slave_running - 1 when the slave is running, 0 when it's stopped
+### Current connections for users
+
+This is using performance_schema. If performance_schema is not enabled, it won't work.
+
+ user_connection.root
+ user_connection.user-repl
+
### Query Response Times
For versions of MySQL with support for it and where enabled, `INFORMATION_SCHEMA.QUERY_RESPONSE_TIME` will be queried for metrics to generate a histogram of query response times.
diff --git a/mysql.py b/mysql.py
index 95f9bb1..a0d2c67 100644
--- a/mysql.py
+++ b/mysql.py
@@ -1,597 +1,740 @@
-#!/usr/bin/env python
-# CollectD MySQL plugin, designed for MySQL 5.5+ (specifically Percona Server)
-#
-# Pulls most of the same metrics as the Percona Monitoring Plugins for Cacti,
-# however is designed to be used on newer versions of MySQL and as such drops
-# all of the legacy compatibility, and favors metrics from SHOW GLOBAL STATUS
-# as opposed to SHOW ENGINE INNODB STATUS where possible.
-#
-# Configuration:
-# Import mysql
-#
-# Host localhost
-# Port 3306 (optional)
-# User root
-# Password xxxx
-# HeartbeatTable percona.heartbeat (optional, if using pt-heartbeat)
-# Verbose true (optional, to enable debugging)
-#
-#
-# Requires "MySQLdb" for Python
-#
-# Author: Chris Boulton
-# License: MIT (http://www.opensource.org/licenses/mit-license.php)
-#
+#!/usr/bin/env python3
+"""
+CollectD MySQL plugin, designed for MySQL 5.5+ (specifically Percona Server)
+
+Pulls most of the same metrics as the Percona Monitoring Plugins for Cacti,
+however is designed to be used on newer versions of MySQL and as such drops
+all of the legacy compatibility, and favors metrics from SHOW GLOBAL STATUS
+as opposed to SHOW ENGINE INNODB STATUS where possible.
+
+Configuration:
+Import mysql
+
+ Host localhost
+ Port 3306 (optional)
+ User root
+ Password xxxx
+ HeartbeatTable percona.heartbeat (optional, if using pt-heartbeat)
+ Verbose true (optional, to enable debugging)
+
+
+Requires "pymysql" for Python
+
+Author: Chris Boulton
+License: MIT (http://www.opensource.org/licenses/mit-license.php)
+"""
import sys
+import re
+
+import pymysql
-COLLECTD_ENABLED=True
+COLLECTD_ENABLED = True
try:
- import collectd
+ import collectd
except ImportError:
- # We're not running in CollectD, set this to False so we can make some changes
- # accordingly for testing/development.
- COLLECTD_ENABLED=False
-import re
-import MySQLdb
+ # We're not running in CollectD, set this to False so we can make some changes
+ # accordingly for testing/development.
+ COLLECTD_ENABLED = False
MYSQL_CONFIG = {
- 'Host': 'localhost',
- 'Port': 3306,
- 'User': 'root',
- 'Password': '',
- 'HeartbeatTable': '',
- 'Verbose': False,
+ 'Host': 'localhost',
+ 'Port': 3306,
+ 'User': 'root',
+ 'Password': '',
+ 'HeartbeatTable': '',
+ 'Verbose': False,
}
MYSQL_STATUS_VARS = {
- 'Aborted_clients': 'counter',
- 'Aborted_connects': 'counter',
- 'Binlog_cache_disk_use': 'counter',
- 'Binlog_cache_use': 'counter',
- 'Bytes_received': 'counter',
- 'Bytes_sent': 'counter',
- 'Connections': 'counter',
- 'Created_tmp_disk_tables': 'counter',
- 'Created_tmp_files': 'counter',
- 'Created_tmp_tables': 'counter',
- 'Innodb_buffer_pool_pages_data': 'gauge',
- 'Innodb_buffer_pool_pages_dirty': 'gauge',
- 'Innodb_buffer_pool_pages_free': 'gauge',
- 'Innodb_buffer_pool_pages_total': 'gauge',
- 'Innodb_buffer_pool_read_requests': 'counter',
- 'Innodb_buffer_pool_reads': 'counter',
- 'Innodb_checkpoint_age': 'gauge',
- 'Innodb_checkpoint_max_age': 'gauge',
- 'Innodb_data_fsyncs': 'counter',
- 'Innodb_data_pending_fsyncs': 'gauge',
- 'Innodb_data_pending_reads': 'gauge',
- 'Innodb_data_pending_writes': 'gauge',
- 'Innodb_data_read': 'counter',
- 'Innodb_data_reads': 'counter',
- 'Innodb_data_writes': 'counter',
- 'Innodb_data_written': 'counter',
- 'Innodb_deadlocks': 'counter',
- 'Innodb_history_list_length': 'gauge',
- 'Innodb_ibuf_free_list': 'gauge',
- 'Innodb_ibuf_merged_delete_marks': 'counter',
- 'Innodb_ibuf_merged_deletes': 'counter',
- 'Innodb_ibuf_merged_inserts': 'counter',
- 'Innodb_ibuf_merges': 'counter',
- 'Innodb_ibuf_segment_size': 'gauge',
- 'Innodb_ibuf_size': 'gauge',
- 'Innodb_lsn_current': 'counter',
- 'Innodb_lsn_flushed': 'counter',
- 'Innodb_max_trx_id': 'counter',
- 'Innodb_mem_adaptive_hash': 'gauge',
- 'Innodb_mem_dictionary': 'gauge',
- 'Innodb_mem_total': 'gauge',
- 'Innodb_mutex_os_waits': 'counter',
- 'Innodb_mutex_spin_rounds': 'counter',
- 'Innodb_mutex_spin_waits': 'counter',
- 'Innodb_os_log_pending_fsyncs': 'gauge',
- 'Innodb_pages_created': 'counter',
- 'Innodb_pages_read': 'counter',
- 'Innodb_pages_written': 'counter',
- 'Innodb_row_lock_time': 'counter',
- 'Innodb_row_lock_time_avg': 'gauge',
- 'Innodb_row_lock_time_max': 'gauge',
- 'Innodb_row_lock_waits': 'counter',
- 'Innodb_rows_deleted': 'counter',
- 'Innodb_rows_inserted': 'counter',
- 'Innodb_rows_read': 'counter',
- 'Innodb_rows_updated': 'counter',
- 'Innodb_s_lock_os_waits': 'counter',
- 'Innodb_s_lock_spin_rounds': 'counter',
- 'Innodb_s_lock_spin_waits': 'counter',
- 'Innodb_uncheckpointed_bytes': 'gauge',
- 'Innodb_unflushed_log': 'gauge',
- 'Innodb_unpurged_txns': 'gauge',
- 'Innodb_x_lock_os_waits': 'counter',
- 'Innodb_x_lock_spin_rounds': 'counter',
- 'Innodb_x_lock_spin_waits': 'counter',
- 'Key_blocks_not_flushed': 'gauge',
- 'Key_blocks_unused': 'gauge',
- 'Key_blocks_used': 'gauge',
- 'Key_read_requests': 'counter',
- 'Key_reads': 'counter',
- 'Key_write_requests': 'counter',
- 'Key_writes': 'counter',
- 'Max_used_connections': 'gauge',
- 'Open_files': 'gauge',
- 'Open_table_definitions': 'gauge',
- 'Open_tables': 'gauge',
- 'Opened_files': 'counter',
- 'Opened_table_definitions': 'counter',
- 'Opened_tables': 'counter',
- 'Qcache_free_blocks': 'gauge',
- 'Qcache_free_memory': 'gauge',
- 'Qcache_hits': 'counter',
- 'Qcache_inserts': 'counter',
- 'Qcache_lowmem_prunes': 'counter',
- 'Qcache_not_cached': 'counter',
- 'Qcache_queries_in_cache': 'counter',
- 'Qcache_total_blocks': 'counter',
- 'Questions': 'counter',
- 'Select_full_join': 'counter',
- 'Select_full_range_join': 'counter',
- 'Select_range': 'counter',
- 'Select_range_check': 'counter',
- 'Select_scan': 'counter',
- 'Slave_open_temp_tables': 'gauge',
- 'Slave_retried_transactions': 'counter',
- 'Slow_launch_threads': 'counter',
- 'Slow_queries': 'counter',
- 'Sort_merge_passes': 'counter',
- 'Sort_range': 'counter',
- 'Sort_rows': 'counter',
- 'Sort_scan': 'counter',
- 'Table_locks_immediate': 'counter',
- 'Table_locks_waited': 'counter',
- 'Table_open_cache_hits': 'counter',
- 'Table_open_cache_misses': 'counter',
- 'Table_open_cache_overflows': 'counter',
- 'Threadpool_idle_threads': 'gauge',
- 'Threadpool_threads': 'gauge',
- 'Threads_cached': 'gauge',
- 'Threads_connected': 'gauge',
- 'Threads_created': 'counter',
- 'Threads_running': 'gauge',
- 'Uptime': 'gauge',
- 'wsrep_apply_oooe': 'gauge',
- 'wsrep_apply_oool': 'gauge',
- 'wsrep_apply_window': 'gauge',
- 'wsrep_causal_reads': 'gauge',
- 'wsrep_cert_deps_distance': 'gauge',
- 'wsrep_cert_index_size': 'gauge',
- 'wsrep_cert_interval': 'gauge',
- 'wsrep_cluster_size': 'gauge',
- 'wsrep_commit_oooe': 'gauge',
- 'wsrep_commit_oool': 'gauge',
- 'wsrep_commit_window': 'gauge',
- 'wsrep_flow_control_paused': 'gauge',
- 'wsrep_flow_control_paused_ns': 'counter',
- 'wsrep_flow_control_recv': 'counter',
- 'wsrep_flow_control_sent': 'counter',
- 'wsrep_local_bf_aborts': 'counter',
- 'wsrep_local_cert_failures': 'counter',
- 'wsrep_local_commits': 'counter',
- 'wsrep_local_recv_queue': 'gauge',
- 'wsrep_local_recv_queue_avg': 'gauge',
- 'wsrep_local_recv_queue_max': 'gauge',
- 'wsrep_local_recv_queue_min': 'gauge',
- 'wsrep_local_replays': 'gauge',
- 'wsrep_local_send_queue': 'gauge',
- 'wsrep_local_send_queue_avg': 'gauge',
- 'wsrep_local_send_queue_max': 'gauge',
- 'wsrep_local_send_queue_min': 'gauge',
- 'wsrep_received': 'counter',
- 'wsrep_received_bytes': 'counter',
- 'wsrep_repl_data_bytes': 'counter',
- 'wsrep_repl_keys': 'counter',
- 'wsrep_repl_keys_bytes': 'counter',
- 'wsrep_repl_other_bytes': 'counter',
- 'wsrep_replicated': 'counter',
- 'wsrep_replicated_bytes': 'counter',
+ 'Aborted_clients': 'counter',
+ 'Aborted_connects': 'counter',
+ 'Binlog_cache_disk_use': 'counter',
+ 'Binlog_cache_use': 'counter',
+ 'Bytes_received': 'counter',
+ 'Bytes_sent': 'counter',
+ 'Connections': 'counter',
+ 'Created_tmp_disk_tables': 'counter',
+ 'Created_tmp_files': 'counter',
+ 'Created_tmp_tables': 'counter',
+ 'Innodb_buffer_pool_pages_data': 'gauge',
+ 'Innodb_buffer_pool_pages_dirty': 'gauge',
+ 'Innodb_buffer_pool_pages_free': 'gauge',
+ 'Innodb_buffer_pool_pages_total': 'gauge',
+ 'Innodb_buffer_pool_read_requests': 'counter',
+ 'Innodb_buffer_pool_reads': 'counter',
+ 'Innodb_checkpoint_age': 'gauge',
+ 'Innodb_checkpoint_max_age': 'gauge',
+ 'Innodb_data_fsyncs': 'counter',
+ 'Innodb_data_pending_fsyncs': 'gauge',
+ 'Innodb_data_pending_reads': 'gauge',
+ 'Innodb_data_pending_writes': 'gauge',
+ 'Innodb_data_read': 'counter',
+ 'Innodb_data_reads': 'counter',
+ 'Innodb_data_writes': 'counter',
+ 'Innodb_data_written': 'counter',
+ 'Innodb_deadlocks': 'counter',
+ 'Innodb_history_list_length': 'gauge',
+ 'Innodb_ibuf_free_list': 'gauge',
+ 'Innodb_ibuf_merged_delete_marks': 'counter',
+ 'Innodb_ibuf_merged_deletes': 'counter',
+ 'Innodb_ibuf_merged_inserts': 'counter',
+ 'Innodb_ibuf_merges': 'counter',
+ 'Innodb_ibuf_segment_size': 'gauge',
+ 'Innodb_ibuf_size': 'gauge',
+ 'Innodb_lsn_current': 'counter',
+ 'Innodb_lsn_flushed': 'counter',
+ 'Innodb_max_trx_id': 'counter',
+ 'Innodb_mem_adaptive_hash': 'gauge',
+ 'Innodb_mem_dictionary': 'gauge',
+ 'Innodb_mem_total': 'gauge',
+ 'Innodb_mutex_os_waits': 'counter',
+ 'Innodb_mutex_spin_rounds': 'counter',
+ 'Innodb_mutex_spin_waits': 'counter',
+ 'Innodb_os_log_pending_fsyncs': 'gauge',
+ 'Innodb_pages_created': 'counter',
+ 'Innodb_pages_read': 'counter',
+ 'Innodb_pages_written': 'counter',
+ 'Innodb_row_lock_time': 'counter',
+ 'Innodb_row_lock_time_avg': 'gauge',
+ 'Innodb_row_lock_time_max': 'gauge',
+ 'Innodb_row_lock_waits': 'counter',
+ 'Innodb_rows_deleted': 'counter',
+ 'Innodb_rows_inserted': 'counter',
+ 'Innodb_rows_read': 'counter',
+ 'Innodb_rows_updated': 'counter',
+ 'Innodb_s_lock_os_waits': 'counter',
+ 'Innodb_s_lock_spin_rounds': 'counter',
+ 'Innodb_s_lock_spin_waits': 'counter',
+ 'Innodb_uncheckpointed_bytes': 'gauge',
+ 'Innodb_unflushed_log': 'gauge',
+ 'Innodb_unpurged_txns': 'gauge',
+ 'Innodb_x_lock_os_waits': 'counter',
+ 'Innodb_x_lock_spin_rounds': 'counter',
+ 'Innodb_x_lock_spin_waits': 'counter',
+ 'Key_blocks_not_flushed': 'gauge',
+ 'Key_blocks_unused': 'gauge',
+ 'Key_blocks_used': 'gauge',
+ 'Key_read_requests': 'counter',
+ 'Key_reads': 'counter',
+ 'Key_write_requests': 'counter',
+ 'Key_writes': 'counter',
+ 'Max_used_connections': 'gauge',
+ 'Open_files': 'gauge',
+ 'Open_table_definitions': 'gauge',
+ 'Open_tables': 'gauge',
+ 'Opened_files': 'counter',
+ 'Opened_table_definitions': 'counter',
+ 'Opened_tables': 'counter',
+ 'Qcache_free_blocks': 'gauge',
+ 'Qcache_free_memory': 'gauge',
+ 'Qcache_hits': 'counter',
+ 'Qcache_inserts': 'counter',
+ 'Qcache_lowmem_prunes': 'counter',
+ 'Qcache_not_cached': 'counter',
+ 'Qcache_queries_in_cache': 'counter',
+ 'Qcache_total_blocks': 'counter',
+ 'Questions': 'counter',
+ 'Select_full_join': 'counter',
+ 'Select_full_range_join': 'counter',
+ 'Select_range': 'counter',
+ 'Select_range_check': 'counter',
+ 'Select_scan': 'counter',
+ 'Slave_open_temp_tables': 'gauge',
+ 'Slave_retried_transactions': 'counter',
+ 'Slow_launch_threads': 'counter',
+ 'Slow_queries': 'counter',
+ 'Sort_merge_passes': 'counter',
+ 'Sort_range': 'counter',
+ 'Sort_rows': 'counter',
+ 'Sort_scan': 'counter',
+ 'Table_locks_immediate': 'counter',
+ 'Table_locks_waited': 'counter',
+ 'Table_open_cache_hits': 'counter',
+ 'Table_open_cache_misses': 'counter',
+ 'Table_open_cache_overflows': 'counter',
+ 'Threadpool_idle_threads': 'gauge',
+ 'Threadpool_threads': 'gauge',
+ 'Threads_cached': 'gauge',
+ 'Threads_connected': 'gauge',
+ 'Threads_created': 'counter',
+ 'Threads_running': 'gauge',
+ 'Uptime': 'gauge',
+ 'wsrep_apply_oooe': 'gauge',
+ 'wsrep_apply_oool': 'gauge',
+ 'wsrep_apply_window': 'gauge',
+ 'wsrep_causal_reads': 'gauge',
+ 'wsrep_cert_deps_distance': 'gauge',
+ 'wsrep_cert_index_size': 'gauge',
+ 'wsrep_cert_interval': 'gauge',
+ 'wsrep_cluster_size': 'gauge',
+ 'wsrep_commit_oooe': 'gauge',
+ 'wsrep_commit_oool': 'gauge',
+ 'wsrep_commit_window': 'gauge',
+ 'wsrep_flow_control_paused': 'gauge',
+ 'wsrep_flow_control_paused_ns': 'counter',
+ 'wsrep_flow_control_recv': 'counter',
+ 'wsrep_flow_control_sent': 'counter',
+ 'wsrep_local_bf_aborts': 'counter',
+ 'wsrep_local_cert_failures': 'counter',
+ 'wsrep_local_commits': 'counter',
+ 'wsrep_local_recv_queue': 'gauge',
+ 'wsrep_local_recv_queue_avg': 'gauge',
+ 'wsrep_local_recv_queue_max': 'gauge',
+ 'wsrep_local_recv_queue_min': 'gauge',
+ 'wsrep_local_replays': 'gauge',
+ 'wsrep_local_send_queue': 'gauge',
+ 'wsrep_local_send_queue_avg': 'gauge',
+ 'wsrep_local_send_queue_max': 'gauge',
+ 'wsrep_local_send_queue_min': 'gauge',
+ 'wsrep_received': 'counter',
+ 'wsrep_received_bytes': 'counter',
+ 'wsrep_repl_data_bytes': 'counter',
+ 'wsrep_repl_keys': 'counter',
+ 'wsrep_repl_keys_bytes': 'counter',
+ 'wsrep_repl_other_bytes': 'counter',
+ 'wsrep_replicated': 'counter',
+ 'wsrep_replicated_bytes': 'counter',
}
MYSQL_VARS = [
- 'binlog_stmt_cache_size',
- 'innodb_additional_mem_pool_size',
- 'innodb_buffer_pool_size',
- 'innodb_concurrency_tickets',
- 'innodb_io_capacity',
- 'innodb_log_buffer_size',
- 'innodb_log_file_size',
- 'innodb_open_files',
- 'innodb_open_files',
- 'join_buffer_size',
- 'max_connections',
- 'open_files_limit',
- 'query_cache_limit',
- 'query_cache_size',
- 'query_cache_size',
- 'read_buffer_size',
- 'table_cache',
- 'table_definition_cache',
- 'table_open_cache',
- 'thread_cache_size',
- 'thread_cache_size',
- 'thread_concurrency',
- 'tmp_table_size',
+ 'binlog_stmt_cache_size',
+ 'innodb_additional_mem_pool_size',
+ 'innodb_buffer_pool_size',
+ 'innodb_concurrency_tickets',
+ 'innodb_io_capacity',
+ 'innodb_log_buffer_size',
+ 'innodb_log_file_size',
+ 'innodb_open_files',
+ 'innodb_open_files',
+ 'join_buffer_size',
+ 'max_connections',
+ 'open_files_limit',
+ 'query_cache_limit',
+ 'query_cache_size',
+ 'query_cache_size',
+ 'read_buffer_size',
+ 'read_only',
+ 'table_cache',
+ 'table_definition_cache',
+ 'table_open_cache',
+ 'thread_cache_size',
+ 'thread_cache_size',
+ 'thread_concurrency',
+ 'tmp_table_size',
]
MYSQL_PROCESS_STATES = {
- 'closing_tables': 0,
- 'copying_to_tmp_table': 0,
- 'end': 0,
- 'freeing_items': 0,
- 'init': 0,
- 'locked': 0,
- 'login': 0,
- 'none': 0,
- 'other': 0,
- 'preparing': 0,
- 'reading_from_net': 0,
- 'sending_data': 0,
- 'sorting_result': 0,
- 'statistics': 0,
- 'updating': 0,
- 'writing_to_net': 0,
- 'creating_table': 0,
- 'opening_tables': 0,
+ 'closing_tables': 0,
+ 'copying_to_tmp_table': 0,
+ 'end': 0,
+ 'freeing_items': 0,
+ 'init': 0,
+ 'locked': 0,
+ 'login': 0,
+ 'none': 0,
+ 'other': 0,
+ 'preparing': 0,
+ 'reading_from_net': 0,
+ 'sending_data': 0,
+ 'sorting_result': 0,
+ 'statistics': 0,
+ 'updating': 0,
+ 'writing_to_net': 0,
+ 'creating_table': 0,
+ 'opening_tables': 0,
}
MYSQL_INNODB_STATUS_VARS = {
- 'active_transactions': 'gauge',
- 'current_transactions': 'gauge',
- 'file_reads': 'counter',
- 'file_system_memory': 'gauge',
- 'file_writes': 'counter',
- 'innodb_lock_structs': 'gauge',
- 'innodb_lock_wait_secs': 'gauge',
- 'innodb_locked_tables': 'gauge',
- 'innodb_sem_wait_time_ms': 'gauge',
- 'innodb_sem_waits': 'gauge',
- 'innodb_tables_in_use': 'gauge',
- 'lock_system_memory': 'gauge',
- 'locked_transactions': 'gauge',
- 'log_writes': 'counter',
- 'page_hash_memory': 'gauge',
- 'pending_aio_log_ios': 'gauge',
- 'pending_buf_pool_flushes': 'gauge',
- 'pending_chkp_writes': 'gauge',
- 'pending_ibuf_aio_reads': 'gauge',
- 'pending_log_writes':'gauge',
- 'queries_inside': 'gauge',
- 'queries_queued': 'gauge',
- 'read_views': 'gauge',
+ 'active_transactions': 'gauge',
+ 'current_transactions': 'gauge',
+ 'file_reads': 'counter',
+ 'file_system_memory': 'gauge',
+ 'file_writes': 'counter',
+ 'innodb_lock_structs': 'gauge',
+ 'innodb_lock_wait_secs': 'gauge',
+ 'innodb_locked_tables': 'gauge',
+ 'innodb_sem_wait_time_ms': 'gauge',
+ 'innodb_sem_waits': 'gauge',
+ 'innodb_tables_in_use': 'gauge',
+ 'lock_system_memory': 'gauge',
+ 'locked_transactions': 'gauge',
+ 'log_writes': 'counter',
+ 'page_hash_memory': 'gauge',
+ 'pending_aio_log_ios': 'gauge',
+ 'pending_buf_pool_flushes': 'gauge',
+ 'pending_chkp_writes': 'gauge',
+ 'pending_ibuf_aio_reads': 'gauge',
+ 'pending_log_writes': 'gauge',
+ 'queries_inside': 'gauge',
+ 'queries_queued': 'gauge',
+ 'read_views': 'gauge',
}
MYSQL_INNODB_STATUS_MATCHES = {
- # 0 read views open inside InnoDB
- 'read views open inside InnoDB': {
- 'read_views': 0,
- },
- # 5635328 OS file reads, 27018072 OS file writes, 20170883 OS fsyncs
- ' OS file reads, ': {
- 'file_reads': 0,
- 'file_writes': 4,
- },
- # ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
- 'ibuf aio reads': {
- 'pending_ibuf_aio_reads': 3,
- 'pending_aio_log_ios': 6,
- 'pending_aio_sync_ios': 9,
- },
- # Pending flushes (fsync) log: 0; buffer pool: 0
- 'Pending flushes (fsync)': {
- 'pending_buf_pool_flushes': 7,
- },
- # 16086708 log i/o's done, 106.07 log i/o's/second
- " log i/o's done, ": {
- 'log_writes': 0,
- },
- # 0 pending log writes, 0 pending chkp writes
- ' pending log writes, ': {
- 'pending_log_writes': 0,
- 'pending_chkp_writes': 4,
- },
- # Page hash 2302856 (buffer pool 0 only)
- 'Page hash ': {
- 'page_hash_memory': 2,
- },
- # File system 657820264 (812272 + 657007992)
- 'File system ': {
- 'file_system_memory': 2,
- },
- # Lock system 143820296 (143819576 + 720)
- 'Lock system ': {
- 'lock_system_memory': 2,
- },
- # 0 queries inside InnoDB, 0 queries in queue
- 'queries inside InnoDB, ': {
- 'queries_inside': 0,
- 'queries_queued': 4,
- },
- # --Thread 139954487744256 has waited at dict0dict.cc line 472 for 0.0000 seconds the semaphore:
- 'seconds the semaphore': {
- 'innodb_sem_waits': lambda row, stats: stats['innodb_sem_waits'] + 1,
- 'innodb_sem_wait_time_ms': lambda row, stats: int(float(row[9]) * 1000),
- },
- # mysql tables in use 1, locked 1
- 'mysql tables in use': {
- 'innodb_tables_in_use': lambda row, stats: stats['innodb_tables_in_use'] + int(row[4]),
- 'innodb_locked_tables': lambda row, stats: stats['innodb_locked_tables'] + int(row[6]),
- },
- "------- TRX HAS BEEN": {
- "innodb_lock_wait_secs": lambda row, stats: stats['innodb_lock_wait_secs'] + int(row[5]),
- },
+ # 0 read views open inside InnoDB
+ 'read views open inside InnoDB': {
+ 'read_views': 0,
+ },
+ # 5635328 OS file reads, 27018072 OS file writes, 20170883 OS fsyncs
+ ' OS file reads, ': {
+ 'file_reads': 0,
+ 'file_writes': 4,
+ },
+ # ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
+ 'ibuf aio reads': {
+ 'pending_ibuf_aio_reads': 3,
+ 'pending_aio_log_ios': 6,
+ 'pending_aio_sync_ios': 9,
+ },
+ # Pending flushes (fsync) log: 0; buffer pool: 0
+ 'Pending flushes (fsync)': {
+ 'pending_buf_pool_flushes': 7,
+ },
+ # 16086708 log i/o's done, 106.07 log i/o's/second
+ " log i/o's done, ": {
+ 'log_writes': 0,
+ },
+ # 0 pending log writes, 0 pending chkp writes
+ ' pending log writes, ': {
+ 'pending_log_writes': 0,
+ 'pending_chkp_writes': 4,
+ },
+ # Page hash 2302856 (buffer pool 0 only)
+ 'Page hash ': {
+ 'page_hash_memory': 2,
+ },
+ # File system 657820264 (812272 + 657007992)
+ 'File system ': {
+ 'file_system_memory': 2,
+ },
+ # Lock system 143820296 (143819576 + 720)
+ 'Lock system ': {
+ 'lock_system_memory': 2,
+ },
+ # 0 queries inside InnoDB, 0 queries in queue
+ 'queries inside InnoDB, ': {
+ 'queries_inside': 0,
+ 'queries_queued': 4,
+ },
+ # --Thread 139954487744256 has waited at dict0dict.cc line 472 for 0.0000 seconds the semaphore:
+ 'seconds the semaphore': {
+ 'innodb_sem_waits': lambda row, stats: stats['innodb_sem_waits'] + 1,
+ 'innodb_sem_wait_time_ms': lambda row, stats: int(float(row[9]) * 1000),
+ },
+ # mysql tables in use 1, locked 1
+ 'mysql tables in use': {
+ 'innodb_tables_in_use': lambda row, stats: stats['innodb_tables_in_use'] + int(row[4]),
+ 'innodb_locked_tables': lambda row, stats: stats['innodb_locked_tables'] + int(row[6]),
+ },
+ "------- TRX HAS BEEN": {
+ "innodb_lock_wait_secs": lambda row, stats: stats['innodb_lock_wait_secs'] + int(row[5]),
+ },
}
+
def get_mysql_conn():
- return MySQLdb.connect(
- host=MYSQL_CONFIG['Host'],
- port=MYSQL_CONFIG['Port'],
- user=MYSQL_CONFIG['User'],
- passwd=MYSQL_CONFIG['Password']
- )
+ """ Get connection parameters """
+ return pymysql.connect(
+ host=MYSQL_CONFIG['Host'],
+ port=MYSQL_CONFIG['Port'],
+ user=MYSQL_CONFIG['User'],
+ passwd=MYSQL_CONFIG['Password']
+ )
+
def mysql_query(conn, query):
- cur = conn.cursor(MySQLdb.cursors.DictCursor)
- cur.execute(query)
- return cur
+ """ Function to run MySQL queries """
+ cur = conn.cursor(pymysql.cursors.DictCursor)
+ cur.execute(query)
+ return cur
+
def fetch_mysql_status(conn):
- result = mysql_query(conn, 'SHOW GLOBAL STATUS')
- status = {}
- for row in result.fetchall():
- status[row['Variable_name']] = row['Value']
+ """ Fetch global status variables """
+ result = mysql_query(conn, 'SHOW GLOBAL STATUS')
+ status = {}
+ for row in result.fetchall():
+ status[row['Variable_name']] = row['Value']
+
+ # calculate the number of unpurged txns from existing variables
+ if 'Innodb_max_trx_id' in status and 'Innodb_purge_trx_id' in status:
+ status['Innodb_unpurged_txns'] = int(status['Innodb_max_trx_id']) - int(status['Innodb_purge_trx_id'])
- # calculate the number of unpurged txns from existing variables
- if 'Innodb_max_trx_id' in status:
- status['Innodb_unpurged_txns'] = int(status['Innodb_max_trx_id']) - int(status['Innodb_purge_trx_id'])
+ if 'Innodb_lsn_last_checkpoint' in status:
+ status['Innodb_uncheckpointed_bytes'] = int(status['Innodb_lsn_current']) - int(status['Innodb_lsn_last_checkpoint'])
- if 'Innodb_lsn_last_checkpoint' in status:
- status['Innodb_uncheckpointed_bytes'] = int(status['Innodb_lsn_current'])- int(status['Innodb_lsn_last_checkpoint'])
+ if 'Innodb_lsn_flushed' in status:
+ status['Innodb_unflushed_log'] = int(status['Innodb_lsn_current']) - int(status['Innodb_lsn_flushed'])
- if 'Innodb_lsn_flushed' in status:
- status['Innodb_unflushed_log'] = int(status['Innodb_lsn_current']) - int(status['Innodb_lsn_flushed'])
+ return status
- return status
def fetch_mysql_master_stats(conn):
- try:
- result = mysql_query(conn, 'SHOW BINARY LOGS')
- except MySQLdb.OperationalError:
- return {}
+ """ Fetch master information """
+ try:
+ result = mysql_query(conn, 'SHOW BINARY LOGS')
+ except pymysql.OperationalError:
+ return {}
- stats = {
- 'binary_log_space': 0,
- }
+ stats = {
+ 'binary_log_space': 0,
+ }
- for row in result.fetchall():
- if 'File_size' in row and row['File_size'] > 0:
- stats['binary_log_space'] += int(row['File_size'])
+ for row in result.fetchall():
+ if 'File_size' in row and row['File_size'] > 0:
+ stats['binary_log_space'] += int(row['File_size'])
+
+ return stats
- return stats
def fetch_mysql_slave_stats(conn):
- result = mysql_query(conn, 'SHOW SLAVE STATUS')
- slave_row = result.fetchone()
- if slave_row is None:
- return {}
-
- status = {
- 'relay_log_space': slave_row['Relay_Log_Space'],
- 'slave_lag': slave_row['Seconds_Behind_Master'] if slave_row['Seconds_Behind_Master'] != None else 0,
- }
-
- if MYSQL_CONFIG['HeartbeatTable']:
- query = """
- SELECT MAX(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts)) AS delay
- FROM %s
- WHERE server_id = %s
- """ % (MYSQL_CONFIG['HeartbeatTable'], slave_row['Master_Server_Id'])
- result = mysql_query(conn, query)
- row = result.fetchone()
- if 'delay' in row and row['delay'] != None:
- status['slave_lag'] = row['delay']
-
- status['slave_running'] = 1 if slave_row['Slave_SQL_Running'] == 'Yes' else 0
- status['slave_stopped'] = 1 if slave_row['Slave_SQL_Running'] != 'Yes' else 0
- return status
+ """ Fetch slave status """
+ result = mysql_query(conn, 'SHOW SLAVE STATUS')
+ slave_row = result.fetchone()
+ if slave_row is None:
+ return {}
+
+ status = {
+ 'relay_log_space': slave_row['Relay_Log_Space'],
+ 'slave_lag': slave_row['Seconds_Behind_Master'] if slave_row['Seconds_Behind_Master'] is not None else 0,
+ }
+
+ if MYSQL_CONFIG['HeartbeatTable']:
+ query = """
+ SELECT MAX(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts)) AS delay
+ FROM %s
+ WHERE server_id = %s
+ """ % (MYSQL_CONFIG['HeartbeatTable'], slave_row['Master_Server_Id'])
+ result = mysql_query(conn, query)
+ row = result.fetchone()
+ if 'delay' in row and row['delay'] is not None:
+ status['slave_lag'] = row['delay']
+
+ status['slave_running'] = 1 if slave_row['Slave_SQL_Running'] == 'Yes' and slave_row['Slave_IO_Running'] == 'Yes' else 0
+ status['slave_stopped'] = 1 if slave_row['Slave_SQL_Running'] != 'Yes' or slave_row['Slave_IO_Running'] != 'Yes' else 0
+ return status
+
+
+def fetch_mysql_db_size(conn):
+ """ Fetch database size """
+ result = mysql_query(
+ conn,
+ "SELECT table_schema 'db_name', Round(Sum(data_length + index_length) / 1024 / 1024, 0) 'db_size_mb' "
+ "FROM information_schema.tables "
+ "WHERE table_schema not in ('mysql', 'information_schema', 'performance_schema', 'heartbeat') "
+ "GROUP BY table_schema;"
+ )
+
+ stats = {}
+ for row in result.fetchall():
+ stats[row['db_name']] = row['db_size_mb']
+ return stats
+
+
+def fetch_innodb_os_log_bytes_written(conn):
+ """ Fetch innodb metric os_log_bytes_written """
+ # This feature is only available for mariaDB >= 10.x and MySQL > 5.5.
+ try:
+ result = mysql_query(
+ conn,
+ "SELECT COUNT from INFORMATION_SCHEMA.INNODB_METRICS "
+ "WHERE name ='os_log_bytes_written';"
+ )
+ stats = result.fetchone()
+ except pymysql.OperationalError:
+ stats = {'COUNT': 0}
+ return stats
+
+
+def fetch_mysql_lock(conn):
+ """ Fetch MySQL lock """
+ # This feature is only available for mariaDB with plugin METADATA_LOCK_INFO installed
+ try:
+ result = mysql_query(
+ conn,
+ "SELECT count(1) as `nb_lock` "
+ "FROM INFORMATION_SCHEMA.PROCESSLIST P, INFORMATION_SCHEMA.METADATA_LOCK_INFO M "
+ "WHERE LOCATE(lcase(M.LOCK_TYPE), lcase(P.STATE))>0;"
+ )
+ stats = result.fetchone()
+ except pymysql.OperationalError:
+ stats = {'nb_lock': 0}
+ return stats
+
def fetch_mysql_process_states(conn):
- global MYSQL_PROCESS_STATES
- result = mysql_query(conn, 'SHOW PROCESSLIST')
- states = MYSQL_PROCESS_STATES.copy()
- for row in result.fetchall():
- state = row['State']
- if state == '' or state == None: state = 'none'
- state = re.sub(r'^(Table lock|Waiting for .*lock)$', "Locked", state)
- state = state.lower().replace(" ", "_")
- if state not in states: state = 'other'
- states[state] += 1
-
- return states
+ """ Fetch process states """
+ global MYSQL_PROCESS_STATES
+ result = mysql_query(conn, 'SHOW PROCESSLIST')
+ states = MYSQL_PROCESS_STATES.copy()
+ for row in result.fetchall():
+ state = row['State']
+ if state == '' or state is None:
+ state = 'none'
+ state = re.sub(r'^(Table lock|Waiting for .*lock)$', "Locked", state)
+ state = state.lower().replace(" ", "_")
+ if state not in states:
+ state = 'other'
+ states[state] += 1
+ return states
+
def fetch_mysql_variables(conn):
- global MYSQL_VARS
- result = mysql_query(conn, 'SHOW GLOBAL VARIABLES')
- variables = {}
- for row in result.fetchall():
- if row['Variable_name'] in MYSQL_VARS:
- variables[row['Variable_name']] = row['Value']
+ """ Fetch defined MySQL variables """
+ global MYSQL_VARS
+ result = mysql_query(conn, 'SHOW GLOBAL VARIABLES')
+ variables = {}
+ for row in result.fetchall():
+ if row['Variable_name'] in MYSQL_VARS:
+ variables[row['Variable_name']] = row['Value']
+
+ return variables
+
+
+def is_ps_enabled(conn):
+ """ Check is performance_schema is enabled """
+ result = mysql_query(conn, 'SHOW GLOBAL VARIABLES LIKE "performance_schema"')
+ row = result.fetchone()
+ return bool(row['Value'] == 'ON')
+
+
+def fetch_connections_per_account(conn):
+ """ Fetch number of connections per account """
+ queries = {}
+ try:
+ result = mysql_query(conn, """
+ SELECT user, sum(current_connections) as `cur_conn`
+ FROM performance_schema.accounts
+ WHERE user is not null
+ GROUP BY user;
+ """)
+ for row in result.fetchall():
+ user = str(row['user'])
+ queries[user] = row['cur_conn']
+
+ except pymysql.OperationalError:
+ return {}
+
+ return queries
- return variables
def fetch_mysql_response_times(conn):
- response_times = {}
- try:
- result = mysql_query(conn, """
- SELECT *
- FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME
- WHERE `time` != 'TOO LONG'
- ORDER BY `time`
- """)
- except MySQLdb.OperationalError:
- return {}
-
- for i in range(1, 14):
- row = result.fetchone()
-
- # fill in missing rows with zeros
- if not row:
- row = { 'count': 0, 'total': 0 }
-
- row = {key.lower(): val for key, val in row.items()}
-
- response_times[i] = {
- 'time': float(row['time']),
- 'count': int(row['count']),
- 'total': round(float(row['total']) * 1000000, 0),
- }
-
- return response_times
+ """ Fetch mysql response time from percona plugin """
+ response_times = {}
+ try:
+ result = mysql_query(conn, """
+ SELECT *
+ FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME
+ WHERE `time` != 'TOO LONG'
+ ORDER BY `time`
+ """)
+ except pymysql.OperationalError:
+ return {}
+
+ for i in range(1, 14):
+ row = result.fetchone()
+
+ # fill in missing rows with zeros
+ if not row:
+ row = {'count': 0, 'total': 0}
+
+ row = {key.lower(): val for key, val in row.items()}
+
+ response_times[i] = {
+ 'time': float(row['time']),
+ 'count': int(row['count']),
+ 'total': round(float(row['total']) * 1000000, 0),
+ }
+
+ return response_times
+
def fetch_innodb_stats(conn):
- global MYSQL_INNODB_STATUS_MATCHES, MYSQL_INNODB_STATUS_VARS
- result = mysql_query(conn, 'SHOW ENGINE INNODB STATUS')
- row = result.fetchone()
- status = row['Status']
- stats = dict.fromkeys(MYSQL_INNODB_STATUS_VARS.keys(), 0)
-
- for line in status.split("\n"):
- line = line.strip()
- row = re.split(r' +', re.sub(r'[,;] ', ' ', line))
- if line == '': continue
-
- # ---TRANSACTION 124324402462, not started
- # ---TRANSACTION 124324402468, ACTIVE 0 sec committing
- if line.find("---TRANSACTION") != -1:
- stats['current_transactions'] += 1
- if line.find("ACTIVE") != -1:
- stats['active_transactions'] += 1
- # LOCK WAIT 228 lock struct(s), heap size 46632, 65 row lock(s), undo log entries 1
- # 205 lock struct(s), heap size 30248, 37 row lock(s), undo log entries 1
- elif line.find("lock struct(s)") != -1:
- if line.find("LOCK WAIT") != -1:
- stats['innodb_lock_structs'] += int(row[2])
- stats['locked_transactions'] += 1
- else:
- stats['innodb_lock_structs'] += int(row[0])
- else:
- for match in MYSQL_INNODB_STATUS_MATCHES:
- if line.find(match) == -1: continue
- for key in MYSQL_INNODB_STATUS_MATCHES[match]:
- value = MYSQL_INNODB_STATUS_MATCHES[match][key]
- if type(value) is int:
- if value < len(row) and row[value].isdigit():
- stats[key] = int(row[value])
- else:
- stats[key] = value(row, stats)
- break
-
- return stats
+ """ Fetch innodb statistics """
+ global MYSQL_INNODB_STATUS_MATCHES, MYSQL_INNODB_STATUS_VARS
+ result = mysql_query(conn, 'SHOW ENGINE INNODB STATUS')
+ row = result.fetchone()
+ status = row['Status']
+ stats = dict.fromkeys(MYSQL_INNODB_STATUS_VARS.keys(), 0)
+
+ for line in status.split("\n"):
+ line = line.strip()
+ row = re.split(r' +', re.sub(r'[,;] ', ' ', line))
+ if line == '':
+ continue
+
+ # ---TRANSACTION 124324402462, not started
+ # ---TRANSACTION 124324402468, ACTIVE 0 sec committing
+ if line.find("---TRANSACTION") != -1:
+ stats['current_transactions'] += 1
+ if line.find("ACTIVE") != -1:
+ stats['active_transactions'] += 1
+ # LOCK WAIT 228 lock struct(s), heap size 46632, 65 row lock(s), undo log entries 1
+ # 205 lock struct(s), heap size 30248, 37 row lock(s), undo log entries 1
+ elif line.find("lock struct(s)") != -1:
+ if line.find("LOCK WAIT") != -1:
+ stats['innodb_lock_structs'] += int(row[2])
+ stats['locked_transactions'] += 1
+ else:
+ stats['innodb_lock_structs'] += int(row[0])
+ else:
+ for match in MYSQL_INNODB_STATUS_MATCHES:
+ if line.find(match) == -1:
+ continue
+ for key in MYSQL_INNODB_STATUS_MATCHES[match]:
+ value = MYSQL_INNODB_STATUS_MATCHES[match][key]
+ if isinstance(value, int):
+ if value < len(row) and row[value].isdigit():
+ stats[key] = int(row[value])
+ else:
+ stats[key] = value(row, stats)
+ break
+
+ return stats
+
+
+def get_mysql_version(conn):
+ """ Get MySQL version """
+ try:
+ result = mysql_query(conn, "SELECT VERSION()")
+ mysql_version = result.fetchone()
+ except pymysql.OperationalError:
+ return {}
+ return mysql_version['VERSION()']
+
def log_verbose(msg):
- if not MYSQL_CONFIG['Verbose']:
- return
- if COLLECTD_ENABLED:
- collectd.info('mysql plugin: %s' % msg)
- else:
- print('mysql plugin: %s' % msg)
+ """ To enable verbose mode """
+ if not MYSQL_CONFIG['Verbose']:
+ return
+ if COLLECTD_ENABLED:
+ collectd.info('mysql plugin: %s' % msg)
+ else:
+ print('mysql plugin: %s' % msg)
+
def dispatch_value(prefix, key, value, type, type_instance=None):
- if not type_instance:
- type_instance = key
-
- log_verbose('Sending value: %s/%s=%s' % (prefix, type_instance, value))
- if value is None:
- return
- try:
- value = int(value)
- except ValueError:
- value = float(value)
-
- if COLLECTD_ENABLED:
- val = collectd.Values(plugin='mysql', plugin_instance=prefix)
- val.type = type
- val.type_instance = type_instance
- val.values = [value]
- val.dispatch()
+ """ Dispatch metrics """
+ if not type_instance:
+ type_instance = key
+
+ log_verbose('Sending value: %s/%s=%s' % (prefix, type_instance, value))
+ if value is None:
+ return
+ try:
+ value = int(value)
+ except ValueError:
+ value = float(value)
+
+ if COLLECTD_ENABLED:
+ val = collectd.Values(plugin='mysql', plugin_instance=prefix)
+ val.type = type
+ val.type_instance = type_instance
+ val.values = [value]
+ val.dispatch()
+
def configure_callback(conf):
- global MYSQL_CONFIG
- for node in conf.children:
- if node.key in MYSQL_CONFIG:
- MYSQL_CONFIG[node.key] = node.values[0]
+ """ Config callback """
+ global MYSQL_CONFIG
+ for node in conf.children:
+ if node.key in MYSQL_CONFIG:
+ MYSQL_CONFIG[node.key] = node.values[0]
+
+ MYSQL_CONFIG['Port'] = int(MYSQL_CONFIG['Port'])
+ MYSQL_CONFIG['Verbose'] = bool(MYSQL_CONFIG['Verbose'])
- MYSQL_CONFIG['Port'] = int(MYSQL_CONFIG['Port'])
- MYSQL_CONFIG['Verbose'] = bool(MYSQL_CONFIG['Verbose'])
def read_callback():
- global MYSQL_STATUS_VARS
- conn = get_mysql_conn()
-
- mysql_status = fetch_mysql_status(conn)
- for key in mysql_status:
- if mysql_status[key] == '': mysql_status[key] = 0
-
- # collect anything beginning with Com_/Handler_ as these change
- # regularly between mysql versions and this is easier than a fixed
- # list
- if key.split('_', 2)[0] in ['Com', 'Handler']:
- ds_type = 'counter'
- elif key in MYSQL_STATUS_VARS:
- ds_type = MYSQL_STATUS_VARS[key]
- else:
- continue
-
- dispatch_value('status', key, mysql_status[key], ds_type)
-
- mysql_variables = fetch_mysql_variables(conn)
- for key in mysql_variables:
- dispatch_value('variables', key, mysql_variables[key], 'gauge')
-
- mysql_master_status = fetch_mysql_master_stats(conn)
- for key in mysql_master_status:
- dispatch_value('master', key, mysql_master_status[key], 'gauge')
-
- mysql_states = fetch_mysql_process_states(conn)
- for key in mysql_states:
- dispatch_value('state', key, mysql_states[key], 'gauge')
-
- slave_status = fetch_mysql_slave_stats(conn)
- for key in slave_status:
- dispatch_value('slave', key, slave_status[key], 'gauge')
-
- response_times = fetch_mysql_response_times(conn)
- for key in response_times:
- dispatch_value('response_time_total', str(key), response_times[key]['total'], 'counter')
- dispatch_value('response_time_count', str(key), response_times[key]['count'], 'counter')
-
- innodb_status = fetch_innodb_stats(conn)
- for key in MYSQL_INNODB_STATUS_VARS:
- if key not in innodb_status: continue
- dispatch_value('innodb', key, innodb_status[key], MYSQL_INNODB_STATUS_VARS[key])
+ """ Everything is happenning here """
+ global MYSQL_STATUS_VARS
+ conn = get_mysql_conn()
+
+ mysql_status = fetch_mysql_status(conn)
+ for key in mysql_status:
+ if mysql_status[key] == '':
+ mysql_status[key] = 0
+ # collect anything beginning with Com_/Handler_ as these change
+ # regularly between mysql versions and this is easier than a fixed
+ # list
+ if key.split('_', 2)[0] in ['Com', 'Handler']:
+ ds_type = 'counter'
+ elif key in MYSQL_STATUS_VARS:
+ ds_type = MYSQL_STATUS_VARS[key]
+ else:
+ continue
+
+ dispatch_value('status', key, mysql_status[key], ds_type)
+
+ mysql_variables = fetch_mysql_variables(conn)
+ for key in mysql_variables:
+ if mysql_variables[key] == 'ON':
+ mysql_variables[key] = 1
+ elif mysql_variables[key] == 'OFF':
+ mysql_variables[key] = 0
+
+ dispatch_value('variables', key, mysql_variables[key], 'gauge')
+
+ mysql_master_status = fetch_mysql_master_stats(conn)
+ for key in mysql_master_status:
+ dispatch_value('master', key, mysql_master_status[key], 'gauge')
+
+ mysql_states = fetch_mysql_process_states(conn)
+ for key in mysql_states:
+ dispatch_value('state', key, mysql_states[key], 'gauge')
+
+ slave_status = fetch_mysql_slave_stats(conn)
+ for key in slave_status:
+ dispatch_value('slave', key, slave_status[key], 'gauge')
+
+ if is_ps_enabled(conn) is True:
+ user_connections = fetch_connections_per_account(conn)
+ for key in user_connections:
+ dispatch_value('user_connection', key, user_connections[key], 'gauge')
+
+ # This is only available in Percona Server and some MySQL versions but not in MariaDB
+ # https://www.percona.com/blog/2010/07/11/query-response-time-histogram-new-feature-in-percona-server/
+ version = get_mysql_version(conn)
+ if version.startswith('10.'):
+ pass
+ else:
+ response_times = fetch_mysql_response_times(conn)
+ for key in response_times:
+ dispatch_value('response_time_total', str(key), response_times[key]['total'], 'counter')
+ dispatch_value('response_time_count', str(key), response_times[key]['count'], 'counter')
+
+ mysql_db_size = fetch_mysql_db_size(conn)
+ for key in mysql_db_size:
+ dispatch_value('db_size', key, mysql_db_size[key], 'gauge')
+
+ innodb_log_bytes_written = fetch_innodb_os_log_bytes_written(conn)
+ dispatch_value('innodb', 'os_log_bytes_written', innodb_log_bytes_written['COUNT'], 'counter')
+
+ meta_data_lock = fetch_mysql_lock(conn)
+ dispatch_value('innodb', 'lock', meta_data_lock['nb_lock'], 'gauge')
+
+ innodb_status = fetch_innodb_stats(conn)
+ for key in MYSQL_INNODB_STATUS_VARS:
+ if key not in innodb_status:
+ continue
+ dispatch_value('innodb', key, innodb_status[key], MYSQL_INNODB_STATUS_VARS[key])
+
if COLLECTD_ENABLED:
- collectd.register_read(read_callback)
- collectd.register_config(configure_callback)
+ collectd.register_read(read_callback)
+ collectd.register_config(configure_callback)
if __name__ == "__main__" and not COLLECTD_ENABLED:
- print "Running in test mode, invoke with"
- print sys.argv[0] + " Host Port User Password "
- MYSQL_CONFIG['Host'] = sys.argv[1]
- MYSQL_CONFIG['Port'] = int(sys.argv[2])
- MYSQL_CONFIG['User'] = sys.argv[3]
- MYSQL_CONFIG['Password'] = sys.argv[4]
- MYSQL_CONFIG['Verbose'] = True
- from pprint import pprint as pp
- pp(MYSQL_CONFIG)
- read_callback()
-
-
-# vim:noexpandtab ts=8 sw=8 sts=8
+ print('Running in test mode, invoke with')
+ print(sys.argv[0] + ' Host Port User Password ')
+ MYSQL_CONFIG['Host'] = sys.argv[1]
+ MYSQL_CONFIG['Port'] = int(sys.argv[2])
+ MYSQL_CONFIG['User'] = sys.argv[3]
+ MYSQL_CONFIG['Password'] = sys.argv[4]
+ MYSQL_CONFIG['Verbose'] = True
+ from pprint import pprint as pp
+ pp(MYSQL_CONFIG)
+ read_callback()
+
+# vim:noexpandtab ts=4 sw=4 sts=4