python 监控mysql脚本
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 监控mysql脚本相关的知识,希望对你有一定的参考价值。
#!/usr/bin/env python #-*- coding: UTF-8 -*- from __future__ import print_function from mysql import connector import logging,argparse,sys import sys #create user [email protected]'127.0.0.1' identified by '123456'; #grant replication client on *.* to [email protected]'127.0.0.1'; #grant super on *.* to [email protected]'127.0.0.1'; class MonitorItem(object): """ 所有监控项的基类 """ def __init__(self,user='monitoruser',password='123456',host='127.0.0.1',port=3306): """初始化属性与到数据库端的连接""" self.user=user self.password=password self.host=host self.port=port self.cnx=None self.cursor=None try: config={'user':self.user,'password':self.password,'host':self.host,'port':self.port} self.cnx=connector.connect(**config) self.cursor=self.cnx.cursor(prepared=True) except connector.Error as err: """如果连接失败就赋空值""" self.cnx=None self.cursor=None sys.stderr.write(err.msg+' ') def __str__(self): attrs={} attrs['user']=self.user attrs['password']=self.password attrs['host']=self.host attrs['port']=self.port return "instance of {0} {1}".format(self.__class__,attrs) def __del__(self): """在python 进行垃圾回收时关闭连接""" if self.cnx != None: self.cnx.close() def get_result(self): """返回监控项的状态,由子类实现相应的功能""" pass def print_result(self): """打印监控项的状态""" print(self.get_result()) def action(self): """监控项达到阀值时可以触发的操作""" print("末定义任何有意义的操作") ########计算磁盘使用率############## class MysqlDiskUsed(MonitorItem): def get_result(self): try: sql_cmd = "select TABLE_SCHEMA, concat(truncate(sum(data_length)/1024/1024,2)) as data_size,concat(truncate(sum(index_length)/1024/1024,2)) as index_size from information_schema.tables group by TABLE_SCHEMA order by data_length desc;" #单位MB self.cursor.execute(sql_cmd) row = self.cursor.fetchall() #self.cursor.close() #self.cnx.close() disk_size = 0 for i in row: for j in i[1:]: disk_size += float(j.decode('utf8')) disk_used_percent = disk_size / 50 * 100 return int(disk_used_percent) except Exception as err: sys.stderr.write(err.__str__()+' ') return -1 ##################################### ################计算内存使用率############## class MysqlMemUsed(MonitorItem): """计算内存使用率""" def get_result(self): try: sql_cmd = "select (@@key_buffer_size + @@query_cache_size + @@tmp_table_size [email protected]@innodb_buffer_pool_size [email protected]@innodb_additional_mem_pool_size [email protected]@innodb_log_buffer_size [email protected]@max_connections * (@@read_buffer_size [email protected]@read_rnd_buffer_size [email protected]@sort_buffer_size + @@join_buffer_size [email protected]@binlog_cache_size [email protected]@thread_stack)) /1024/1024/1024 AS MAX_MEMORY_GB;" self.cursor.execute(sql_cmd) row = self.cursor.fetchone() mem_used_GB = 0 #代为GB mem_used_GB = float(row[0].decode('utf8')) mem_used_percent = mem_used_GB / 16 * 100 return "%.2f" % mem_used_percent except Exception as err: sys.stderr.write(err.__str__()+' ') return -1 #以下类用于检测MySQL数据库的正常与否 class IsAlive(MonitorItem): """监控MySQL数据库是否正常运行、{正常:on line,宕机:off line}""" def get_result(self): if self.cnx != None: return "on line" else: return "off line" #以下类用于检测MySQL数据库的基本信息 class MysqlVariable(MonitorItem): """派生自MonitorItem类,用于所有variable 监控项的基类""" variable_name=None def get_result(self): try: if self.cursor != None: stmt=r"""show global variables like '{0}';""".format(self.variable_name) self.cursor.execute(stmt) return self.cursor.fetchone()[1].decode('utf8') except Exception as err: sys.stderr.write(err.__str__()+' ') return -1 class MysqlPort(MonitorItem): """监控MySQL数据库监听是否正常、{正常:端口号,异常:-1}""" def get_result(self): if self.cnx != None: return self.port else: return -1 class MysqlBasedir(MysqlVariable): """监控MySQL安装目录所在位置,{正常:安装目录位置,异常:-1}""" variable_name="basedir" class MysqlDatadir(MysqlVariable): """监控MySQL数据目录所在位置,{正常:数据目录位置,异常:-1}""" variable_name="datadir" class MysqlVersion(MysqlVariable): """监控MySQL版本号,{正常:版本号,异常:-1}""" variable_name="version" class MysqlServerId(MysqlVariable): """监控MySQL的server_id""" variable_name="server_id" class MysqlLogBin(MysqlVariable): """binlog 是否有开启""" variable_name="log_bin" class MysqlLogError(MysqlVariable): """errorlog文件名""" variable_name="log_error" class MysqlPerformanceSchema(MysqlVariable): """performance_schema是否有开启""" variable_name="performance_schema" class MysqlInnodbBufferPoolSize(MysqlVariable): """监控MySQL innodb_buffer_pool的大小,{正常:缓冲池大小(byte),异常:-1}""" variable_name="innodb_buffer_pool_size" class MysqlMaxConnections(MysqlVariable): """最大连接数""" variable_name="max_connections" #派生自MonitorItem类,用于所有status 监控项的基类 class MysqlStatu(MonitorItem): """派生自MonitorItem类,用于所有statu 监控项的基类""" statu_name=None def get_result(self): try: if self.cursor != None: stmt=r"""show global status like '{0}';""".format(self.statu_name) self.cursor.execute(stmt) return self.cursor.fetchone()[1].decode('utf8') except Exception as err: sys.stderr.write(err.__str__()+' ') return -1 class MysqlCurrentClient(MysqlStatu): """当前的客户端连接数""" statu_name="Threads_connected" class MysqlTableOpenCacheHitRate(MysqlStatu): """表缓存命中率""" def get_result(self): try: if self.cursor != None: stmt=r"""show global status like 'table_open_cache_hits';""" self.cursor.execute(stmt) hit=float((self.cursor.fetchone()[1].decode('utf8'))) stmt=r"""show global status like 'table_open_cache_misses';""" self.cursor.execute(stmt) miss=float(self.cursor.fetchone()[1].decode('utf8')) return hit/(hit+miss) except Exception as err: sys.stderr.write(err.__str__()) return -1 class MysqlTableOpenCacheOverflows(MysqlStatu): """表缓存溢出次数,如果大于0,可以增大table_open_cache和table_open_cache_instances.""" statu_name="Table_open_cache_overflows" class MysqlTableLocksWaited(MysqlStatu): """因不能立刻获得表锁而等待的次数""" statu_name="table_locks_waited" class MysqlSlowqueries(MysqlStatu): """执行时间超过long_query_time的查询次数,不管慢查询日志有没有打开""" statu_name="slow_queries" class MysqlSortScan(MysqlStatu): """全表扫描之后又排序(排序键不是主键)的次数""" statu_name="sort_scan" class MysqlSortRows(MysqlStatu): """与sortscan差不多,前者指的是sortscan的次数,srotrows指的是sort操作影响的行数""" statu_name="sort_rows" class MysqlSortRange(MysqlStatu): """根据索引进行范围扫描之后再进行排序(排序键不能是主键)的次数""" statu_name="sort_range" class MysqlSortMergePasses(MysqlStatu): """排序时归并的次数,如果这个值比较大(要求高一点大于0)那么可以考虑增大sort_buffer_size的大小""" statu_name="sort_merge_passes" class MysqlSelectRangeCheck(MysqlStatu): """如果这个值不是0那么就要好好的检查表上的索引了""" statu_name="select_range_check" class MysqlQuestions(MysqlStatu): """erver端执行的语句数量,但是每执行一个语句它又只增加一,这点让我特别被动""" statu_name="Questions" class MysqlQcacheFreeMemory(MysqlStatu): """query cache 的可用内存大小""" statu_name="qcache_free_memory" class MysqlPreparedStmtCount(MysqlStatu): """由于本监控程序就是通过prepare语句完成的,所以这个监控项的值最少会是1不是0""" statu_name="prepared_stmt_count" class MysqlOpenedTables(MysqlStatu): """mysql数据库打开过的表,如果这个值过大,应该适当的增大table_open_cache的值""" statu_name="opened_tables" class MysqlOpenTables(MysqlStatu): """当前mysql数据库打开的表数量""" statu_name="open_tables" class MysqlServerLevelOpenFiles(MysqlStatu): """mysql数据库的server层当前正打开的文件数据""" statu_name="open_files" class MysqlInnodbAvailableUndoLogs(MysqlStatu): """innodb当前可用的undo段的数据""" statu_name="innodb_available_undo_logs" class MysqlInnodbNumOpenFiles(MysqlStatu): """innodb当前打开的文件数量""" statu_name="innodb_num_open_files" class MysqlInnodbRowsUpdated(MysqlStatu): """innodb层面执行的update所影响的行数""" statu_name="innodb_rows_updated" class MysqlInnodbRowsRead(MysqlStatu): """innodb 层面受读操作所影响的行数""" statu_name="innodb_rows_read" class MysqlInnodbRowsInserted(MysqlStatu): """innodb 层面受insert操作所影响的行数""" statu_name="innodb_rows_inserted" class MysqlInnodbRowsDeleted(MysqlStatu): """innodb 层面受delete操作所影响的行数""" statu_name="innodb_rows_deleted" class MysqlInnodbRowLockWaits(MysqlStatu): """innodb 行锁等待的次数""" statu_name="innodb_row_lock_waits" class MysqlInnodbRowLockTimeMax(MysqlStatu): """innodb层面行锁等待的最大毫秒数""" statu_name="innodb_row_lock_time_max" class MysqlInnodbRowLockTimeAvg(MysqlStatu): """innodb层面行锁等待的平均毫秒数""" statu_name="Innodb_row_lock_time_avg" class MysqlInnodbRowLockTime(MysqlStatu): """innodb层面行锁等待的总毫秒数""" statu_name="Innodb_row_lock_time" class MysqlInnodbPagesWritten(MysqlStatu): """innodb层面写入磁盘的页面数""" statu_name="Innodb_pages_written" class MysqlInnodbPagesRead(MysqlStatu): """从innodb buffer pool 中读取的页数""" statu_name="Innodb_pages_read" class MysqlInnodbOsLogWritten(MysqlStatu): """innodb redo 写入字节数""" statu_name="Innodb_os_log_written" class MysqlInnodbOsLogPendingWrites(MysqlStatu): """innodb redo log 被挂起的写操作次数""" statu_name="Innodb_os_log_pending_writes" class MysqlInnodbOsLogPendingFsyncs(MysqlStatu): """innodb redo log 被挂起的fsync操作次数""" statu_name="Innodb_os_log_pending_fsyncs" class MysqlInnodbOsLogFsyncs(MysqlStatu): """innodb redo log fsync的次数""" statu_name="Innodb_os_log_fsyncs" class MysqlInnodbLogWrites(MysqlStatu): """innodb redo log 物理写的次数""" statu_name="innodb_log_writes" class MysqlInnodbLogWriteRequests(MysqlStatu): """innodb redo log 逻辑写的次数""" statu_name="Innodb_log_write_requests" class MysqlInnodbLogWaits(MysqlStatu): """innodb 写redo 之前必须等待的次数""" statu_name="Innodb_log_waits" class MysqlInnodbDblwrWrites(MysqlStatu): """innodb double write 的次数""" statu_name="Innodb_dblwr_writes" class MysqlInnodbDblwrPagesWritten(MysqlStatu): """innodb double write 的页面数量""" statu_name="Innodb_dblwr_pages_written" class MysqlInnodbDoubleWriteLoader(MysqlStatu): """innodb double write 压力1~64、数值越大压力越大""" def get_result(self): try: if self.cursor != None: stmt=r"""show global status like 'innodb_dblwr_pages_written';""" self.cursor.execute(stmt) pages=float((self.cursor.fetchone()[1].decode('utf8'))) stmt=r"""show global status like 'innodb_dblwr_writes';""" self.cursor.execute(stmt) requests=float(self.cursor.fetchone()[1].decode('utf8')) if requests == 0: return 0 return pages/requests except Exception as err: sys.stderr.write(err.__str__()) return -1 class MysqlInnodbBufferPoolHitRate(MysqlStatu): """innodb buffer pool 命中率""" def get_result(self): try: if self.cursor != None: stmt=r"""show global status like 'innodb_buffer_pool_read_requests';""" self.cursor.execute(stmt) hit_read=float((self.cursor.fetchone()[1].decode('utf8'))) stmt=r"""show global status like 'innodb_buffer_pool_reads';""" self.cursor.execute(stmt) miss_read=float(self.cursor.fetchone()[1].decode('utf8')) total_read=(miss_read+hit_read) if total_read == 0: return 0 return hit_read/total_read except Exception as err: sys.stderr.write(err.__str__()) return -1 class MysqlInnodbBufferPoolFreePagePercent(MysqlStatu): """innodb buffer pool free page 百分比""" def get_result(self): try: if self.cursor != None: stmt=r"""show global status like 'innodb_buffer_pool_pages_total';""" self.cursor.execute(stmt) total_page=float((self.cursor.fetchone()[1].decode('utf8'))) stmt=r"""show global status like 'innodb_buffer_pool_pages_free';""" self.cursor.execute(stmt) free_page=float(self.cursor.fetchone()[1].decode('utf8')) return free_page/total_page except Exception as err: sys.stderr.write(err.__str__()) return -1 class MysqlInnodbBufferPoolDirtyPercent(MysqlStatu): """innodb buffer pool dirty page 百分比""" def get_result(self): try: if self.cursor != None: stmt=r"""show global status like 'innodb_buffer_pool_pages_total';""" self.cursor.execute(stmt) total_page=float((self.cursor.fetchone()[1].decode('utf8'))) stmt=r"""show global status like 'innodb_buffer_pool_pages_dirty';""" self.cursor.execute(stmt) dirty_page=float(self.cursor.fetchone()[1].decode('utf8')) return dirty_page/total_page except Exception as err: sys.stderr.write(err.__str__()) return -1 class MysqlCreated_tmp_disk_tables(MysqlStatu): """mysql运行时所创建的磁盘临时表的数量,如果这个数值比较大,可以适当的增大 tmp_table_size | max_heap_table_size""" statu_name="Created_tmp_disk_tables" class MysqlComSelect(MysqlStatu): """select 语句执行的次数""" statu_name="com_select" class MysqlComInsert(MysqlStatu): """insert 语句执行的次数""" statu_name="com_insert" class MysqlComDelete(MysqlStatu): """delete 语句执行的次数""" statu_name="com_delete" class MysqlComUpdate(MysqlStatu): """update 语句执行的次数""" statu_name="com_update" class MysqlBinlogCacheDiskUse(MysqlStatu): """事务引擎因binlog缓存不足而用到临时文件的次数,如果这个值过大,可以通过增大binlog_cache_size来解决""" statu_name="Binlog_cache_disk_use" class MysqlBinlogStmtCacheDiskUse(MysqlStatu): """非事务引擎因binlog缓存不足而用到临时文件的次数,如果这个值过大,可以通过增大binlog_stmt_cache_size来解决""" statu_name="Binlog_stmt_cache_disk_use" class MysqlReplication(MonitorItem): """所有监控mysql replication的基类""" def __init__(self,user='monitoruser',password='123456',host='127.0.0.1',port=3306): MonitorItem.__init__(self,user,password,host,port) try: if self.cursor != None: stmt="show slave status;" self.cursor.execute(stmt) self.replication_info=self.cursor.fetchone() except Exception as err: pass class MysqlReplicationIsRunning(MysqlReplication): """mysql replication 是否正常运行""" def get_result(self): if self.replication_info == None: return "replication is not running" else: slave_io_running=self.replication_info[10].decode('utf8') slave_sql_running=self.replication_info[11].decode('utf8') if slave_io_running == 'Yes' and slave_sql_running == 'Yes': return "running" return "replication is not running" class MysqlReplicationBehindMaster(MysqlReplication): """监控seconde behind master """ def get_result(self): if self.replication_info != None: return self.replication_info[32] else: return -1 #监控项字典 items={ #实例配置信息收集项 'port' :MysqlPort, 'baseDir' :MysqlBasedir, 'dataDir' :MysqlDatadir, 'version' :MysqlVersion, 'serverId' :MysqlServerId, 'isBinlogEnable' :MysqlLogBin, 'isErrorlogEnable' :MysqlLogError, 'isPerformanceScheamEnable' :MysqlPerformanceSchema, 'innodbBufferPoolSize' :MysqlInnodbBufferPoolSize, 'maxConnections' :MysqlMaxConnections, #实例运行时信息收集项 'isOnLine' :IsAlive, 'currentConnections' :MysqlCurrentClient, 'tableCacheHitRate' :MysqlTableOpenCacheHitRate, 'tableOpenCacheOverflows' :MysqlTableOpenCacheOverflows, 'tableLocksWaited' :MysqlTableLocksWaited, 'slowqueries' :MysqlSlowqueries, 'sortScan' :MysqlSortScan, 'sortRows' :MysqlSortRows, 'sortRange' :MysqlSortRange, 'sortMergePasses' :MysqlSortMergePasses, 'selectRangeCheck' :MysqlSelectRangeCheck, 'questions' :MysqlQuestions, 'qcacheFreeMemory' :MysqlQcacheFreeMemory, 'preparedStmtCount' :MysqlPreparedStmtCount, 'openedTables' :MysqlOpenedTables, 'openTables' :MysqlOpenTables, 'serverLevelOpenFiles' :MysqlServerLevelOpenFiles, 'created_tmp_disk_tables' :MysqlCreated_tmp_disk_tables, 'comSelect' :MysqlComSelect, 'comInsert' :MysqlComInsert, 'comDelete' :MysqlComDelete, 'comUpdate' :MysqlComUpdate, 'binlogCacheDiskUse' :MysqlBinlogCacheDiskUse, 'binlogStmtCacheDiskUse' :MysqlBinlogStmtCacheDiskUse, 'MysqlDiskUsed' :MysqlDiskUsed, 'MysqlMemUsed':MysqlMemUsed, #innodb运行时信息收集项 'innodbAvailableUndoLogs' :MysqlInnodbAvailableUndoLogs, 'innodbOpenFiles' :MysqlInnodbNumOpenFiles, 'innodbRowsUpdated' :MysqlInnodbRowsUpdated, 'innodbRowsRead' :MysqlInnodbRowsRead, 'innodbRowsInserted' :MysqlInnodbRowsInserted, 'innodbRowsDeleted' :MysqlInnodbRowsDeleted, 'innodbRowLockWaits' :MysqlInnodbRowLockWaits, 'innodbRowLockTimeMax' :MysqlInnodbRowLockTimeMax, 'innodbRowLockTimeAvg' :MysqlInnodbRowLockTimeAvg, 'innodbRowLockTime' :MysqlInnodbRowLockTime, 'innodbPagesWritten' :MysqlInnodbPagesWritten, 'innodbPagesRead' :MysqlInnodbPagesRead, 'innodbOsLogWritten' :MysqlInnodbOsLogWritten, 'innodbOsLogPendingWrites' :MysqlInnodbOsLogPendingWrites, 'innodbOsLogPendingFsyncs' :MysqlInnodbOsLogPendingFsyncs, 'innodbOsLogFsyncs' :MysqlInnodbOsLogFsyncs, 'innodbLogWrites' :MysqlInnodbLogWrites, 'innodbLogWriteRequests' :MysqlInnodbLogWriteRequests, 'innodbLogWaits' :MysqlInnodbLogWaits, 'innodbDblwrWrites' :MysqlInnodbDblwrWrites, 'innodbDblwrPagesWritten' :MysqlInnodbDblwrPagesWritten, 'innodbDoubleWriteLoader' :MysqlInnodbDoubleWriteLoader, 'innodbBufferPoolHitRate' :MysqlInnodbBufferPoolHitRate, 'innodbBufferPoolFreePagePercent' :MysqlInnodbBufferPoolFreePagePercent, 'innodbBufferPoolDirtyPercent' :MysqlInnodbBufferPoolDirtyPercent, #对mysql replication 的监控 'replicationIsRunning' :MysqlReplicationIsRunning, 'replicationBehindMaster' :MysqlReplicationBehindMaster, } # item_key_names=[name for name in items.keys()] if __name__=="__main__": parser=argparse.ArgumentParser() parser.add_argument('--user',default='root',help='user name for connect to mysql') parser.add_argument('--password',default='xxxxxx',help='user password for connect to mysql') parser.add_argument('--host',default='172.31.x.x',help='mysql host ip') parser.add_argument('--port',default=1231,type=int,help='mysql port') parser.add_argument('monitor_item_name',choices=item_key_names) args=parser.parse_args() m=items[args.monitor_item_name](host=args.host,port=args.port,user=args.user,password=args.password) m.print_result()
以上是关于python 监控mysql脚本的主要内容,如果未能解决你的问题,请参考以下文章
使用python写一个监控mysql的脚本,在zabbix web上加上模板