#!/usr/bin/python#!coding:utf-8
importmysql.connector as connectorimportjson"""目标 : 这个工具用于分析MySQL实例的性能问题
作者 : 蒋乐兴
QQ : 1721900707
版本信息 : 基于python3.4 MySQL 5.7.11
MySQL用户要用到的一些权限:
create user admin@'127.0.0.1' identified by '131417';
grant select on performance_schema.* to admin@'localhost';"""show_golbal_value="select variable_name,variable_value from performance_schema.global_variables where variable_name= %s"show_global_statu="select variable_name,variable_value from performance_schema.global_status where variable_name= %s"
defanalyse_innodb_cache(cursor,results):'''用于分析innodb_buffer_pool的缓存命中率'''
#查询出innodb_buffer_pool_read_requests
cursor.execute(show_global_statu,('Innodb_buffer_pool_read_requests',))
key,value=cursor.fetchone()
innodb_buffer_pool_read_requests=value#查询出Innodb_buffer_pool_reads
cursor.execute(show_global_statu,('Innodb_buffer_pool_reads',))
key,value=cursor.fetchone()
Innodb_buffer_pool_reads=value#计算结果
innodb_buffer_pool_hit_rate=float(innodb_buffer_pool_read_requests)/(float(innodb_buffer_pool_read_requests)+float(Innodb_buffer_pool_reads))#组织结果
tempResult={}
tempResult['innodb_buffer_pool_read_requests']=innodb_buffer_pool_read_requests
tempResult['Innodb_buffer_pool_reads']=Innodb_buffer_pool_reads
tempResult['innodb_buffer_pool_hit_rate']=innodb_buffer_pool_hit_rate
results['innodb_buffer_pool_hit_rate']=tempResultdefanalyse_query_no_use_index(curosr,results):"""用于分析没有用索引的查询,最多只返回8条没有使用索引的SQL;执行次数越多的SQL在结果集中越靠前。"""query="select digest_text,sum_no_index_used from performance_schema.events_statements_summary_by_digest where sum_no_index_used>=1 and digest_text not like 'SHOW%' order by sum_no_index_used desc limit 8"cursor.execute(query)
index=0
tempResult={}for digest_text,sum_no_use_index incurosr:
tempResult[index]=digest_text
index=index+1results['analyse_query_no_use_index']=tempResultdefanalyse_query_cache(cursor,results):"""本函数用于分析mysql实例的查询缓存、如果query_cache_type=0说明没有开启这个工能,那么分析结束。
不然要分析查询缓存的剩余内存,和命中率。把分析的结果包装到results变量中。"""analysis_var=("query_cache_type",)
cursor.execute(show_golbal_value,analysis_var)
key,value=cursor.fetchone()#如果value的值等于OFF、说明本实例并没有开启查询缓存。
if value=='OFF':
results['query_cache']='query cache function not in use for this instance'
else:#如果逻辑走到了这里说明、实例开启了查询缓存
#Qcache_free_memory 对应着剩余的查询缓存内存。
cursor.execute(show_global_statu,("Qcache_free_memory",))
key,value=cursor.fetchone()#由于这个是延时计算的;所以查出来就要把它用掉。********************
Qcache_free_memory=value#query_cache_size 对应着查询缓存的内存大小。
cursor.execute(show_golbal_value,("query_cache_size",))
key,value=cursor.fetchone();
query_cache_size=value#用于查询缓存的内存空闲率
if float(query_cache_size) !=0:
query_cache_memory_free_rate=float(Qcache_free_memory)/float(query_cache_size)else:
query_cache_memory_free_rate=None#Qcache_hits 对应着命中的次数
cursor.execute(show_global_statu,("Qcache_hits",))
key,value=cursor.fetchone()
Qcache_hits=value#Qcache_inserts 对应的没有命中的次数----由于没有命中所以要插入。
cursor.execute(show_global_statu,("Qcache_inserts",))
key,value=cursor.fetchone()
Qcache_inserts=value#查询缓存的命中率为
if float(Qcache_hits+Qcache_inserts) !=0:
query_cache_hit_rate=float(Qcache_hits)/float(Qcache_hits+Qcache_inserts)else:
query_cache_hit_rate=None#组织结果
tempResult={}
tempResult['Qcache_free_memory']=Qcache_free_memory
tempResult['query_cache_size']=query_cache_size
tempResult['query_cache_memory_free_rate']=query_cache_memory_free_rate
tempResult['Qcache_hits']=Qcache_hits
tempResult['Qcache_inserts']=Qcache_inserts
tempResult['query_cache_hit_rate']=query_cache_hit_rate
results['query_cache']=tempResult
analysis_function_sets={'anaylsis_query_cache':analyse_query_cache,'analyse_query_no_use_index':analyse_query_no_use_index,'analyse_innodb_cache':analyse_innodb_cache
}if __name__=="__main__":
cnx=None
cursor=None
config={'host':'127.0.0.1','port':3306,'user':'admin','password':'131417'}
results={}try:
cnx=connector.connect(**config)
cursor=cnx.cursor(buffered=True)for key,function inanalysis_function_sets.items():print('start analyse {0}'.format(key))
function(cursor,results)print(json.dumps(results))exceptException as err:print(err)finally:if cnx !=None:
cnx.close()
cursor.close()