利用zabbix自定义脚本监控MySQL基础状态

1、 mysql_monitor.sh

主要关注mysql的这些状态:

uptime| version| questions| slowQueries| select| bytesSent| bytesReceived| ping| activeThread| connectThread| maxConnect| bigSql| bigTransaction | innodbLock| primaryKey| dbRole| readonly| superReadonly| ioRunning| sqlRunning| slaveBehind

bash 复制代码
#!/bin/bash
MYSQL_USER='zabbix_mysql_monitor' 
MYSQL_PWD='zabbix_mysql_monitor_passwd'
MYSQL_PATH='/vdb/mysql/bin'
MYSQL_CONN="${MYSQL_PATH}/mysql -u${MYSQL_USER} -p${MYSQL_PWD}"
MYSQL_ADMIN="${MYSQL_PATH}/mysqladmin -u${MYSQL_USER} -p${MYSQL_PWD}"


main(){
    case $1 in
        uptime) 
            result=`${MYSQL_CONN} -e "\s" 2>/dev/null|grep Uptime|awk -F ':' '{print $2}'`
            echo $result
            ;;
        version) 
            result=`${MYSQL_CONN} -e "\s" 2>/dev/null|grep 'Server version'|awk -F ':' '{print $2}'`
            echo $result
            ;;
        questions)
            # qps 两次差集
            result=`${MYSQL_ADMIN} status 2>/dev/null |cut -f4 -d":"|cut -f1 -d"S"`
            echo $result
            ;;
        slowQueries)
            # 两次差集
            result=`${MYSQL_ADMIN} status 2>/dev/null |cut -f5 -d":"|cut -f1 -d"O"`
            echo $result
            ;;
        select)
            # 两次差集 select
            result=`${MYSQL_ADMIN} extended-status 2>/dev/null |grep -w "Com_select"|cut -d"|" -f3`
            echo $result
            ;;
        bytesSent)
            # 两次差集
            result=`${MYSQL_ADMIN} extended-status 2>/dev/null |grep -w "Bytes_sent" |cut -d"|" -f3`
            echo $result
            ;;
        bytesReceived)
            # 两次差集
            result=`${MYSQL_ADMIN} extended-status 2>/dev/null |grep -w "Bytes_received" |cut -d"|" -f3`
            echo $result
            ;;
        ping)
            result=`${MYSQL_ADMIN} ping 2>/dev/null| grep -c alive` 
            if [ ${result} -eq 1 ] ; then
                echo 0
            else
                echo 1
            fi
            ;;
        activeThread) 
            result=`${MYSQL_CONN} -e "show global status like 'threads_running'\G" 2>/dev/null|grep -i Value|awk -F ':' '{print $2}'`
            echo $result 
            ;; 
        connectThread) 
            result=`${MYSQL_CONN} -e "show global status like 'threads_connected'\G" 2>/dev/null|grep -i Value|awk -F ':' '{print $2}'`
            echo $result 
            ;;
        maxConnect) 
            result=`${MYSQL_CONN} -e "select @@max_connections value\G" 2>/dev/null|grep -i Value|awk -F ':' '{print $2}'`
            echo $result 
            ;; 
        bigSql)
            # 超过30秒的sql
            result=`${MYSQL_CONN} -e "select count(*) value from information_schema.processlist where user not in ('event_scheduler','system user') and user not like 'mysql_router\%' and command<>'sleep' and command not like 'Binlog Dump%' and time>=30\G" 2>/dev/null|grep -i Value|awk -F ':' '{print $2}'`
            echo $result 
            if [ ${result} -gt 0 ] ; then
                filename=/tmp/bigsql`date +"%Y%m%d%H%M%S"`
                res=`${MYSQL_CONN} -e "tee $filename;select * from information_schema.processlist where user not in ('event_scheduler','system user') and user not like 'mysql_router\%' and command<>'sleep' and command not like 'Binlog Dump%' and time>=30\G" 2>/dev/null`
            fi
            ;;
        bigTransaction)
            # 超过5分钟的事务
            result=`${MYSQL_CONN} -e "select count(*) value from information_schema.innodb_trx trx join information_schema.processlist pcl on trx.trx_mysql_thread_id=pcl.id where trx.trx_mysql_thread_id !=connection_id() and to_seconds(now())-to_seconds(trx_started)>300\G" 2>/dev/null|grep -i Value|awk -F ':' '{print $2}'`
            echo $result 
            if [ ${result} -gt 0 ] ; then
                 filename=/tmp/bigtrx`date +"%Y%m%d%H%M%S"`
                 res=`${MYSQL_CONN} -e "tee $filename;SELECT trx_mysql_thread_id AS PROCESSLIST_ID, NOW(), TRX_STARTED, TO_SECONDS(now())-TO_SECONDS(trx_started) AS TRX_LAST_TIME , USER, HOST, DB, TRX_QUERY FROM INFORMATION_SCHEMA.INNODB_TRX trx JOIN INFORMATION_SCHEMA.processlist pcl ON trx.trx_mysql_thread_id=pcl.id WHERE trx.trx_mysql_thread_id !=connection_id() and to_seconds(now())-to_seconds(trx_started)>300\G" 2>/dev/null`
            fi
            ;;
        innodbLock)
            result=`${MYSQL_CONN} -e "select ifnull(sum(waiting_age),0) value from (SELECT distinct a.OBJECT_SCHEMA AS locked_schema, a.OBJECT_NAME AS locked_table, \"Metadata Lock\" AS locked_type, c.PROCESSLIST_ID AS waiting_processlist_id, c.PROCESSLIST_TIME AS waiting_age, c.PROCESSLIST_INFO AS waiting_query, c.PROCESSLIST_STATE AS waiting_state, d.PROCESSLIST_ID AS blocking_processlist_id, d.PROCESSLIST_TIME AS blocking_age, d.PROCESSLIST_INFO AS blocking_query, concat('KILL ', d.PROCESSLIST_ID) AS sql_kill_blocking_connection FROM performance_schema.metadata_locks a JOIN performance_schema.metadata_locks b ON a.OBJECT_SCHEMA = b.OBJECT_SCHEMA AND a.OBJECT_NAME = b.OBJECT_NAME AND a.lock_status = 'PENDING' AND b.lock_status = 'GRANTED' AND a.OWNER_THREAD_ID <> b.OWNER_THREAD_ID JOIN performance_schema.threads c ON a.OWNER_THREAD_ID = c.THREAD_ID JOIN performance_schema.threads d ON b.OWNER_THREAD_ID = d.THREAD_ID) e\G" 2>/dev/null|grep -i Value|awk -F ':' '{print $2}'`
            echo $result
            if [ ${result} -gt 60 ] ; then
                 filename=/tmp/innodbLock`date +"%Y%m%d%H%M%S"`
                 res=`${MYSQL_CONN} -e "tee $filename;SELECT distinct a.OBJECT_SCHEMA AS locked_schema, a.OBJECT_NAME AS locked_table, \"Metadata Lock\" AS locked_type, c.PROCESSLIST_ID AS waiting_processlist_id, c.PROCESSLIST_TIME AS waiting_age, c.PROCESSLIST_INFO AS waiting_query, c.PROCESSLIST_STATE AS waiting_state, d.PROCESSLIST_ID AS blocking_processlist_id, d.PROCESSLIST_TIME AS blocking_age, d.PROCESSLIST_INFO AS blocking_query, concat('KILL ', d.PROCESSLIST_ID) AS sql_kill_blocking_connection FROM performance_schema.metadata_locks a JOIN performance_schema.metadata_locks b ON a.OBJECT_SCHEMA = b.OBJECT_SCHEMA AND a.OBJECT_NAME = b.OBJECT_NAME AND a.lock_status = 'PENDING' AND b.lock_status = 'GRANTED' AND a.OWNER_THREAD_ID <> b.OWNER_THREAD_ID JOIN performance_schema.threads c ON a.OWNER_THREAD_ID = c.THREAD_ID JOIN performance_schema.threads d ON b.OWNER_THREAD_ID = d.THREAD_ID\G" 2>/dev/null`
            fi
            ;;
        primaryKey)
            result=`${MYSQL_CONN} -e "select ifnull(count(distinct table_schema,table_name),0) value from information_schema.columns where table_schema not in ('sys','information_schema','performance_schema','mysql','sysaux','mysql_innodb_cluster_metadata') and (table_name not in (select distinct table_name from information_schema.columns where column_key='PRI') and (table_schema,table_name) not in (select table_schema,table_name from information_schema.views where table_schema not in ('sys','information_schema','performance_schema','mysql','sysaux','mysql_innodb_cluster_metadata')))\G" 2>/dev/null|grep -i Value|awk -F ':' '{print $2}'`
            echo $result
            ;;
        dbRole) 
            # 0是主库
            result=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|wc -l`
            if [ ${result} -eq 0 ] ; then
                echo 0
            else
                echo 1
            fi
            ;;
        readonly)
            # 0表示只读状态正常(主库不检查readonly,从库readonly=1)
            result=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|wc -l`
            readonly=`${MYSQL_CONN} -e "select @@read_only value\G" 2>/dev/null|awk -F ':' '{print $2}'`
            readonly=`eval echo $readonly`
            if [ ${result} -eq 0 ] ; then
                echo 0
            elif [ ${result} -gt 0 ]&[ ${readonly} -eq 1 ] ; then
                echo 0
            else
                echo 1
            fi
            ;;
        superReadonly)
            # 0表示只读状态正常(主库不检查readonly,从库readonly=1)
            result=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|wc -l`
            readonly=`${MYSQL_CONN} -e "select @@super_read_only value\G" 2>/dev/null|awk -F ':' '{print $2}'`
            readonly=`eval echo $readonly`
            if [ ${result} -eq 0 ] ; then
                echo 0
            elif [ ${result} -gt 0 ]&[ ${readonly} -eq 1 ] ; then
                echo 0
            else
                echo 1
            fi
            ;;
        ioRunning)
            # 0表示IO进程状态正常
            result=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|wc -l`
            ioRunning=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|grep -i -w Slave_IO_Running|awk -F ':' '{print $2}'`
            ioRunning=`eval echo $ioRunning| tr [a-z] [A-Z]`
            if [ ${result} -eq 0 ] ; then
                echo 0
            elif [ ${result} -gt 0 ]&[ ${ioRunning} == 'YES' ] ; then
                echo 0
            else
                echo 1
            fi
            ;;
        sqlRunning)
            result=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|wc -l`
            sqlRunning=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|grep -i -w Slave_SQL_Running|awk -F ':' '{print $2}'`
            sqlRunning=`eval echo $sqlRunning| tr [a-z] [A-Z]`
            if [ ${result} -eq 0 ] ; then
                echo 0
            elif [ ${result} -gt 0 ]&[ ${sqlRunning} == 'YES' ] ; then
                echo 0
            else
                echo 1
            fi
            ;;
        slaveBehind)
            result=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|wc -l`
            slaveBehind=`${MYSQL_CONN} -e "show slave status\G" 2>/dev/null|grep Seconds_Behind_Master|awk -F ':' '{print $2}'`
            if [ ${result} -eq 0 ] ; then
                echo 0
                slaveBehind=0
            else
                echo ${slaveBehind}
            fi
            if [ ${slaveBehind} -gt 60 ] ; then
                filename=/tmp/slave`date +"%Y%m%d%H%M%S"`
                res=`${MYSQL_CONN} -e "tee $filename;show slave status\G" 2>/dev/null`
            fi
            ;;
        *)
        echo "Usage:$0 (uptime| version| questions| slowQueries| select| bytesSent| bytesReceived| ping| activeThread| connectThread| maxConnect| bigSql| bigTransaction | innodbLock| primaryKey| dbRole| readonly| superReadonly| ioRunning| sqlRunning| slaveBehind)" 
        ;; 
    esac
}

main $1

2、把mysql_monitor.sh放在/etc/zabbix/share/zabbix/externalscripts/,并赋予它执行权限

3、另外你需要在mysql数据库中创建一个用来监控用的账户MYSQL_USER='zabbix_mysql_monitor' ,以下这些事sql语句,是需要进去mysql交互界面输入的。

bash 复制代码
create user 'zabbix_mysql_monitor'@'localhost' identified with mysql_native_password by 'zabbix_mysql_monitor_passwd';

grant select,process,replication client on *.* to 'zabbix_mysql_monitor'@'localhost' ;

flush privileges;

4、在/etc/zabbix/zabbix_agent2.d/mysql_conf写入一个文件mysql.conf

bash 复制代码
UserParameter=mysql.status[*],/etc/zabbix/share/zabbix/externalscripts/mysql_monitor.sh $1

5、OK了。然后你就可以去zabbix-server网页端创建自动发现规则和监控项除法项了

相关推荐
海奥华29 分钟前
SQLEXPLAIN 详解
数据库·mysql
情深不寿31739 分钟前
MySQL————数据库基础
数据库·mysql
程序新视界1 小时前
如何选择合适的数据库?PostgreSQL与MySQL各项对比
数据库·mysql·postgresql
dongchen。3 小时前
MySQL第一次作业
数据库·mysql
重生之我是Java开发战士5 小时前
【MySQL】数据库基础
数据库·mysql
ChuHsiang5 小时前
【剑指MySQL】数据库基础(1)
数据库·mysql
九皇叔叔5 小时前
Docker 镜像维护指南:从配置优化到 MySQL 实战运行
mysql·adb·docker
muxin-始终如一5 小时前
MySQL分区分表实现方法详解
数据库·mysql·adb
奥尔特星云大使5 小时前
mysql高可用架构之MHA部署(三)——故障转移后邮件告警配置(保姆级)
mysql·dba·高可用·mha·邮件告警
disanleya7 小时前
MySQL时间格式转换,时间数据混乱不堪如何彻底重构?
数据库·mysql·重构