python 監控mysql腳本
阿新 • • 發佈:2018-07-28
gpa server turn 失敗 main ads like 緩存 ria #!/usr/bin/env python
#-*- coding: UTF-8 -*-
from __future__ import print_function
from mysql import connector
import logging,argparse,sys
import sys
#create user monitoruser@'127.0.0.1' identified by '123456';
#grant replication client on *.* to monitoruser@'127.0.0.1';
#grant super on *.* to monitoruser@'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+'\n')
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__()+'\n')
return -1
#####################################
################計算內存使用率##############
class MysqlMemUsed(MonitorItem):
"""計算內存使用率"""
def get_result(self):
try:
sql_cmd = "select (@@key_buffer_size + @@query_cache_size + @@tmp_table_size +@@innodb_buffer_pool_size +@@innodb_additional_mem_pool_size +@@innodb_log_buffer_size +@@max_connections * (@@read_buffer_size +@@read_rnd_buffer_size +@@sort_buffer_size + @@join_buffer_size +@@binlog_cache_size +@@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__()+'\n')
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__()+'\n')
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__()+'\n')
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腳本