├── README.md ├── SendEmail.py ├── SendEmail3.py ├── dbset.ini ├── emailset.ini ├── html.jpg ├── mysql_watcher.py ├── mysql_watcher.sh ├── mysql_watcher3.py └── txt.jpg /README.md: -------------------------------------------------------------------------------- 1 | # MySQL_Watcher 2 | MySQL Watcher is a tool to help DBA's to trouble shoot MySQL performance. 3 | 4 | pip install psutil 5 | 6 | pip install prettytable 7 | 8 | 2.7: 9 | 10 | pip install mysql-python 11 | 12 | 3.8: 13 | 14 | pip install mysqlclient 15 | 16 | Some options must be executed on the host,not remote. 17 | 18 | The MySQL sys schema support now. 19 | 20 | https://github.com/mysql/mysql-sys 21 | 22 | Some sys view is off by default, you can set in the dbset.ini. 23 | 24 | example: 25 | 26 | ![txt example](https://github.com/kinghows/MySQL_Watcher/blob/master/txt.jpg) 27 | ![html example](https://github.com/kinghows/MySQL_Watcher/blob/master/html.jpg) 28 | 29 | Edit MySQL connect info in dbset.ini. 30 | 31 | execute: 32 | 33 | 2.7: 34 | 35 | python mysql_watcher.py 36 | 37 | python mysql_watcher.py -p dbset.ini 38 | 39 | python mysql_watcher.py -p dbset.ini -s txt >mysql_watcher.txt 40 | 41 | python mysql_watcher.py -p dbset.ini -s html >mysql_watcher.html 42 | 43 | send email: 44 | 45 | python SendEmail.py -p emailset.ini -f my_report1.html,my_report2.html 46 | 47 | 3.8: 48 | 49 | python3 mysql_watcher3.py 50 | 51 | python3 mysql_watcher3.py -p dbset.ini 52 | 53 | python3 mysql_watcher3.py -p dbset.ini -s txt >mysql_watcher.txt 54 | 55 | python3 mysql_watcher3.py -p dbset.ini -s html >mysql_watcher.html 56 | 57 | send email: 58 | 59 | python3 SendEmail3.py -p emailset.ini -f my_report1.html,my_report2.html 60 | 61 | use crontab regularly perform sql_report.sh,auto generate report,and send email. 62 | 63 | Enjoy it! 64 | 65 | ## 好用的DBA系列,喜欢的打颗星: 66 | 67 | - [MySQL_Watcher:数据库性能指标的HTML监控报告](https://github.com/kinghows/MySQL_Watcher) 68 | 69 | - [SQL_Report:自定义SQL生成HTML报告](https://github.com/kinghows/SQL_Report) 70 | 71 | - [SQL_Chart:自定义SQL生成HTML图表](https://github.com/kinghows/SQL_Chart) 72 | 73 | - [Logthin:日志精简工具](https://github.com/kinghows/Logthin) 74 | 75 | - [Logchart:日志图形化工具](https://github.com/kinghows/Logchart) 76 | 77 | - [Linux_Report:自定义Linux 命令生成HTML报告](https://github.com/kinghows/Linux_Report) 78 | 79 | - [IO-performance-analysis:Linux IO性能问题分析](https://github.com/kinghows/IO-performance-analysis) 80 | -------------------------------------------------------------------------------- /SendEmail.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import datetime 4 | import getopt 5 | import sys 6 | import ConfigParser 7 | import smtplib 8 | from email.mime.multipart import MIMEMultipart 9 | from email.mime.text import MIMEText 10 | 11 | today = datetime.datetime.now() 12 | config_file = "emailset.ini" 13 | 14 | opts, args = getopt.getopt(sys.argv[1:], "p:f:") 15 | for o, v in opts: 16 | if o == "-p": 17 | config_file = v 18 | elif o == "-f": 19 | attfile = v 20 | 21 | config = ConfigParser.ConfigParser() 22 | config.readfp(open(config_file, "rb")) 23 | Email_host = config.get("Email", "host") 24 | Email_port = config.get("Email", "port") 25 | Email_user = config.get("Email", "user") 26 | Email_pass = config.get("Email", "pass") 27 | Email_from = config.get("Email", "from") 28 | to_list = config.get("Email", "to_list") 29 | Email_subject = config.get("Email", "subject") 30 | Email_text = config.get("Email", "text") 31 | 32 | Email_to_list=[] 33 | for Email_to in to_list.split(','): 34 | Email_to_list.append(Email_to) 35 | 36 | msg = MIMEMultipart() 37 | msg['Subject'] = Email_subject 38 | msg.attach(MIMEText(Email_text, 'plain', 'gbk')) #utf-8 39 | msg["From"]=Email_from 40 | 41 | for fs in attfile.split(','): 42 | att = MIMEText(open(r'%s' % fs, 'rb').read(), 'base64', 'utf-8') # 添加附件 43 | att["Content-Type"] = 'application/octet-stream' 44 | att["Content-Disposition"] = 'attachment; filename="%s"' % fs 45 | msg.attach(att) 46 | 47 | try: 48 | s = smtplib.SMTP_SSL() # smtplib.SMTP() 如果是使用SSL端口:SMTP_SSL 49 | s.connect(Email_host,Email_port) 50 | s.login(Email_user,Email_pass) 51 | s.sendmail(Email_from,Email_to_list, msg.as_string()) 52 | except Exception, e: 53 | print str(e) 54 | finally: 55 | s.close() -------------------------------------------------------------------------------- /SendEmail3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding:utf-8 -*- 3 | 4 | import datetime 5 | import getopt 6 | import sys 7 | import configparser 8 | import smtplib 9 | from email.mime.multipart import MIMEMultipart 10 | from email.mime.text import MIMEText 11 | from email.header import Header 12 | 13 | today = datetime.datetime.now() 14 | config_file = "emailset.ini" 15 | 16 | opts, args = getopt.getopt(sys.argv[1:], "p:f:") 17 | for o, v in opts: 18 | if o == "-p": 19 | config_file = v 20 | elif o == "-f": 21 | attfile = v 22 | 23 | config = configparser.ConfigParser() 24 | config.read(config_file) 25 | Email_host = config.get("Email", "host") 26 | Email_port = config.get("Email", "port") 27 | Email_user = config.get("Email", "user") 28 | Email_pass = config.get("Email", "pass") 29 | Email_from = config.get("Email", "from") 30 | to_list = config.get("Email", "to_list") 31 | Email_subject = config.get("Email", "subject") 32 | Email_text = config.get("Email", "text") 33 | 34 | Email_to_list=[] 35 | for Email_to in to_list.split(','): 36 | Email_to_list.append(Email_to) 37 | 38 | msg = MIMEMultipart() 39 | msg['Subject'] = Email_subject 40 | msg.attach(MIMEText(Email_text, 'plain', 'gbk')) #utf-8 41 | msg["From"]=Email_from 42 | 43 | for fs in attfile.split(','): 44 | att = MIMEText(open(r'%s' % fs, 'rb').read(), 'base64', 'utf-8') 45 | att["Content-Type"] = 'application/octet-stream' 46 | att["Content-Disposition"] = 'attachment; filename="%s"' % fs 47 | msg.attach(att) 48 | 49 | try: 50 | s = smtplib.SMTP_SSL(host=Email_host) #3.7+ 51 | #s = smtplib.SMTP_SSL() # smtplib.SMTP() 如果是使用SSL端口:SMTP_SSL 52 | s.connect(Email_host,Email_port) 53 | s.login(Email_user,Email_pass) 54 | s.sendmail(Email_from,Email_to_list, msg.as_string()) 55 | except Exception as e: 56 | print (str(e)) 57 | finally: 58 | s.close() -------------------------------------------------------------------------------- /dbset.ini: -------------------------------------------------------------------------------- 1 | # topN must be OFF or number 2 | [database] 3 | host = 192.168.0.101 4 | port = 3306 5 | user = root 6 | passwd = 123456 7 | db = mysql 8 | [option] 9 | interval =60 10 | #must be executed on the host 11 | linux_info = ON 12 | filesystem_info = ON 13 | linux_overview = ON 14 | host_memory_topN = 10 15 | log_error_statistics = ON 16 | #mysql 17 | mysql_overview = ON 18 | sys_parm = ON 19 | replication = ON 20 | connect_count = ON 21 | avg_query_time = ON 22 | err_sql_count = ON 23 | database_size = ON 24 | object_count = ON 25 | table_info = ON 26 | index_info = OFF 27 | #5.7sys Schema 28 | slow_query_topN = 10 29 | err_sql_topN = 10 30 | query_analysis_topN = 10 31 | query_full_table_scans_topN = OFF 32 | query_sorting_topN = OFF 33 | query_with_temp_tables_topN = OFF 34 | schema_index_statistics = OFF 35 | schema_table_statistics = OFF 36 | schema_table_statistics_with_buffer = ON 37 | schema_tables_with_full_table_scans = ON 38 | schema_unused_indexes = ON 39 | host_summary = ON 40 | host_summary_by_file_io_type = OFF 41 | host_summary_by_file_io = ON 42 | host_summary_by_stages = OFF 43 | host_summary_by_statement_latency = ON 44 | host_summary_by_statement_type = OFF 45 | user_summary = ON 46 | user_summary_by_file_io_type = OFF 47 | user_summary_by_file_io = ON 48 | user_summary_by_stages = ON 49 | user_summary_by_statement_latency = ON 50 | user_summary_by_statement_type = OFF 51 | innodb_buffer_stats_by_schema = ON 52 | innodb_buffer_stats_by_table = OFF 53 | io_by_thread_by_latency_topN = 20 54 | io_global_by_file_by_bytes_topN = 20 55 | io_global_by_file_by_latency_topN = 20 56 | io_global_by_wait_by_bytes_topN = 20 57 | io_global_by_wait_by_latency_topN = 20 58 | wait_classes_global_by_avg_latency = ON 59 | wait_classes_global_by_latency = ON 60 | waits_by_host_by_latency = OFF 61 | waits_by_user_by_latency = ON 62 | waits_global_by_latency = ON 63 | schema_table_lock_waits = ON 64 | innodb_lock_waits = ON 65 | memory_by_host_by_current_bytes = OFF 66 | memory_by_thread_by_current_bytes = OFF 67 | memory_by_user_by_current_bytes = OFF 68 | memory_global_by_current_bytes = OFF 69 | memory_global_total = OFF 70 | processlist = OFF 71 | session = OFF 72 | metrics = OFF -------------------------------------------------------------------------------- /emailset.ini: -------------------------------------------------------------------------------- 1 | [Email] 2 | host = smtp.xxx.com 3 | port = 25 4 | user = xxx@xxx.com 5 | pass = xxx 6 | from = xxx@xxx.com 7 | to_list = xxx@xxx.com,xxx@xxx.com 8 | subject = xxxxxxxxxx 9 | text = xxxxxxxxxxxxxxxxxxxxx -------------------------------------------------------------------------------- /html.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinghows/MySQL_Watcher/c95781fcd70a3183422b4717899ce2cb5f1b6771/html.jpg -------------------------------------------------------------------------------- /mysql_watcher.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python 2 | # coding: utf-8 3 | 4 | # MySQL Watcher V1.2.0 5 | # trouble shoot MySQL performance 6 | # Copyright (C) 2017-2017 Kinghow - Kinghow@hotmail.com 7 | # Git repository available at https://github.com/kinghows/MySQL_Watcher 8 | 9 | import getopt 10 | import sys 11 | import MySQLdb 12 | import ConfigParser 13 | import math 14 | import time 15 | import os 16 | import prettytable 17 | import psutil 18 | import platform 19 | import glob 20 | import re 21 | from collections import OrderedDict 22 | from collections import namedtuple 23 | from warnings import filterwarnings 24 | 25 | filterwarnings('ignore', category = MySQLdb.Warning) 26 | 27 | tab1="=" 28 | tab2="*" 29 | linesize=104 30 | 31 | SYS_PARM_FILTER = ( 32 | 'autocommit', 33 | 'binlog_cache_size', 34 | 'bulk_insert_buffer_size', 35 | 'character_set_server', 36 | 'tx_isolation', 37 | 'tx_read_only', 38 | 'sql_mode', 39 | # connection # 40 | 'interactive_timeout', 41 | 'wait_timeout', 42 | 'lock_wait_timeout', 43 | 'skip_name_resolve', 44 | 'max_connections', 45 | 'max_connect_errors', 46 | # table cache performance settings 47 | 'table_open_cache', 48 | 'table_definition_cache', 49 | 'table_open_cache_instances', 50 | # performance settings 51 | 'have_query_cache', 52 | 'join_buffer_size', 53 | 'key_buffer_size', 54 | 'key_cache_age_threshold', 55 | 'key_cache_block_size', 56 | 'key_cache_division_limit', 57 | 'large_pages', 58 | 'locked_in_memory', 59 | 'long_query_time', 60 | 'max_allowed_packet', 61 | 'max_binlog_size', 62 | 'max_length_for_sort_data', 63 | 'max_sort_length', 64 | 'max_tmp_tables', 65 | 'max_user_connections', 66 | 'optimizer_prune_level', 67 | 'optimizer_search_depth', 68 | 'query_cache_size', 69 | 'query_cache_type', 70 | 'query_prealloc_size', 71 | 'range_alloc_block_size', 72 | # session memory settings # 73 | 'read_buffer_size', 74 | 'read_rnd_buffer_size', 75 | 'sort_buffer_size', 76 | 'tmp_table_size', 77 | 'join_buffer_size', 78 | 'thread_cache_size', 79 | # log settings # 80 | 'log_error', 81 | 'slow_query_log', 82 | 'slow_query_log_file', 83 | 'log_queries_not_using_indexes', 84 | 'log_slow_admin_statements', 85 | 'log_slow_slave_statements', 86 | 'log_throttle_queries_not_using_indexes', 87 | 'expire_logs_days', 88 | 'long_query_time', 89 | 'min_examined_row_limit', 90 | 'binlog-rows-query-log-events', 91 | 'log-bin-trust-function-creators', 92 | 'expire-logs-days', 93 | 'log-slave-updates', 94 | # innodb settings # 95 | 'innodb_page_size', 96 | 'innodb_buffer_pool_size', 97 | 'innodb_buffer_pool_instances', 98 | 'innodb_buffer_pool_chunk_size', 99 | 'innodb_buffer_pool_load_at_startup', 100 | 'innodb_buffer_pool_dump_at_shutdown', 101 | 'innodb_lru_scan_depth', 102 | 'innodb_lock_wait_timeout', 103 | 'innodb_io_capacity', 104 | 'innodb_io_capacity_max', 105 | 'innodb_flush_method', 106 | 'innodb_file_format', 107 | 'innodb_file_format_max', 108 | 'innodb_undo_logs', 109 | 'innodb_undo_tablespaces', 110 | 'innodb_flush_neighbors', 111 | 'innodb_log_file_size', 112 | 'innodb_log_files_in_group', 113 | 'innodb_log_buffer_size', 114 | 'innodb_purge_threads', 115 | 'innodb_large_prefix', 116 | 'innodb_thread_concurrency', 117 | 'innodb_print_all_deadlocks', 118 | 'innodb_strict_mode', 119 | 'innodb_sort_buffer_size', 120 | 'innodb_write_io_threads', 121 | 'innodb_read_io_threads', 122 | 'innodb_file_per_table', 123 | 'innodb_stats_persistent_sample_pages', 124 | 'innodb_autoinc_lock_mode', 125 | 'innodb_online_alter_log_max_size', 126 | 'innodb_open_files', 127 | # replication settings # 128 | 'master_info_repository', 129 | 'relay_log_info_repository', 130 | 'sync_binlog', 131 | 'gtid_mode', 132 | 'enforce_gtid_consistency', 133 | 'log_slave_updates', 134 | 'binlog_format', 135 | 'binlog_rows_query_log_events', 136 | 'relay_log', 137 | 'relay_log_recovery', 138 | 'slave_skip_errors', 139 | 'slave-rows-search-algorithms', 140 | # semi sync replication settings # 141 | 'plugin_load', 142 | 'rpl_semi_sync_master_enabled', 143 | 'rpl_semi_sync_master_timeout', 144 | 'rpl_semi_sync_slave_enabled', 145 | # password plugin # 146 | 'validate_password_policy', 147 | 'validate-password', 148 | # metalock performance settings 149 | 'metadata_locks_hash_instances', 150 | # new innodb settings # 151 | 'loose_innodb_numa_interleave', 152 | 'innodb_buffer_pool_dump_pct', 153 | 'innodb_page_cleaners', 154 | 'innodb_undo_log_truncate', 155 | 'innodb_max_undo_log_size', 156 | 'innodb_purge_rseg_truncate_frequency', 157 | # new replication settings # 158 | 'slave-parallel-type', 159 | 'slave-parallel-workers', 160 | 'slave_preserve_commit_order', 161 | 'slave_transaction_retries', 162 | # other change settings # 163 | 'binlog_gtid_simple_recovery', 164 | 'log_timestamps', 165 | 'show_compatibility_56' 166 | ) 167 | 168 | def f_get_conn(dbinfo): 169 | try: 170 | conn = MySQLdb.connect(host=dbinfo[0],user=dbinfo[1],passwd=dbinfo[2],db=dbinfo[3],port=int(dbinfo[4])) 171 | return conn 172 | except MySQLdb.Error, e: 173 | print "Error %d: %s" % (e.args[0], e.args[1]) 174 | sys.exit(1) 175 | 176 | def f_get_query_value(conn, query): 177 | cursor = conn.cursor() 178 | getNum = cursor.execute(query) 179 | if getNum > 0: 180 | result = cursor.fetchone() 181 | else: 182 | result = ['0'] 183 | cursor.close() 184 | return result[0] 185 | 186 | def f_get_query_record(conn, query): 187 | cursor = conn.cursor() 188 | cursor.execute(query) 189 | records = cursor.fetchall() 190 | cursor.close() 191 | return records 192 | 193 | def f_print_title(title): 194 | print 195 | print ((linesize-4)/2 - int(len(title) / 2)) * tab1, title, ((linesize-4)/2+1 - int(len(title) / 2)) * tab1 196 | print 197 | 198 | def f_print_table_body(rows, style,tab): 199 | for row in rows: 200 | k = 0 201 | for col in row: 202 | k += 1 203 | print tab, 204 | if style[k].split(',')[2] == 'l': 205 | print str(col).ljust(int(style[k].split(',')[1])), 206 | elif style[k].split(',')[2] == 'r': 207 | print str(col).rjust(int(style[k].split(',')[1])), 208 | else: 209 | print str(col).center(int(style[k].split(',')[1])), 210 | print tab 211 | 212 | def f_print_table_txt(rows, title, style): 213 | field_names = [] 214 | f_print_title(title) 215 | table = prettytable.PrettyTable() 216 | for k in style.keys(): 217 | field_names.append(style[k].split(',')[0]) 218 | table.field_names = field_names 219 | for k in style.keys(): 220 | table.align[style[k].split(',')[0]] = style[k].split(',')[1] 221 | for row in rows: 222 | table.add_row(row) 223 | print table 224 | 225 | def f_print_table_html(rows, title, style): 226 | print """

""" + title + "

" 227 | print """""" 228 | 229 | print """""", 230 | for k in style.keys(): 231 | v = style[k] 232 | print """""", 235 | print """""" 236 | 237 | linenum = 0 238 | for row in rows: 239 | k = 0 240 | linenum += 1 241 | print "", 242 | if linenum % 2 == 0: 243 | classs='awrc' 244 | else: 245 | classs='awrnc' 246 | 247 | for col in row: 248 | k += 1 249 | if style[k].split(',')[1] == 'r': 250 | print """", 251 | else: 252 | print """", 253 | print "" 254 | print """
""", 233 | print v.split(',')[0], 234 | print """
"+str(col)+""+str(col)+"
255 |
Back to Top 256 |

257 |

258 | """ 259 | 260 | def f_print_table(rows,title,style,save_as): 261 | if save_as == "txt": 262 | f_print_table_txt(rows, title, style) 263 | elif save_as == "html": 264 | f_print_table_html(rows, title, style) 265 | 266 | def f_print_query_table(conn, title, query, style,save_as): 267 | rows = f_get_query_record(conn, query) 268 | f_print_table(rows,title,style,save_as) 269 | 270 | def f_is_sys_schema_exist(conn): 271 | query = "SHOW DATABASES" 272 | rows = f_get_query_record(conn, query) 273 | exist=False 274 | for row in rows: 275 | if row[0]=='sys': 276 | exist = True 277 | break 278 | return exist 279 | 280 | def f_print_optimizer_switch(conn,save_as,perfor_or_infor): 281 | title = "Optimizer Switch" 282 | style = {1: 'switch_name,l', 2: 'value,r'} 283 | rows =[] 284 | query="select variable_value from "+perfor_or_infor+".global_variables where variable_name='optimizer_switch'" 285 | recode = f_get_query_record(conn, query) 286 | for col in recode[0][0].split(','): 287 | rows.append([col.split('=')[0],col.split('=')[1]]) 288 | f_print_table(rows, title, style,save_as) 289 | 290 | def f_print_log_error(conn,perfor_or_infor,save_as): 291 | title = "Log file Statistics" 292 | style = {1: 'start & shutdown:,l'} 293 | rows =[] 294 | WarnLog = 0 295 | ErrLog = 0 296 | query = "SELECT variable_value FROM " + perfor_or_infor + ".global_variables where variable_name ='log_error'" 297 | filename = f_get_query_value(conn, query) 298 | if os.path.exists(filename): 299 | with open(filename, 'r') as f: 300 | for line in f: 301 | if ('ready for connections' in line or 'Shutdown completed' in line): 302 | rows.append([line]) 303 | if ('Warning' in line): 304 | WarnLog += 1 305 | if ('error' in line): 306 | ErrLog += 1 307 | else: 308 | rows.append([filename + " not exists"]) 309 | 310 | rows.append(['Warning & Error Statistics:']) 311 | rows.append([filename + ' contains ' + str(WarnLog) + ' warning(s).']) 312 | rows.append([filename + ' contains ' + str(ErrLog) + ' error(s).']) 313 | f_print_table(rows, title, style,save_as) 314 | 315 | def f_print_caption(dbinfo,mysql_version,save_as): 316 | if save_as == "txt": 317 | print tab2 * linesize 318 | print tab2, 'MySQL Watcher V1.2.0'.center(linesize - 4), tab2 319 | print tab2, 'Kinghow@hotmail.com'.center(linesize - 4), tab2 320 | print tab2, 'https://github.com/kinghows/MySQL_Watcher'.center(linesize - 4), tab2 321 | print tab2 * linesize 322 | elif save_as == "html": 323 | print """ 324 | MySQL Watcher V1.2.0 Kinghow@hotmail.com https://github.com/kinghows/MySQL_Watcher 325 | 353 |

354 | WORKLOAD REPOSITORY report for 355 |

356 | """ 357 | 358 | title = "Basic Information" 359 | style = {1: 'host,c', 2: 'user,c', 3: 'db,c', 4: 'mysql version,c'} 360 | rows = [[dbinfo[0], dbinfo[1], dbinfo[3], mysql_version]] 361 | f_print_table(rows, title, style,save_as) 362 | 363 | def f_print_ending(save_as): 364 | if save_as == "txt": 365 | f_print_title('--@-- End --@--') 366 | elif save_as == "html": 367 | print """ 368 |

369 | End of Report 370 | 371 | """ 372 | 373 | def size(device): 374 | nr_sectors = open(device+'/size').read().rstrip('\n') 375 | sect_size = open(device+'/queue/hw_sector_size').read().rstrip('\n') 376 | return (float(nr_sectors)*float(sect_size))/(1024.0*1024.0*1024.0) 377 | 378 | def f_print_linux_info(save_as): 379 | title = "Linux info" 380 | style = {1: 'Linux,l',2: 'Info,l'} 381 | rows =[] 382 | #version 383 | rows.append(["Version",platform.uname()[0]+' '+platform.uname()[2]+' '+platform.uname()[4]]) 384 | #cpu 385 | cpu_count = 0 386 | with open('/proc/cpuinfo') as f: 387 | for line in f: 388 | if line.strip(): 389 | if line.rstrip('\n').startswith('model name'): 390 | model_name = line.rstrip('\n').split(':')[1] 391 | cpu_count +=1 392 | rows.append(["CPU",model_name + ' X '+str(cpu_count)]) 393 | #mem 394 | meminfo = OrderedDict() 395 | with open('/proc/meminfo') as f: 396 | for line in f: 397 | meminfo[line.split(':')[0]] = line.split(':')[1].strip() 398 | rows.append(["Memory",'Total: {0}'.format(meminfo['MemTotal'])+' Free: {0}'.format(meminfo['MemFree'])]) 399 | #net 400 | with open('/proc/net/dev') as f: 401 | net_dump = f.readlines() 402 | device_data = {} 403 | data = namedtuple('data', ['rx', 'tx']) 404 | for line in net_dump[2:]: 405 | line = line.split(':') 406 | if line[0].strip() != 'lo': 407 | device_data[line[0].strip()] = data(float(line[1].split()[0]) / (1024.0 * 1024.0), 408 | float(line[1].split()[8]) / (1024.0 * 1024.0)) 409 | for dev in device_data.keys(): 410 | rows.append(["Net",'{0}: {1} MiB {2} MiB'.format(dev, device_data[dev].rx, device_data[dev].tx)]) 411 | #Device 412 | dev_pattern = ['sd.*', 'mmcblk*'] 413 | for device in glob.glob('/sys/block/*'): 414 | for pattern in dev_pattern: 415 | if re.compile(pattern).match(os.path.basename(device)): 416 | rows.append(["Device",'{0}, Size: {1} GiB'.format(device, size(device))]) 417 | #process 418 | pids = [] 419 | for subdir in os.listdir('/proc'): 420 | if subdir.isdigit(): 421 | pids.append(subdir) 422 | rows.append(["Processes",'Total number of running : {0}'.format(len(pids))]) 423 | 424 | f_print_table(rows, title, style,save_as) 425 | 426 | def f_print_filesystem_info(save_as): 427 | title = "Filesystem info" 428 | style = {1: 'Filesystem,l',2: 'Size,r',3: 'Used,r',4: 'Avail,r',5: 'Use %,r',6: ' Mounted on,l'} 429 | rows =[] 430 | file_info = [] 431 | j = 0 432 | for line in os.popen('df -h').readlines(): 433 | for eachList in line.strip().split(): 434 | file_info.append(eachList) 435 | j +=1 436 | i = 6 437 | while i= topN: 492 | break 493 | rows.append([i + 1, item['name'], item['pid'], format(item['memory_percent'] / 100, '.2%')]) 494 | 495 | style = {1: 'No,r', 2: 'Name,l',3: 'Pid,r', 4: 'Memory percent,r'} 496 | title = "Host memory top"+str(topN) 497 | f_print_table(rows, title, style, save_as) 498 | 499 | def f_sec2dhms(sec): 500 | day = 24*60*60 501 | hour = 60*60 502 | min = 60 503 | if sec <60: 504 | return "%ds"%math.ceil(sec) 505 | elif sec > day: 506 | days = divmod(sec,day) 507 | return "%dd%s"%(int(days[0]),f_sec2dhms(days[1])) 508 | elif sec > hour: 509 | hours = divmod(sec,hour) 510 | return '%dh%s'%(int(hours[0]),f_sec2dhms(hours[1])) 511 | else: 512 | mins = divmod(sec,min) 513 | return "%dm%ds"%(int(mins[0]),math.ceil(mins[1])) 514 | 515 | def f_get_mysql_status(conn): 516 | query = "SHOW GLOBAL STATUS" 517 | rows = f_get_query_record(conn, query) 518 | mysqlstatus = dict(rows) 519 | return mysqlstatus 520 | 521 | def f_print_mysql_status(conn,perfor_or_infor,interval,save_as): 522 | ###获取参数################################################################### 523 | mysqlstatus1 = f_get_mysql_status(conn) 524 | time.sleep(interval) 525 | mysqlstatus2 = f_get_mysql_status(conn) 526 | 527 | # 执行查询的总次数 528 | Questions1 = long(mysqlstatus1["Questions"]) 529 | Questions2 = long(mysqlstatus2["Questions"]) 530 | # 服务器已经运行的时间(以秒为单位) 531 | Uptime2 = long(mysqlstatus2["Uptime"]) 532 | Com_commit1 = long(mysqlstatus1["Com_commit"]) 533 | Com_commit2 = long(mysqlstatus2["Com_commit"]) 534 | Com_rollback1 = long(mysqlstatus1["Com_rollback"]) 535 | Com_rollback2 = long(mysqlstatus2["Com_rollback"]) 536 | # 从硬盘读取键的数据块的次数。如果Key_reads较大,则Key_buffer_size值可能太小。 537 | # 可以用Key_reads/Key_read_requests计算缓存损失率 538 | #Key_reads1 = long(mysqlstatus1["Key_reads"]) 539 | #Key_reads2 = long(mysqlstatus2["Key_reads"]) 540 | # 从缓存读键的数据块的请求数 541 | #Key_read_requests1 = long(mysqlstatus1["Key_read_requests"]) 542 | #Key_read_requests2 = long(mysqlstatus2["Key_read_requests"]) 543 | # 向硬盘写入将键的数据块的物理写操作的次数 544 | #Key_writes1 = long(mysqlstatus1["Key_writes"]) 545 | #Key_writes2 = long(mysqlstatus2["Key_writes"]) 546 | # 将键的数据块写入缓存的请求数 547 | #Key_write_requests1 = long(mysqlstatus1["Key_write_requests"]) 548 | #Key_write_requests2 = long(mysqlstatus2["Key_write_requests"]) 549 | # 不能满足InnoDB必须单页读取的缓冲池中的逻辑读数量。 550 | Innodb_buffer_pool_reads1 = long(mysqlstatus1["Innodb_buffer_pool_reads"]) 551 | Innodb_buffer_pool_reads2 = long(mysqlstatus2["Innodb_buffer_pool_reads"]) 552 | # InnoDB已经完成的逻辑读请求数 553 | Innodb_buffer_pool_read_requests1 = long(mysqlstatus1["Innodb_buffer_pool_read_requests"]) 554 | Innodb_buffer_pool_read_requests2 = long(mysqlstatus2["Innodb_buffer_pool_read_requests"]) 555 | 556 | # 当前打开的表的数量 557 | Open_tables1 = long(mysqlstatus2["Open_tables"])-long(mysqlstatus1["Open_tables"]) 558 | Open_tables2 = long(mysqlstatus2["Open_tables"]) 559 | # 已经打开的表的数量。如果Opened_tables较大,table_cache 值可能太小 560 | Opened_tables1 = long(mysqlstatus2["Opened_tables"])-long(mysqlstatus1["Opened_tables"]) 561 | Opened_tables2 = long(mysqlstatus2["Opened_tables"]) 562 | # 创建用来处理连接的线程数。如果Threads_created较大,你可能要 563 | # 增加thread_cache_size值。缓存访问率的计算方法Threads_created/Connections 564 | Threads_created1 = long(mysqlstatus1["Threads_created"]) 565 | Threads_created2 = long(mysqlstatus2["Threads_created"]) 566 | # 试图连接到(不管是否成功)MySQL服务器的连接数。缓存访问率的计算方法Threads_created/Connections 567 | Connections1 = long(mysqlstatus1["Connections"]) 568 | Connections2 = long(mysqlstatus2["Connections"]) 569 | Threads_connected1 = str(long(mysqlstatus2["Threads_connected"])-long(mysqlstatus1["Threads_connected"])) 570 | Threads_connected2 = mysqlstatus2["Threads_connected"] 571 | Aborted_connects1 = str(long(mysqlstatus2["Aborted_connects"])-long(mysqlstatus1["Aborted_connects"])) 572 | Aborted_connects2 = mysqlstatus2["Aborted_connects"] 573 | # Com_select/s:平均每秒select语句执行次数 574 | # Com_insert/s:平均每秒insert语句执行次数 575 | # Com_update/s:平均每秒update语句执行次数 576 | # Com_delete/s:平均每秒delete语句执行次数 577 | Com_select1 = long(mysqlstatus1["Com_select"]) 578 | Com_select2 = long(mysqlstatus2["Com_select"]) 579 | Com_insert1 = long(mysqlstatus1["Com_insert"]) 580 | Com_insert2 = long(mysqlstatus2["Com_insert"]) 581 | Com_update1 = long(mysqlstatus1["Com_update"]) 582 | Com_update2 = long(mysqlstatus2["Com_update"]) 583 | Com_delete1 = long(mysqlstatus1["Com_delete"]) 584 | Com_delete2 = long(mysqlstatus2["Com_delete"]) 585 | Com_replace1 = long(mysqlstatus1["Com_replace"]) 586 | Com_replace2 = long(mysqlstatus2["Com_replace"]) 587 | # 不能立即获得的表的锁的次数。如果该值较高,并且有性能问题,你应首先优化查询,然后拆分表或使用复制。 588 | #Table_locks_waited1 = long(mysqlstatus1["Table_locks_waited"]) 589 | #Table_locks_waited2 = long(mysqlstatus2["Table_locks_waited"]) 590 | # 立即获得的表的锁的次数 591 | #Table_locks_immediate1 = long(mysqlstatus1["Table_locks_immediate"]) 592 | #Table_locks_immediate2 = long(mysqlstatus2["Table_locks_immediate"]) 593 | # 服务器执行语句时自动创建的内存中的临时表的数量。如果Created_tmp_disk_tables较大, 594 | # 你可能要增加tmp_table_size值使临时 表基于内存而不基于硬盘 595 | Created_tmp_tables1 = long(mysqlstatus1["Created_tmp_tables"]) 596 | Created_tmp_tables2 = long(mysqlstatus2["Created_tmp_tables"]) 597 | # 服务器执行语句时在硬盘上自动创建的临时表的数量 598 | Created_tmp_disk_tables1 = long(mysqlstatus1["Created_tmp_disk_tables"]) 599 | Created_tmp_disk_tables2 = long(mysqlstatus2["Created_tmp_disk_tables"]) 600 | # 查询时间超过long_query_time秒的查询的个数 缓慢查询个数 601 | Slow_queries1 = long(mysqlstatus1["Slow_queries"]) 602 | Slow_queries2 = long(mysqlstatus2["Slow_queries"]) 603 | # 没有主键(key)联合(Join)的执行。该值可能是零。这是捕获开发错误的好方法,因为一些这样的查询可能降低系统的性能。 604 | Select_full_join1 = long(mysqlstatus1["Select_full_join"]) 605 | Select_full_join2 = long(mysqlstatus2["Select_full_join"]) 606 | # Percentage of full table scans 607 | Handler_read_rnd_next1 = long(mysqlstatus1["Handler_read_rnd_next"]) 608 | Handler_read_rnd_next2 = long(mysqlstatus2["Handler_read_rnd_next"]) 609 | Handler_read_rnd1 = long(mysqlstatus1["Handler_read_rnd"]) 610 | Handler_read_rnd2 = long(mysqlstatus2["Handler_read_rnd"]) 611 | Handler_read_first1 = long(mysqlstatus1["Handler_read_first"]) 612 | Handler_read_first2 = long(mysqlstatus2["Handler_read_first"]) 613 | Handler_read_next1 = long(mysqlstatus1["Handler_read_next"]) 614 | Handler_read_next2 = long(mysqlstatus2["Handler_read_next"]) 615 | Handler_read_key1 = long(mysqlstatus1["Handler_read_key"]) 616 | Handler_read_key2 = long(mysqlstatus2["Handler_read_key"]) 617 | Handler_read_prev1 = long(mysqlstatus1["Handler_read_prev"]) 618 | Handler_read_prev2 = long(mysqlstatus2["Handler_read_prev"]) 619 | # 缓冲池利用率 620 | Innodb_buffer_pool_pages_total1 = long(mysqlstatus1["Innodb_buffer_pool_pages_total"]) 621 | Innodb_buffer_pool_pages_total2 = long(mysqlstatus2["Innodb_buffer_pool_pages_total"]) 622 | Innodb_buffer_pool_pages_free1 = long(mysqlstatus1["Innodb_buffer_pool_pages_free"]) 623 | Innodb_buffer_pool_pages_free2 = long(mysqlstatus2["Innodb_buffer_pool_pages_free"]) 624 | 625 | ###计算参数################################################################### 626 | Uptimes1 = str(interval) + "s" 627 | Uptimes2 = f_sec2dhms(Uptime2) 628 | # QPS = Questions / Seconds 629 | QPS1 = str(round((Questions2-Questions1) * 1.0 / interval, 2))+' ('+str(Questions2-Questions1)+'/'+str(interval)+')' 630 | QPS2 = str(round(Questions2* 1.0 / Uptime2, 2))+' ('+str(Questions2)+'/'+str(Uptime2)+')' 631 | 632 | TPS1 = str(round((Com_commit2 + Com_rollback2-Com_commit1 - Com_rollback1) * 1.0 / interval, 2))+' (('+str(Com_commit2 -Com_commit1)+'+'+str(Com_rollback2- Com_rollback1)+')/'+str(interval)+')' 633 | TPS2 = str(round((Com_commit2 + Com_rollback2)* 1.0 / Uptime2, 2))+' (('+str(Com_commit2)+'+'+str(Com_rollback2)+')/'+str(Uptime2)+')' 634 | 635 | Read1 = Com_select2 -Com_select1 636 | Read2 = Com_select2 637 | ReadS1 = str(round(Read1 * 1.0 / interval, 2))+' ('+str(Read1)+'/'+str(interval)+')' 638 | ReadS2 = str(round(Read2* 1.0 / Uptime2, 2))+' ('+str(Read2)+'/'+str(Uptime2)+')' 639 | 640 | Write1 = Com_insert2 + Com_update2 + Com_delete2 + Com_replace2-Com_insert1 - Com_update1 - Com_delete1 - Com_replace1 641 | Write2 = Com_insert2 + Com_update2 + Com_delete2 + Com_replace2 642 | WriteS1 = str(round(Write1 * 1.0 / interval, 2))+' ('+str(Write1)+'/'+str(interval)+')' 643 | WriteS2 = str(round(Write2* 1.0 / Uptime2, 2))+' ('+str(Write2)+'/'+str(Uptime2)+')' 644 | # Read/Write Ratio 645 | if Write1<>0: 646 | rwr1 = str(round(Read1 * 1.0 / Write1,2))+' ('+str(Read1)+'/'+str(Write1)+')' 647 | else: 648 | rwr1 ='0.0%' 649 | 650 | if Write2<>0: 651 | rwr2 = str(round(Read2 * 1.0 / Write2,2))+' ('+str(Read2)+'/'+str(Write2)+')' 652 | else: 653 | rwr2 ='0.0%' 654 | 655 | Slow_queries_per_second1 = str(round((Slow_queries2-Slow_queries1) * 1.0 / interval, 2))+' ('+str(Slow_queries2-Slow_queries1)+'/'+str(interval)+')' 656 | Slow_queries_per_second2 = str(round(Slow_queries2 * 1.0 / Uptime2, 2))+' ('+str(Slow_queries2)+'/'+str(Uptime2)+')' 657 | #Slow_queries / Questions 658 | SQ1 = str(round(((Slow_queries2-Slow_queries1) * 1.0 / (Questions2-Questions1)) * 100, 2)) + "%"+' ('+str(Slow_queries2-Slow_queries1)+'/'+str(Questions2-Questions1)+')' 659 | SQ2 = str(round((Slow_queries2 * 1.0 / Questions2) * 100, 2)) + "%"+' ('+str(Slow_queries2)+'/'+str(Questions2)+')' 660 | 661 | if (Connections2-Connections1) <> 0: 662 | Thread_cache_hits1 = str(round((1 - (Threads_created2-Threads_created1)* 1.0 / (Connections2-Connections1)) * 100, 2)) + "%" 663 | else: 664 | Thread_cache_hits1 = '0.0%' 665 | Thread_cache_hits2 = str(round((1 - Threads_created2 * 1.0 / Connections2) * 100, 2)) + "%" 666 | 667 | if (Innodb_buffer_pool_read_requests2-Innodb_buffer_pool_read_requests1) <> 0: 668 | Innodb_buffer_read_hits1 = str(round((1 - (Innodb_buffer_pool_reads2-Innodb_buffer_pool_reads1) * 1.0 / (Innodb_buffer_pool_read_requests2-Innodb_buffer_pool_read_requests1)) * 100, 2)) + "%"+ "%"+' (1-'+str(Innodb_buffer_pool_reads2-Innodb_buffer_pool_reads1)+'/'+str(Innodb_buffer_pool_read_requests2-Innodb_buffer_pool_read_requests1)+')' 669 | else: 670 | Innodb_buffer_read_hits1 = '0.0%' 671 | Innodb_buffer_read_hits2 = str(round((1 - Innodb_buffer_pool_reads2* 1.0 / Innodb_buffer_pool_read_requests2) * 100, 2)) + "%"+' (1-'+str(Innodb_buffer_pool_reads2)+'/'+str(Innodb_buffer_pool_read_requests2)+')' 672 | 673 | Innodb_buffer_pool_utilization1 = str(round((Innodb_buffer_pool_pages_total1 - Innodb_buffer_pool_pages_free1) * 1.0 / Innodb_buffer_pool_pages_total1 * 100,2)) + "%"+' ('+str(Innodb_buffer_pool_pages_total1 - Innodb_buffer_pool_pages_free1)+'/'+str(Innodb_buffer_pool_pages_total1)+')' 674 | Innodb_buffer_pool_utilization2 = str(round((Innodb_buffer_pool_pages_total2 - Innodb_buffer_pool_pages_free2) * 1.0 / Innodb_buffer_pool_pages_total2 * 100,2)) + "%"+' ('+str(Innodb_buffer_pool_pages_total2 - Innodb_buffer_pool_pages_free2)+'/'+str(Innodb_buffer_pool_pages_total2)+')' 675 | 676 | """ 677 | if (Key_read_requests2-Key_read_requests1) <> 0: 678 | Key_buffer_read_hits1 = str(round((1 - (Key_reads2-Key_reads1) * 1.0 / (Key_read_requests2-Key_read_requests1)) * 100, 2)) + "%" 679 | else: 680 | Key_buffer_read_hits1 = '0.0%' 681 | if Key_read_requests2 <> 0: 682 | Key_buffer_read_hits2 = str(round((1 - Key_reads2* 1.0 / Key_read_requests2) * 100, 2)) + "%" 683 | else: 684 | Key_buffer_read_hits2 = '0.0%' 685 | 686 | if (Key_write_requests2-Key_write_requests1)<>0: 687 | Key_buffer_write_hits1 = str(round((1 - (Key_writes2-Key_writes1)* 1.0 / (Key_write_requests2-Key_write_requests1)) * 100, 2)) + "%" 688 | else: 689 | Key_buffer_write_hits1 = '0.0%' 690 | if Key_write_requests2<>0: 691 | Key_buffer_write_hits2 = str(round((1 - Key_writes2* 1.0 / Key_write_requests2) * 100, 2)) + "%" 692 | else: 693 | Key_buffer_write_hits2 = '0.0%' 694 | """ 695 | if (Select_full_join2-Select_full_join1) > 0: 696 | Select_full_join_per_second1 = str(round((Select_full_join2-Select_full_join1) * 1.0 / interval, 2))+' ('+str(Select_full_join2-Select_full_join1)+'/'+str(interval)+')' 697 | else: 698 | Select_full_join_per_second1 = '0.0%' 699 | Select_full_join_per_second2 = str(round(Select_full_join2 * 1.0 / Uptime2, 2))+' ('+str(Select_full_join2)+'/'+str(Uptime2)+')' 700 | 701 | if (Com_select2-Com_select1) > 0: 702 | full_select_in_all_select1 = str(round(((Select_full_join2-Select_full_join1) * 1.0 / (Com_select2-Com_select1)) * 100, 2)) + "%"+' ('+str(Select_full_join2-Select_full_join1)+'/'+str(Com_select2-Com_select1)+')' 703 | else: 704 | full_select_in_all_select1 = '0.0%' 705 | full_select_in_all_select2 = str(round((Select_full_join2 * 1.0 / Com_select2) * 100, 2)) + "%"+' ('+str(Select_full_join2)+'/'+str(Com_select2)+')' 706 | 707 | #((Handler_read_rnd_next + Handler_read_rnd) / (Handler_read_rnd_next + Handler_read_rnd + Handler_read_first + Handler_read_next + Handler_read_key + Handler_read_prev)). 708 | if (Handler_read_rnd_next2 -Handler_read_rnd_next1+ Handler_read_rnd2-Handler_read_rnd1 + Handler_read_first2 -Handler_read_first1+ Handler_read_next2-Handler_read_next1 + Handler_read_key2-Handler_read_key1 + Handler_read_prev2-Handler_read_prev1) > 0: 709 | full_table_scans1=str(round((Handler_read_rnd_next2 + Handler_read_rnd2-Handler_read_rnd_next1 - Handler_read_rnd1)* 1.0 / (Handler_read_rnd_next2 -Handler_read_rnd_next1+ Handler_read_rnd2-Handler_read_rnd1 + Handler_read_first2 -Handler_read_first1+ Handler_read_next2-Handler_read_next1 + Handler_read_key2-Handler_read_key2 + Handler_read_prev2-Handler_read_prev1)* 100, 2)) + "%" 710 | else: 711 | full_table_scans1 = '0.0%' 712 | full_table_scans2=str(round((Handler_read_rnd_next2 + Handler_read_rnd2)* 1.0 / (Handler_read_rnd_next2 + Handler_read_rnd2 + Handler_read_first2 + Handler_read_next2 + Handler_read_key2 + Handler_read_prev2)* 100, 2)) + "%" 713 | """ 714 | if (Table_locks_immediate2-Table_locks_immediate1) > 0: 715 | lock_contention1 = str(round(((Table_locks_waited2-Table_locks_waited1) * 1.00 / (Table_locks_immediate2-Table_locks_immediate1)) * 100, 2)) + "%" 716 | else: 717 | lock_contention1 = '0.0%' 718 | lock_contention2 = str(round((Table_locks_waited2 * 1.00 / Table_locks_immediate2) * 100, 2)) + "%" 719 | """ 720 | if (Created_tmp_tables2-Created_tmp_tables1) > 0: 721 | Temp_tables_to_disk1 = str(round(((Created_tmp_disk_tables2-Created_tmp_disk_tables1) * 1.0 / (Created_tmp_tables2-Created_tmp_tables1)) * 100, 2)) + "%"+' ('+str(Created_tmp_disk_tables2-Created_tmp_disk_tables1)+'/'+str(Created_tmp_tables2-Created_tmp_tables1)+')' 722 | else: 723 | Temp_tables_to_disk1 = '0.0%' 724 | Temp_tables_to_disk2 = str(round((Created_tmp_disk_tables2 * 1.0 / Created_tmp_tables2) * 100, 2)) + "%"+' ('+str(Created_tmp_disk_tables2)+'/'+str(Created_tmp_tables2)+')' 725 | 726 | ###打印参数################################################################### 727 | title = "MySQL Overview" 728 | style = {1: 'Key,l', 2: 'In '+Uptimes1+',r', 3: 'Total,r'} 729 | rows=[ 730 | ["Uptimes",Uptimes1,Uptimes2], 731 | ["QPS (Questions / Seconds)", QPS1, QPS2], 732 | ["TPS ((Commit + Rollback)/ Seconds)", TPS1, TPS2], 733 | ["Reads per second", ReadS1, ReadS2], 734 | ["Writes per second", WriteS1, WriteS2], 735 | ["Read/Writes", rwr1,rwr2], 736 | ["Slow queries per second", Slow_queries_per_second1, Slow_queries_per_second2], 737 | ["Slow_queries/Questions", SQ1,SQ2], 738 | ["Threads connected", Threads_connected1, Threads_connected2], 739 | ["Aborted connects", Aborted_connects1, Aborted_connects2], 740 | ["Thread cache hits (>90%)", Thread_cache_hits1, Thread_cache_hits2], 741 | ["Innodb buffer hits(96% - 99%)", Innodb_buffer_read_hits1,Innodb_buffer_read_hits2], 742 | ["Innodb buffer pool utilization", Innodb_buffer_pool_utilization1,Innodb_buffer_pool_utilization2], 743 | #["Key buffer read hits(99.3% - 99.9%)",str(Key_buffer_read_hits1), str(Key_buffer_read_hits2)], 744 | #["Key buffer write hits(99.3% - 99.9%)", str(Key_buffer_write_hits1), str(Key_buffer_write_hits2)], 745 | ["Select full join per second", Select_full_join_per_second1, Select_full_join_per_second2], 746 | ["full select in all select", full_select_in_all_select1, full_select_in_all_select2], 747 | ["full table scans", full_table_scans1, full_table_scans2], 748 | #["MyISAM Lock waiting ratio", lock_contention1, lock_contention2], 749 | ["Current open tables", str(Open_tables1), str(Open_tables2)], 750 | ["Accumulative open tables", str(Opened_tables1), str(Opened_tables2)], 751 | ["Temp tables to disk(<10%)", Temp_tables_to_disk1, Temp_tables_to_disk2] 752 | ] 753 | 754 | f_print_table(rows, title, style,save_as) 755 | 756 | if __name__=="__main__": 757 | dbinfo=["127.0.0.1","root","","mysql",3306] #host,user,passwd,db,port 758 | config_file="dbset.ini" 759 | mysql_version="" 760 | option = [] 761 | save_as = "txt" 762 | 763 | opts, args = getopt.getopt(sys.argv[1:], "p:s:") 764 | for o,v in opts: 765 | if o == "-p": 766 | config_file = v 767 | elif o == "-s": 768 | save_as = v 769 | 770 | config = ConfigParser.ConfigParser() 771 | config.readfp(open(config_file,"rb")) 772 | dbinfo[0] = config.get("database","host") 773 | dbinfo[1] = config.get("database","user") 774 | dbinfo[2] = config.get("database","passwd") 775 | dbinfo[3] = config.get("database","db") 776 | dbinfo[4] = config.get("database", "port") 777 | interval = long(config.get("option", "interval")) 778 | 779 | conn = f_get_conn(dbinfo) 780 | query ="select @@version" 781 | mysql_version = f_get_query_value(conn, query) 782 | f_print_caption(dbinfo,mysql_version,save_as) 783 | 784 | if "5.6" in mysql_version: 785 | perfor_or_infor = "information_schema" 786 | else: 787 | perfor_or_infor = "performance_schema" 788 | 789 | sys_schema_exist = f_is_sys_schema_exist(conn) 790 | 791 | if config.get("option","linux_info")=='ON': 792 | f_print_linux_info(save_as) 793 | 794 | if config.get("option","filesystem_info")=='ON': 795 | f_print_filesystem_info(save_as) 796 | 797 | if config.get("option","linux_overview")=='ON': 798 | f_print_linux_status(save_as) 799 | 800 | if config.get("option","host_memory_topN")<>'OFF': 801 | topN=int(config.get("option","host_memory_topN")) 802 | f_print_host_memory_topN(topN,save_as) 803 | 804 | if config.get("option","mysql_overview")=='ON': 805 | f_print_mysql_status(conn,perfor_or_infor,interval,save_as) 806 | 807 | if config.get("option","sys_parm")=='ON': 808 | title = "System Parameter " 809 | query = "SELECT variable_name,IF(INSTR(variable_name,'size'), \ 810 | CASE \ 811 | WHEN variable_value>=1024*1024*1024*1024*1024 THEN CONCAT(variable_value/1024/1024/1024/1024/1024,'P') \ 812 | WHEN variable_value>=1024*1024*1024*1024 THEN CONCAT(variable_value/1024/1024/1024/1024,'T') \ 813 | WHEN variable_value>=1024*1024*1024 THEN CONCAT(variable_value/1024/1024/1024,'G') \ 814 | WHEN variable_value>=1024*1024 THEN CONCAT(variable_value/1024/1024,'M') \ 815 | WHEN variable_value>=1024 THEN CONCAT(variable_value/1024,'K') \ 816 | ELSE variable_value END , \ 817 | variable_value) \ 818 | FROM "+perfor_or_infor+".global_variables \ 819 | where variable_name in ('" + "','".join(list(SYS_PARM_FILTER)) + "')" 820 | style = {1: 'parameter_name,l', 2: 'value,r'} 821 | f_print_query_table(conn, title, query, style,save_as) 822 | f_print_optimizer_switch(conn,save_as,perfor_or_infor) 823 | 824 | if config.get("option","log_error_statistics")=='ON': 825 | f_print_log_error(conn,perfor_or_infor,save_as) 826 | 827 | if config.get ( "option", "replication" ) == 'ON': 828 | title = "Replication" 829 | query = """SELECT USER,HOST,command,CONCAT(FLOOR(TIME/86400),'d',FLOOR(TIME/3600)%24,'h',FLOOR(TIME/60)%60,'m',TIME%60,'s') TIMES,state 830 | FROM information_schema.processlist WHERE COMMAND = 'Binlog Dump' OR COMMAND = 'Binlog Dump GTID'""" 831 | style = {1: 'USER,l', 2: 'HOST,l', 3: 'command,l', 4: 'TIMES,r', 5: 'state,r'} 832 | f_print_query_table(conn, title, query, style,save_as) 833 | 834 | if config.get ( "option", "connect_count" ) == 'ON': 835 | title = "Connect Count" 836 | query = """SELECT SUBSTRING_INDEX(HOST,':',1) HOSTS,USER,db,command,COUNT(*),SUM(TIME) 837 | FROM information_schema.processlist 838 | WHERE Command !='' AND DB !='information_schema' 839 | GROUP BY HOSTS,USER,db,command""" 840 | style = {1: 'HOSTS,l', 2: 'USER,l', 3: 'db,l', 4: 'command,l', 5: 'COUNT(*),r', 6: 'SUM(TIME),r'} 841 | f_print_query_table(conn, title, query, style,save_as) 842 | 843 | if config.get ( "option", "avg_query_time" ) == 'ON' and not ("5.6" in mysql_version): 844 | title = "Avg Query Time" 845 | query = """SELECT schema_name,SUM(count_star) COUNT, ROUND((SUM(sum_timer_wait)/SUM(count_star))/1000000) avg_microsec 846 | FROM performance_schema.events_statements_summary_by_digest 847 | WHERE schema_name IS NOT NULL 848 | GROUP BY schema_name""" 849 | style = {1: 'schema_name,l', 2: 'COUNT,r', 3: 'avg_microsec,r'} 850 | f_print_query_table(conn, title, query, style,save_as) 851 | 852 | if config.get ( "option", "slow_query_topN" ) <> 'OFF' and sys_schema_exist: 853 | topN = int(config.get("option", "slow_query_topN")) 854 | title = "Slow Query Top"+str(topN) 855 | query = "SELECT QUERY,db,exec_count,total_latency,max_latency,avg_latency FROM sys.statements_with_runtimes_in_95th_percentile LIMIT "+str(topN) 856 | style = {1: 'QUERY,l', 2: 'db,r', 3: 'exec_count,r', 4: 'total_latency,r', 5: 'max_latency,r', 6: 'avg_latency,r'} 857 | f_print_query_table(conn, title, query, style,save_as) 858 | 859 | if config.get ( "option", "err_sql_count" ) == 'ON' and ("5.7" in mysql_version): 860 | title = "Err Sql Count" 861 | query = """SELECT schema_name,SUM(sum_errors) err_count 862 | FROM performance_schema.events_statements_summary_by_digest 863 | WHERE sum_errors > 0 864 | GROUP BY schema_name""" 865 | style = {1: 'schema_name,l', 2: 'err_count,r'} 866 | f_print_query_table(conn, title, query, style,save_as) 867 | 868 | if config.get ( "option", "err_sql_topN" ) <> 'OFF' and sys_schema_exist: 869 | topN = int(config.get("option", "err_sql_topN")) 870 | title = "Err SQL Top"+str(topN) 871 | query = "SELECT QUERY,db,exec_count,ERRORS FROM sys.statements_with_errors_or_warnings ORDER BY ERRORS DESC LIMIT "+str(topN) 872 | style = {1: 'QUERY,l', 2: 'db,r', 3: 'exec_count,r', 4: 'ERRORS,r'} 873 | f_print_query_table(conn, title, query, style,save_as) 874 | 875 | if config.get ( "option", "query_analysis_topN" ) <> 'OFF' and sys_schema_exist: 876 | topN = int(config.get("option", "query_analysis_topN")) 877 | title = "query analysis top"+str(topN) 878 | query = """SELECT QUERY,full_scan,exec_count,total_latency,lock_latency,rows_sent_avg,rows_examined_avg, 879 | tmp_tables,tmp_disk_tables,rows_sorted,last_seen 880 | FROM sys.statement_analysis 881 | where db='""" + dbinfo[3] + "' ORDER BY total_latency DESC LIMIT "+str(topN) 882 | style = {1: 'QUERY,l', 2: 'fscan,l', 3: 'ex_cot,r', 4: 'total_ltc,r', 5:'lock_ltc,r', 6: 'rw_st_avg,r', 883 | 7: 'rw_exm_avg,9,r',8: 'tmp_table,9,r',9: 'tp_dk_tab,9,r',10: 'rows_sort,9,r',11: 'last_seen,19,r'} 884 | f_print_query_table(conn, title, query, style,save_as) 885 | 886 | if config.get ( "option", "query_full_table_scans_topN" ) <> 'OFF' and sys_schema_exist: 887 | topN = int(config.get("option", "query_full_table_scans_topN")) 888 | title = "query full table scans top"+str(topN) 889 | query = """SELECT QUERY,exec_count,total_latency,no_index_used_count,no_good_index_used_count,no_index_used_pct,rows_sent_avg,rows_examined_avg,last_seen 890 | FROM sys.statements_with_full_table_scans 891 | where db='""" + dbinfo[3] + "' ORDER BY total_latency DESC LIMIT "+str(topN) 892 | style = {1: 'QUERY,l', 2: 'ex_cot,r', 3: 'total_ltc,r', 4:'no_idx_use,r', 5: 'n_g_idx_use,r',6: 'n_i_u_pct,r', 893 | 7: 'rw_st_avg,r',8: 'rw_exm_avg,r',9: 'last_seen,r'} 894 | f_print_query_table(conn, title, query, style,save_as) 895 | 896 | if config.get ( "option", "query_sorting_topN" ) <> 'OFF' and sys_schema_exist: 897 | topN = int(config.get("option", "query_sorting_topN")) 898 | title = "query sorting top"+str(topN) 899 | query = """SELECT QUERY,exec_count,total_latency,sort_merge_passes,avg_sort_merges,sorts_using_scans,sort_using_range, 900 | rows_sorted,avg_rows_sorted,last_seen 901 | FROM sys.statements_with_sorting 902 | where db='""" + dbinfo[3] + "' ORDER BY avg_rows_sorted DESC LIMIT "+str(topN) 903 | style = {1: 'QUERY,l', 2: 'ex_cot,r', 3: 'total_ltc,r', 4:'st_mg_ps,r', 5: 'avg_st_mg,r',6: 'st_us_scan,r', 904 | 7: 'st_us_rag,r',8: 'rows_sort,r',9: 'avg_rw_st,r',10: 'last_seen,r'} 905 | f_print_query_table(conn, title, query, style,save_as) 906 | 907 | if config.get ( "option", "query_with_temp_tables_topN" ) <> 'OFF' and sys_schema_exist: 908 | topN = int(config.get("option", "query_with_temp_tables_topN")) 909 | title = "query with temp tables top"+str(topN) 910 | query = """SELECT QUERY,exec_count,total_latency,memory_tmp_tables,disk_tmp_tables,avg_tmp_tables_per_query,tmp_tables_to_disk_pct,last_seen 911 | FROM sys.statements_with_temp_tables 912 | where db='""" + dbinfo[3] + "' ORDER BY avg_tmp_tables_per_query DESC LIMIT "+str(topN) 913 | style = {1: 'QUERY,l', 2: 'ex_cot,r', 3: 'total_ltc,r', 4:'mem_tmp_tab,r', 5: 'dsk_tmp_tab,r',6: 'avg_tt_per_qry,r', 914 | 7: 'tt_to_dk_pct,r',8:'last_seen,r'} 915 | f_print_query_table(conn, title, query, style,save_as) 916 | 917 | if config.get ( "option", "database_size" ) == 'ON': 918 | title = "Database Size" 919 | query = """SELECT table_schema, 920 | CONCAT(ROUND(SUM(data_length)/(1024*1024),2),'MB') AS 'Table Size', 921 | CONCAT(ROUND(SUM(index_length)/(1024*1024),2),'MB') AS 'Index Size' , 922 | CONCAT(ROUND(SUM(data_length)/(1024*1024),2) + ROUND(SUM(index_length)/(1024*1024),2),'MB') AS 'DB Size' 923 | FROM information_schema.tables GROUP BY table_schema 924 | UNION 925 | SELECT '*** all ***' table_schema, 926 | CONCAT(ROUND(SUM(data_length)/(1024*1024),2),'MB') AS 'Table Size', 927 | CONCAT(ROUND(SUM(index_length)/(1024*1024),2),'MB') AS 'Index Size' , 928 | CONCAT(ROUND(SUM(data_length)/(1024*1024),2) + ROUND(SUM(index_length)/(1024*1024),2),'MB') AS 'DB Size' 929 | FROM information_schema.tables""" 930 | style = {1: 'table_schema,l', 2: 'Table Size,r', 3: 'Index Size,r', 4: 'DB Size,r'} 931 | f_print_query_table(conn, title, query, style,save_as) 932 | 933 | if config.get("option","object_count")=='ON': 934 | title = "Object Count" 935 | query = "SELECT information_schema.routines.ROUTINE_TYPE AS object_type, COUNT(0) AS COUNT FROM information_schema.routines \ 936 | WHERE information_schema.routines.ROUTINE_SCHEMA='" + dbinfo[3] + "' GROUP BY information_schema.routines.ROUTINE_TYPE UNION \ 937 | SELECT information_schema.tables.TABLE_TYPE AS object_type, COUNT(0) AS COUNT FROM information_schema.tables \ 938 | WHERE information_schema.tables.TABLE_SCHEMA='" + dbinfo[3] + "' GROUP BY information_schema.tables.TABLE_TYPE UNION \ 939 | SELECT CONCAT('INDEX (',information_schema.statistics.INDEX_TYPE,')') AS object_type,COUNT(0) AS COUNT FROM information_schema.statistics \ 940 | WHERE information_schema.statistics.TABLE_SCHEMA='" + dbinfo[3] + "' GROUP BY information_schema.statistics.INDEX_TYPE UNION \ 941 | SELECT 'TRIGGER' AS `TRIGGER`,COUNT(0) AS COUNT FROM information_schema.triggers \ 942 | WHERE information_schema.triggers.TRIGGER_SCHEMA='" + dbinfo[3] + "' UNION \ 943 | SELECT 'EVENT' AS object_type, COUNT(0) AS COUNT FROM information_schema.events \ 944 | WHERE information_schema.events.EVENT_SCHEMA='" + dbinfo[3] + "'" 945 | style = {1:'object_type,l',2: 'COUNT,r'} 946 | if save_as == "txt": 947 | f_print_query_table(conn, title, query, style,save_as) 948 | 949 | if config.get ( "option", "table_info" ) == 'ON': 950 | title = "Table Info" 951 | query = """select table_name,engine,row_format as format,table_rows,avg_row_length as avg_row, 952 | round((data_length)/1024/1024,2) as data_mb, 953 | round((index_length)/1024/1024,2) as index_mb, 954 | round((data_length+index_length)/1024/1024,2) as total_mb 955 | from information_schema.tables 956 | where table_schema='""" + dbinfo[3] + "'" 957 | style = {1: 'table_name,l', 2: 'engine,l', 3: 'format,l', 4: 'table_rows,r', 5: 'avg_row,r', 958 | 6: 'data_mb,r', 7: 'index_mb,r', 8: 'total_mb,r'} 959 | f_print_query_table(conn, title, query, style,save_as) 960 | 961 | if config.get ( "option", "index_info" ) == 'ON': 962 | title = "Index Info" 963 | query = """select index_name,non_unique,seq_in_index,column_name,collation,cardinality,nullable,index_type 964 | from information_schema.statistics 965 | where table_schema='""" + dbinfo[3] + "'" 966 | style = {1: 'index_name,l', 2: 'non_unique,l', 3: 'seq_in_index,l', 4: 'column_name,l', 967 | 5: 'collation,r', 6: 'cardinality,r', 7: 'nullable,r', 8: 'index_type,r'} 968 | f_print_query_table(conn, title, query, style,save_as) 969 | 970 | if config.get("option", "schema_index_statistics") == 'ON' and sys_schema_exist: 971 | title = "schema_index_statistics" 972 | query = """SELECT table_name,index_name ,rows_selected,select_latency,rows_inserted,insert_latency,rows_updated, 973 | update_latency,rows_deleted,delete_latency 974 | FROM sys.schema_index_statistics where table_schema='""" + dbinfo[3] + "' ORDER BY table_name" 975 | style = {1: 'table_name,l', 2: 'index_name,l', 3: 'rows_selected,r', 4: 'select_latency,r',5: 'rows_inserted,r', 976 | 6: 'insert_latency,r', 7: 'rows_updated,r', 8: 'update_latency,r', 9: 'rows_deleted,r',10: 'delete_latency,r'} 977 | f_print_query_table(conn, title, query, style,save_as) 978 | 979 | if config.get("option", "schema_table_statistics") == 'ON' and sys_schema_exist: 980 | title = "schema_table_statistics" 981 | query = """SELECT table_name,total_latency ,rows_fetched,fetch_latency,rows_inserted,insert_latency,rows_updated, 982 | update_latency,rows_deleted,delete_latency,io_read_requests,io_read,io_read_latency,io_write_requests, 983 | io_write,io_write_latency,io_misc_requests,io_misc_latency 984 | FROM sys.schema_table_statistics where table_schema='""" + dbinfo[3] + "' ORDER BY table_name" 985 | style = {1: 'table_name,l', 2: 'tal_ltc,r', 3: 'rw_ftc,r', 4: 'ftc_ltc,r', 986 | 5: 'rw_ins,r', 6: 'ins_ltc,r', 7: 'rw_upd,r', 8: 'upd_ltc,r', 987 | 9: 'rw_del,r', 10: 'del_ltc,r', 11: 'io_rd_rq,r', 12: 'io_read,r', 988 | 13: 'io_rd_ltc,r', 14: 'io_wt_rq,r', 15: 'io_write,r',16: 'io_wt_ltc,r', 989 | 17: 'io_ms_rq,r',18: 'io_ms_ltc,r'} 990 | f_print_query_table(conn, title, query, style,save_as) 991 | 992 | if config.get("option", "schema_table_statistics_with_buffer") == 'ON' and sys_schema_exist: 993 | title = "schema_table_statistics_with_buffer" 994 | query = """SELECT table_name,innodb_buffer_allocated,innodb_buffer_data,innodb_buffer_free,innodb_buffer_pages, 995 | innodb_buffer_pages_hashed,innodb_buffer_pages_old,innodb_buffer_rows_cached 996 | FROM sys.schema_table_statistics_with_buffer where table_schema='""" + dbinfo[3] + "' ORDER BY table_name" 997 | style = {1: 'table_name,l', 2: 'indb_buf_alc,r', 3: 'indb_buf_data,r', 4: 'indb_buf_free,r', 5: 'indb_buf_page,r', 998 | 6: 'indb_buf_page_hash,r', 7: 'indb_buf_page_old,r', 8: 'indb_buf_rw_cach,r'} 999 | f_print_query_table(conn, title, query, style, save_as) 1000 | 1001 | if config.get("option", "schema_tables_with_full_table_scans") == 'ON' and sys_schema_exist: 1002 | title = "schema_tables_with_full_table_scans" 1003 | query = """SELECT object_schema,object_name,rows_full_scanned,latency FROM sys.schema_tables_with_full_table_scans 1004 | where object_schema='""" + dbinfo[3] + "' ORDER BY object_name" 1005 | style = {1: 'object_schema,l', 2: 'object_name,l', 3: 'rows_full_scanned,r', 4: 'latency,r'} 1006 | f_print_query_table(conn, title, query, style,save_as) 1007 | 1008 | if config.get("option", "schema_unused_indexes") == 'ON' and sys_schema_exist: 1009 | title = "Schema Unused Indexes" 1010 | query = "SELECT object_schema,object_name,index_name FROM sys.schema_unused_indexes where object_schema='" + dbinfo[3] + "'" 1011 | style = {1: 'object_schema,l', 2: 'object_name,l', 3: 'index_name,l'} 1012 | f_print_query_table(conn, title, query, style,save_as) 1013 | 1014 | if config.get("option", "host_summary") == 'ON' and sys_schema_exist: 1015 | title = "host_summary" 1016 | #host 监听连接过的主机 statements 当前主机执行的语句总数 statement_latency 语句等待时间(延迟时间) statement_avg_latency 执行语句平均延迟时间 table_scans 表扫描次数 1017 | #file_ios io时间总数 file_io_latency 文件io延迟 current_connections 当前连接数 total_connections 总链接数 unique_users 该主机的唯一用户数 current_memory 当前账户分配的内存 1018 | #total_memory_allocated 该主机分配的内存总数 1019 | if "5.6" in mysql_version: 1020 | query = """SELECT host,statements,statement_latency,statement_avg_latency,table_scans,file_ios,file_io_latency,current_connections, 1021 | total_connections,unique_users 1022 | FROM sys.host_summary""" 1023 | style = {1: 'host,l', 2: 'statements,r', 3: 'st_ltc,r', 4: 'st_avg_ltc,r', 5: 'table_scan,r', 6: 'file_ios,r', 1024 | 7: 'f_io_ltc,r', 8: 'cur_conns,r', 9: 'total_conn,r', 10: 'unq_users,r'} 1025 | else: 1026 | query = """SELECT host,statements,statement_latency,statement_avg_latency,table_scans,file_ios,file_io_latency,current_connections, 1027 | total_connections,unique_users,current_memory,total_memory_allocated 1028 | FROM sys.host_summary""" 1029 | style = {1: 'host,l', 2: 'statements,r', 3: 'st_ltc,r', 4: 'st_avg_ltc,r', 5: 'table_scan,r', 6: 'file_ios,r', 1030 | 7: 'f_io_ltc,r', 8: 'cur_conns,r', 9: 'total_conn,r', 10: 'unq_users,r', 11: 'cur_mem,r', 1031 | 12: 'tal_mem_alc,r'} 1032 | f_print_query_table(conn, title, query, style,save_as) 1033 | 1034 | if config.get("option", "host_summary_by_file_io_type") == 'ON' and sys_schema_exist: 1035 | title = "host_summary_by_file_io_type" 1036 | #•host 主机 event_name IO事件名称 total 该主机发生的事件 total_latency 该主机发生IO事件总延迟时间 max_latency 该主机IO事件中最大的延迟时间 1037 | query = """SELECT host,event_name,total,total_latency,max_latency 1038 | FROM sys.host_summary_by_file_io_type""" 1039 | style = {1: 'host,l', 2: 'event_name,l', 3: 'total,r', 4: 'total_ltc,r', 5: 'max_ltc,r'} 1040 | f_print_query_table(conn, title, query, style,save_as) 1041 | 1042 | if config.get("option", "host_summary_by_file_io") == 'ON' and sys_schema_exist: 1043 | title = "host_summary_by_file_io_type" 1044 | #•host 主机 ios IO事件总数 io_latency IO总的延迟时间 1045 | query = """SELECT host,ios,io_latency 1046 | FROM sys.host_summary_by_file_io""" 1047 | style = {1: 'host,l', 2: 'ios,r', 3: 'io_latency,r'} 1048 | f_print_query_table(conn, title, query, style,save_as) 1049 | 1050 | if config.get("option", "host_summary_by_stages") == 'ON' and sys_schema_exist: 1051 | title = "host_summary_by_stages" 1052 | #•host 主机 event_name stage event名称 total stage event发生的总数 total_latency stage event总的延迟时间 avg_latency stage event平均延迟时间 1053 | query = """SELECT host,event_name,total,total_latency,avg_latency 1054 | FROM sys.host_summary_by_stages""" 1055 | style = {1: 'host,l', 2: 'event_name,l', 3: 'total,r', 4: 'total_latency,r', 5: 'avg_latency,r'} 1056 | f_print_query_table(conn, title, query, style,save_as) 1057 | 1058 | if config.get("option", "host_summary_by_statement_latency") == 'ON' and sys_schema_exist: 1059 | title = "host_summary_by_statement_latency" 1060 | #host 主机 total 这个主机的语句总数 total_latency 这个主机总的延迟时间 max_latency 主机最大的延迟时间 lock_latency 等待锁的锁延迟时间 1061 | #rows_sent 该主机通过语句返回的总行数 rows_examined 在存储引擎上通过语句返回的行数 rows_affected 该主机通过语句影响的总行数 full_scans 全表扫描的语句总数 1062 | query = """SELECT host,total,total_latency,max_latency,lock_latency,rows_sent,rows_examined,rows_affected,full_scans 1063 | FROM sys.host_summary_by_statement_latency""" 1064 | style = {1: 'host,l', 2: 'total,r', 3: 'total_latency,r', 4: 'max_latency,r', 5: 'lock_latency,r', 1065 | 6: 'rows_sent,r', 7: 'rows_examined,r', 8: 'rows_affected,r',9: 'full_scans,r'} 1066 | f_print_query_table(conn, title, query, style,save_as) 1067 | 1068 | if config.get("option", "host_summary_by_statement_type") == 'ON' and sys_schema_exist: 1069 | title = "host_summary_by_statement_type" 1070 | #host 主机 statement 最后的语句事件名称 total sql语句总数 total_latency sql语句总延迟数 max_latency 最大的sql语句延迟数 1071 | # lock_latency 锁延迟总数 rows_sent 语句返回的行总数 rows_examined 通过存储引擎的sql语句的读取的总行数 rows_affected 语句影响的总行数 full_scans 全表扫描的语句事件总数 1072 | query = """SELECT host,statement,total,total_latency,max_latency,lock_latency,rows_sent,rows_examined,rows_affected,full_scans 1073 | FROM sys.host_summary_by_statement_type""" 1074 | style = {1: 'host,l', 2: 'statement,l', 3: 'total,r', 4: 'total_latency,r', 5: 'max_latency,r', 1075 | 6: 'lock_latency,r', 7: 'rows_sent,r', 8: 'rows_examined,r',9: 'rows_affected,r',10: 'full_scans,r'} 1076 | f_print_query_table(conn, title, query, style,save_as) 1077 | 1078 | if config.get("option", "user_summary") == 'ON' and sys_schema_exist: 1079 | title = "user_summary" 1080 | # statements 当前用户执行的语句总数 statement_latency 语句等待时间(延迟时间) statement_avg_latency 执行语句平均延迟时间 table_scans 表扫描次数 1081 | #file_ios io时间总数 file_io_latency 文件io延迟 current_connections 当前连接数 total_connections 总链接数 unique_users 该用户的唯一主机数 current_memory 当前账户分配的内存 1082 | #total_memory_allocated 该主机分配的内存总数 1083 | if "5.6" in mysql_version: 1084 | 1085 | query = """SELECT user,statements,statement_latency,statement_avg_latency,table_scans,file_ios,file_io_latency,current_connections, 1086 | total_connections,unique_hosts 1087 | FROM sys.user_summary""" 1088 | style = {1: 'user,l', 2: 'statements,r', 3: 'st_ltc,r', 4: 'st_avg_ltc,r', 5: 'table_scan,r', 6: 'file_ios,r', 1089 | 7: 'f_io_ltc,r', 8: 'cur_conns,r', 9: 'total_conn,r', 10: 'unq_hosts,r'} 1090 | else: 1091 | query = """SELECT user,statements,statement_latency,statement_avg_latency,table_scans,file_ios,file_io_latency,current_connections, 1092 | total_connections,unique_hosts,current_memory,total_memory_allocated 1093 | FROM sys.user_summary""" 1094 | style = {1: 'user,l', 2: 'statements,r', 3: 'st_ltc,r', 4: 'st_avg_ltc,r', 5: 'table_scan,r', 6: 'file_ios,r', 1095 | 7: 'f_io_ltc,r', 8: 'cur_conns,r', 9: 'total_conn,r', 10: 'unq_hosts,r', 11: 'cur_mem,r', 12: 'tal_mem_alc,r'} 1096 | f_print_query_table(conn, title, query, style,save_as) 1097 | 1098 | if config.get("option", "user_summary_by_file_io_type") == 'ON' and sys_schema_exist: 1099 | title = "user_summary_by_file_io_type" 1100 | #event_name IO事件名称 total 该用户发生的事件 total_latency 该用户发生IO事件总延迟时间 max_latency 该用户IO事件中最大的延迟时间 1101 | query = """SELECT user,event_name,total,latency,max_latency 1102 | FROM sys.user_summary_by_file_io_type""" 1103 | style = {1: 'user,l', 2: 'event_name,l', 3: 'total,r', 4: 'latency,r', 5: 'max_ltc,r'} 1104 | f_print_query_table(conn, title, query, style,save_as) 1105 | 1106 | if config.get("option", "user_summary_by_file_io") == 'ON' and sys_schema_exist: 1107 | title = "user_summary_by_file_io_type" 1108 | # ios IO事件总数 io_latency IO总的延迟时间 1109 | query = """SELECT user,ios,io_latency 1110 | FROM sys.user_summary_by_file_io""" 1111 | style = {1: 'user,l', 2: 'ios,r', 3: 'io_latency,r'} 1112 | f_print_query_table(conn, title, query, style,save_as) 1113 | 1114 | if config.get("option", "user_summary_by_stages") == 'ON' and sys_schema_exist: 1115 | title = "user_summary_by_stages" 1116 | # event_name stage event名称 total stage event发生的总数 total_latency stage event总的延迟时间 avg_latency stage event平均延迟时间 1117 | query = """SELECT user,event_name,total,total_latency,avg_latency 1118 | FROM sys.user_summary_by_stages""" 1119 | style = {1: 'user,l', 2: 'event_name,l', 3: 'total,r', 4: 'total_latency,r', 5: 'avg_latency,r'} 1120 | f_print_query_table(conn, title, query, style,save_as) 1121 | 1122 | if config.get("option", "user_summary_by_statement_latency") == 'ON' and sys_schema_exist: 1123 | title = "user_summary_by_statement_latency" 1124 | # total 这个主机的语句总数 total_latency 这个主机总的延迟时间 max_latency 主机最大的延迟时间 lock_latency 等待锁的锁延迟时间 1125 | #rows_sent 该主机通过语句返回的总行数 rows_examined 在存储引擎上通过语句返回的行数 rows_affected 该主机通过语句影响的总行数 full_scans 全表扫描的语句总数 1126 | query = """SELECT user,total,total_latency,max_latency,lock_latency,rows_sent,rows_examined,rows_affected,full_scans 1127 | FROM sys.user_summary_by_statement_latency""" 1128 | style = {1: 'user,l', 2: 'total,r', 3: 'total_latency,r', 4: 'max_latency,r', 5: 'lock_latency,r', 1129 | 6: 'rows_sent,r', 7: 'rows_examined,r', 8: 'rows_affected,r',9: 'full_scans,r'} 1130 | f_print_query_table(conn, title, query, style,save_as) 1131 | 1132 | if config.get("option", "user_summary_by_statement_type") == 'ON' and sys_schema_exist: 1133 | title = "user_summary_by_statement_type" 1134 | #statement 最后的语句事件名称 total sql语句总数 total_latency sql语句总延迟数 max_latency 最大的sql语句延迟数 1135 | # lock_latency 锁延迟总数 rows_sent 语句返回的行总数 rows_examined 通过存储引擎的sql语句的读取的总行数 rows_affected 语句影响的总行数 full_scans 全表扫描的语句事件总数 1136 | query = """SELECT user,statement,total,total_latency,max_latency,lock_latency,rows_sent,rows_examined,rows_affected,full_scans 1137 | FROM sys.user_summary_by_statement_type""" 1138 | style = {1: 'user,l', 2: 'statement,l', 3: 'total,r', 4: 'total_latency,r', 5: 'max_latency,r', 1139 | 6: 'lock_latency,r', 7: 'rows_sent,r', 8: 'rows_examined,r',9: 'rows_affected,r',10: 'full_scans,r'} 1140 | f_print_query_table(conn, title, query, style,save_as) 1141 | 1142 | if config.get("option", "innodb_buffer_stats_by_schema") == 'ON' and sys_schema_exist: 1143 | title = "innodb_buffer_stats_by_schema" 1144 | #object_schema 数据库名称 allocated 分配给当前数据库的总的字节数 data 分配给当前数据库的数据字节数 pages 分配给当前数据库的总页数 1145 | # pages_hashed 分配给当前数据库的hash页数 pages_old 分配给当前数据库的旧页数 rows_cached 当前数据库缓存的行数 1146 | query = """SELECT object_schema,allocated,data,pages,pages_hashed,pages_old,rows_cached 1147 | FROM sys.innodb_buffer_stats_by_schema""" 1148 | style = {1: 'object_schema,l', 2: 'allocated,r', 3: 'data,r', 4: 'pages,r', 5: 'pages_hashed,r', 1149 | 6: 'pages_old,r', 7: 'rows_cached,r'} 1150 | f_print_query_table(conn, title, query, style,save_as) 1151 | 1152 | if config.get("option", "innodb_buffer_stats_by_table") == 'ON' and sys_schema_exist: 1153 | title = "innodb_buffer_stats_by_table" 1154 | # object_schema 数据库名称 object_name 表名称 allocated 分配给表的总字节数 data 分配该表的数据字节数 pages 分配给表的页数 1155 | # pages_hashed 分配给表的hash页数 pages_old 分配给表的旧页数 rows_cached 表的行缓存数 1156 | query = """SELECT object_schema,object_name,allocated,data,pages,pages_hashed,pages_old,rows_cached 1157 | FROM sys.innodb_buffer_stats_by_table""" 1158 | style = {1: 'object_schema,l', 2: 'object_name,l', 3: 'allocated,r', 4: 'data,r', 5: 'pages,r', 1159 | 6: 'pages_hashed,r', 7: 'pages_old,r', 8: 'rows_cached,r'} 1160 | f_print_query_table(conn, title, query, style,save_as) 1161 | 1162 | if config.get("option", "io_by_thread_by_latency_topN") <> 'OFF' and sys_schema_exist: 1163 | topN = int(config.get("option", "io_by_thread_by_latency_topN")) 1164 | title = "io_by_thread_by_latency top"+str(topN) 1165 | #user 对于当前线程来说,这个值是线程被分配的账户,对于后台线程来讲,就是线程的名称 total IO事件的总数 total_latency IO事件的总延迟 1166 | # min_latency 单个最小的IO事件延迟 avg_latency 平均IO延迟 max_latency 最大IO延迟 thread_id 线程ID processlist_id 对于当前线程就是此时的ID,对于后台就是null 1167 | query = """SELECT user,total,total_latency,min_latency,avg_latency,max_latency,thread_id,processlist_id 1168 | FROM sys.io_by_thread_by_latency LIMIT """+str(topN) 1169 | style = {1: 'user,l', 2: 'total,r', 3: 'total_latency,r', 4: 'min_latency,r', 5: 'avg_latency,r', 1170 | 6: 'max_latency,r', 7: 'thread_id,r', 8: 'processlist_id,r'} 1171 | f_print_query_table(conn, title, query, style,save_as) 1172 | 1173 | if config.get("option", "io_global_by_file_by_bytes_topN") <> 'OFF' and sys_schema_exist: 1174 | topN = int(config.get("option", "io_global_by_file_by_bytes_topN")) 1175 | title = "io_global_by_file_by_bytes top"+str(topN) 1176 | query = """SELECT file,count_read,total_read,avg_read,count_write,total_written,avg_write,total,write_pct 1177 | FROM sys.io_global_by_file_by_bytes LIMIT """+str(topN) 1178 | style = {1: 'file,l', 2: 'count_read,r', 3: 'total_read,r', 4: 'avg_read,r', 5: 'count_write,r', 1179 | 6: 'total_written,r', 7: 'avg_write,r', 8: 'total,r', 9: 'write_pct,r'} 1180 | f_print_query_table(conn, title, query, style,save_as) 1181 | 1182 | if config.get("option", "io_global_by_file_by_latency_topN") <> 'OFF' and sys_schema_exist: 1183 | topN = int(config.get("option", "io_global_by_file_by_latency_topN")) 1184 | title = "io_global_by_file_by_latency top"+str(topN) 1185 | query = """SELECT file,total,total_latency,count_read,read_latency,count_write,write_latency,count_misc,misc_latency 1186 | FROM sys.io_global_by_file_by_latency LIMIT """+str(topN) 1187 | style = {1: 'file,l', 2: 'total,r', 3: 'total_latency,r', 4: 'count_read,r', 5: 'read_latency,r', 1188 | 6: 'count_write,r', 7: 'write_latency,r', 8: 'count_misc,r', 9: 'misc_latency,r'} 1189 | f_print_query_table(conn, title, query, style,save_as) 1190 | 1191 | if config.get("option", "io_global_by_wait_by_bytes_topN") <> 'OFF' and sys_schema_exist: 1192 | topN = int(config.get("option", "io_global_by_wait_by_bytes_topN")) 1193 | title = "io_global_by_wait_by_bytes top"+str(topN) 1194 | query = """SELECT event_name,total,total_latency,min_latency,avg_latency,max_latency,count_read,total_read,avg_read,count_write, 1195 | total_written,avg_written,total_requested 1196 | FROM sys.io_global_by_wait_by_bytes LIMIT """+str(topN) 1197 | style = {1: 'event_name,l', 2: 'total,r', 3: 'total_latency,r', 4: 'min_latency,r', 5: 'avg_latency,r', 1198 | 6: 'max_latency,r', 7: 'count_read,r', 8: 'total_read,r', 9: 'avg_read,r', 10: 'count_write,r', 1199 | 11: 'total_written,r', 12: 'avg_written,r', 13: 'total_requested,r'} 1200 | f_print_query_table(conn, title, query, style,save_as) 1201 | 1202 | if config.get("option", "io_global_by_wait_by_latency_topN") <> 'OFF' and sys_schema_exist: 1203 | topN = int(config.get("option", "io_global_by_wait_by_latency_topN")) 1204 | title = "io_global_by_wait_by_latency top"+str(topN) 1205 | query = """SELECT event_name,total,total_latency,avg_latency,max_latency,read_latency,write_latency,misc_latency,count_read, 1206 | total_read,avg_read,count_write,total_written,avg_written 1207 | FROM sys.io_global_by_wait_by_latency LIMIT """+str(topN) 1208 | style = {1: 'event_name,l', 2: 'total,r', 3: 'total_latency,r', 4: 'avg_latency,r', 5: 'max_latency,r', 1209 | 6: 'read_latency,r', 7: 'write_latency,r', 8: 'misc_latency,r', 9: 'count_read,r', 10: 'total_read,r', 1210 | 11: 'avg_read,r', 12: 'count_write,r', 13: 'total_written,r', 14: 'avg_written,r'} 1211 | f_print_query_table(conn, title, query, style,save_as) 1212 | 1213 | if config.get("option", "wait_classes_global_by_avg_latency") == 'ON' and sys_schema_exist: 1214 | title = "wait_classes_global_by_avg_latency" 1215 | query = """SELECT event_class,total,total_latency,min_latency,avg_latency,max_latency 1216 | FROM sys.wait_classes_global_by_avg_latency""" 1217 | style = {1: 'event_class,l', 2: 'total,r', 3: 'total_latency,r',4: 'min_latency,r', 5: 'avg_latency,r', 6: 'max_latency,r'} 1218 | f_print_query_table(conn, title, query, style,save_as) 1219 | 1220 | if config.get("option", "wait_classes_global_by_latency") == 'ON' and sys_schema_exist: 1221 | title = "wait_classes_global_by_latency" 1222 | query = """SELECT event_class,total,total_latency,min_latency,avg_latency,max_latency 1223 | FROM sys.wait_classes_global_by_latency""" 1224 | style = {1: 'event_class,l', 2: 'total,r', 3: 'total_latency,r',4: 'min_latency,r', 5: 'avg_latency,r', 6: 'max_latency,r'} 1225 | f_print_query_table(conn, title, query, style,save_as) 1226 | 1227 | if config.get("option", "waits_by_host_by_latency") == 'ON' and sys_schema_exist: 1228 | title = "waits_by_host_by_latency" 1229 | query = """SELECT HOST,EVENT,total,total_latency,avg_latency,max_latency 1230 | FROM sys.waits_by_host_by_latency """ 1231 | style = {1: 'host,l',2: 'event,l', 3: 'total,r', 4: 'total_latency,r',5: 'avg_latency,r', 6: 'max_latency,r'} 1232 | f_print_query_table(conn, title, query, style,save_as) 1233 | 1234 | if config.get("option", "waits_by_user_by_latency") == 'ON' and sys_schema_exist: 1235 | title = "waits_by_user_by_latency" 1236 | query = """SELECT USER,EVENT,total,total_latency,avg_latency,max_latency 1237 | FROM sys.waits_by_user_by_latency """ 1238 | style = {1: 'user,l',2: 'event,l', 3: 'total,r', 4: 'total_latency,r',5: 'avg_latency,r', 6: 'max_latency,r'} 1239 | f_print_query_table(conn, title, query, style,save_as) 1240 | 1241 | if config.get("option", "waits_global_by_latency") == 'ON' and sys_schema_exist: 1242 | title = "waits_global_by_latency" 1243 | query = """SELECT EVENTS,total,total_latency,avg_latency,max_latency 1244 | FROM sys.waits_global_by_latency """ 1245 | style = {1: 'event,l', 2: 'total,r', 3: 'total_latency,r',4: 'avg_latency,r', 5: 'max_latency,r'} 1246 | f_print_query_table(conn, title, query, style,save_as) 1247 | 1248 | if config.get("option", "schema_table_lock_waits") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1249 | title = "schema_table_lock_waits" 1250 | query = """SELECT object_schema,object_name,waiting_account,waiting_lock_type, 1251 | waiting_lock_duration,waiting_query,waiting_query_secs,waiting_query_rows_affected,waiting_query_rows_examined, 1252 | blocking_account,blocking_lock_type,blocking_lock_duration 1253 | FROM sys.schema_table_lock_waits""" 1254 | #,sql_kill_blocking_query,sql_kill_blocking_connection 1255 | style = {1: 'object_schema,l', 2: 'object_name,r', 3: 'wait_account,r', 4: 'wt_lk_tp,l', 5: 'w_l_dur,l', 1256 | 6: 'waiting_query,l', 7: 'w_qry_s,l', 8: 'w_q_r_a,l',9: 'w_q_r_e,l',10: 'blk_account,l', 1257 | 11: 'bk_lk_tp,l',12: 'b_l_dur,l'} 1258 | f_print_query_table(conn, title, query, style,save_as) 1259 | 1260 | if config.get("option", "innodb_lock_waits") == 'ON' and sys_schema_exist: 1261 | title = "innodb_lock_waits" 1262 | #wait_started 锁等待发生的时间 wait_age 锁已经等待了多长时间 wait_age_secs 以秒为单位显示锁已经等待的时间 1263 | #locked_table 被锁的表 locked_index 被锁住的索引 locked_type 锁类型 waiting_trx_id 正在等待的事务ID waiting_trx_started 等待事务开始的时间 1264 | #waiting_trx_age 已经等待事务多长时间 waiting_trx_rows_locked 正在等待的事务被锁的行数量 waiting_trx_rows_modified 正在等待行重定义的数量 1265 | #waiting_pid 正在等待事务的线程id waiting_query 正在等待锁的查询 waiting_lock_id 正在等待锁的ID waiting_lock_mode 等待锁的模式 1266 | #blocking_trx_id 阻塞等待锁的事务id blocking_pid 正在锁的线程id blocking_query 正在锁的查询 blocking_lock_id 正在阻塞等待锁的锁id. 1267 | #blocking_lock_mode 阻塞锁模式 blocking_trx_started 阻塞事务开始的时间 blocking_trx_age 阻塞的事务已经执行的时间 blocking_trx_rows_locked 阻塞事务锁住的行的数量 1268 | # blocking_trx_rows_modified 阻塞事务重定义行的数量 sql_kill_blocking_query kill 语句杀死正在运行的阻塞事务 sql_kill_blocking_connection kill 语句杀死会话中正在运行的阻塞事务 1269 | query = """SELECT wait_started,wait_age,locked_table,locked_index,locked_type,waiting_query,waiting_lock_mode,blocking_query,blocking_lock_mode 1270 | FROM sys.innodb_lock_waits""" 1271 | style = {1: 'wait_start,l', 2: 'wait_age,r', 3: 'locked_table,r', 4: 'locked_index,l', 5: 'locked_type,l', 1272 | 6: 'waiting_query,l', 7: 'wt_lk_md,l', 8: 'blocking_query,l',9: 'bk_lk_md,l'} 1273 | f_print_query_table(conn, title, query, style,save_as) 1274 | 1275 | if config.get("option", "memory_by_host_by_current_bytes") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1276 | title = "memory_by_host_by_current_bytes" 1277 | query = """SELECT HOST,current_count_used,current_allocated,current_avg_alloc,current_max_alloc,total_allocated 1278 | FROM sys.memory_by_host_by_current_bytes""" 1279 | style = {1: 'HOST,l', 2: 'crt_count_used,r', 3: 'crt_allocatedc,r',4: 'crt_avg_alloc,r', 5: 'crt_max_alloc,r',6: 'tal_alloc,r'} 1280 | f_print_query_table(conn, title, query, style,save_as) 1281 | 1282 | if config.get("option", "memory_by_thread_by_current_bytes") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1283 | title = "memory_by_thread_by_current_bytes" 1284 | query = """SELECT thread_id,USER,current_count_used,current_allocated,current_avg_alloc,current_max_alloc,total_allocated 1285 | FROM sys.memory_by_thread_by_current_bytes ORDER BY thread_id""" 1286 | style = {1: 'thread_id,r', 2: 'USER,l', 3: 'crt_count_used,r', 4: 'crt_allocatedc,r',5: 'crt_avg_alloc,r', 6: 'crt_max_alloc,r',7: 'tal_alloc,r'} 1287 | f_print_query_table(conn, title, query, style,save_as) 1288 | 1289 | if config.get("option", "memory_by_user_by_current_bytes") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1290 | title = "memory_by_user_by_current_bytes" 1291 | query = """SELECT USER,current_count_used,current_allocated,current_avg_alloc,current_max_alloc,total_allocated 1292 | FROM sys.memory_by_user_by_current_bytes""" 1293 | style = {1: 'USER,l', 2: 'crt_count_used,r', 3: 'crt_alloc,r',4: 'crt_avg_alloc,r', 5: 'crt_max_alloc,r',6: 'tal_alloc,r'} 1294 | f_print_query_table(conn, title, query, style,save_as) 1295 | 1296 | if config.get("option", "memory_global_by_current_bytes") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1297 | title = "memory_global_by_current_bytes" 1298 | query = """SELECT event_name,current_count,current_alloc,current_avg_alloc,high_count,high_alloc,high_avg_alloc 1299 | FROM sys.memory_global_by_current_bytes ORDER BY current_alloc DESC""" 1300 | style = {1: 'event_name,l', 2: 'crt_count,r', 3: 'crt_alloc,r',4: 'crt_avg_alloc,r', 5: 'high_count,r',6: 'high_alloc,r',7: 'high_avg_alloc,r'} 1301 | f_print_query_table(conn, title, query, style,save_as) 1302 | 1303 | if config.get("option", "memory_global_total") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1304 | title = "memory_global_total" 1305 | query = """SELECT total_allocated FROM sys.memory_global_total""" 1306 | style = {1: 'total_allocated,r'} 1307 | f_print_query_table(conn, title, query, style,save_as) 1308 | 1309 | if config.get ( "option", "processlist" ) == 'ON' and sys_schema_exist: 1310 | title = "processlist" 1311 | query = """SELECT thd_id,USER,command,TIME,current_statement,statement_latency,full_scan,last_statement,last_statement_latency 1312 | FROM sys.processlist 1313 | where db='""" + dbinfo[3] + "'" 1314 | style = {1: 'thd_id,r', 2: 'USER,l', 3: 'command,r', 4:'TIME,r', 5: 'current_sql,r',6: 'sql_ltc,r', 1315 | 7: 'fscan,r',8: 'last_sql,r',9: 'lsql_ltc,r'} 1316 | f_print_query_table(conn, title, query, style,save_as) 1317 | 1318 | if config.get ( "option", "session" ) == 'ON' and sys_schema_exist: 1319 | title = "session" 1320 | query = """SELECT thd_id,USER,command,TIME,current_statement,statement_latency,lock_latency,full_scan,last_statement,last_statement_latency 1321 | FROM sys.session 1322 | where db='""" + dbinfo[3] + "'" 1323 | style = {1: 'thd_id,r', 2: 'USER,l', 3: 'command,r', 4:'TIME,r', 5: 'current_sql,r',6: 'sql_ltc,r', 1324 | 7: 'lock_ltc,r',8: 'fscan,r',9: 'last_sql,r',10: 'lsql_ltc,r'} 1325 | f_print_query_table(conn, title, query, style,save_as) 1326 | 1327 | if config.get ( "option", "metrics" ) == 'ON' and sys_schema_exist: 1328 | title = "metrics" 1329 | query = """SELECT Variable_name,Variable_value,TYPE,Enabled 1330 | FROM sys.metrics 1331 | WHERE Variable_name<>'rsa_public_key' and Variable_name<>'ssl_cipher_list' and Enabled='YES'""" 1332 | style = {1: 'Variable_name,l', 2: 'Variable_value,r', 3: 'TYPE,l', 4:'Enabled,r'} 1333 | f_print_query_table(conn, title, query, style,save_as) 1334 | 1335 | conn.close() 1336 | f_print_ending(save_as) -------------------------------------------------------------------------------- /mysql_watcher.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | report_base=/services/script 3 | datetime=`date +%Y-%m-%d_%H-%M` 4 | python $report_base/mysql_watcher.py -p $report_base/dbset101.ini -s html>$report_base/mysql_watcher101_$datetime.html 5 | python $report_base/mysql_watcher.py -p $report_base/dbset102.ini -s html>$report_base/mysql_watcher102_$datetime.html 6 | python $report_base/SendEmail.py -p $report_base/emailset101.ini -f $report_base/mysql_watcher101_$datetime.html,$report_base/mysql_watcher102_$datetime.html 7 | -------------------------------------------------------------------------------- /mysql_watcher3.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python 2 | # coding: utf-8 3 | 4 | # MySQL Watcher V1.3.0 for python3 5 | # trouble shoot MySQL performance 6 | # Copyright (C) 2017-2017 Kinghow - Kinghow@hotmail.com 7 | # Git repository available at https://github.com/kinghows/MySQL_Watcher 8 | 9 | import getopt 10 | import sys 11 | import MySQLdb 12 | import configparser 13 | import math 14 | import time 15 | import os 16 | import prettytable 17 | import psutil 18 | import platform 19 | import glob 20 | import re 21 | from collections import OrderedDict 22 | from collections import namedtuple 23 | from warnings import filterwarnings 24 | 25 | filterwarnings('ignore', category = MySQLdb.Warning) 26 | 27 | tab1="=" 28 | tab2="*" 29 | linesize=104 30 | 31 | SYS_PARM_FILTER = ( 32 | 'autocommit', 33 | 'binlog_cache_size', 34 | 'bulk_insert_buffer_size', 35 | 'character_set_server', 36 | 'tx_isolation', 37 | 'tx_read_only', 38 | 'sql_mode', 39 | # connection # 40 | 'interactive_timeout', 41 | 'wait_timeout', 42 | 'lock_wait_timeout', 43 | 'skip_name_resolve', 44 | 'max_connections', 45 | 'max_connect_errors', 46 | # table cache performance settings 47 | 'table_open_cache', 48 | 'table_definition_cache', 49 | 'table_open_cache_instances', 50 | # performance settings 51 | 'have_query_cache', 52 | 'join_buffer_size', 53 | 'key_buffer_size', 54 | 'key_cache_age_threshold', 55 | 'key_cache_block_size', 56 | 'key_cache_division_limit', 57 | 'large_pages', 58 | 'locked_in_memory', 59 | 'long_query_time', 60 | 'max_allowed_packet', 61 | 'max_binlog_size', 62 | 'max_length_for_sort_data', 63 | 'max_sort_length', 64 | 'max_tmp_tables', 65 | 'max_user_connections', 66 | 'optimizer_prune_level', 67 | 'optimizer_search_depth', 68 | 'query_cache_size', 69 | 'query_cache_type', 70 | 'query_prealloc_size', 71 | 'range_alloc_block_size', 72 | # session memory settings # 73 | 'read_buffer_size', 74 | 'read_rnd_buffer_size', 75 | 'sort_buffer_size', 76 | 'tmp_table_size', 77 | 'join_buffer_size', 78 | 'thread_cache_size', 79 | # log settings # 80 | 'log_error', 81 | 'slow_query_log', 82 | 'slow_query_log_file', 83 | 'log_queries_not_using_indexes', 84 | 'log_slow_admin_statements', 85 | 'log_slow_slave_statements', 86 | 'log_throttle_queries_not_using_indexes', 87 | 'expire_logs_days', 88 | 'long_query_time', 89 | 'min_examined_row_limit', 90 | 'binlog-rows-query-log-events', 91 | 'log-bin-trust-function-creators', 92 | 'expire-logs-days', 93 | 'log-slave-updates', 94 | # innodb settings # 95 | 'innodb_page_size', 96 | 'innodb_buffer_pool_size', 97 | 'innodb_buffer_pool_instances', 98 | 'innodb_buffer_pool_chunk_size', 99 | 'innodb_buffer_pool_load_at_startup', 100 | 'innodb_buffer_pool_dump_at_shutdown', 101 | 'innodb_lru_scan_depth', 102 | 'innodb_lock_wait_timeout', 103 | 'innodb_io_capacity', 104 | 'innodb_io_capacity_max', 105 | 'innodb_flush_method', 106 | 'innodb_file_format', 107 | 'innodb_file_format_max', 108 | 'innodb_undo_logs', 109 | 'innodb_undo_tablespaces', 110 | 'innodb_flush_neighbors', 111 | 'innodb_log_file_size', 112 | 'innodb_log_files_in_group', 113 | 'innodb_log_buffer_size', 114 | 'innodb_purge_threads', 115 | 'innodb_large_prefix', 116 | 'innodb_thread_concurrency', 117 | 'innodb_print_all_deadlocks', 118 | 'innodb_strict_mode', 119 | 'innodb_sort_buffer_size', 120 | 'innodb_write_io_threads', 121 | 'innodb_read_io_threads', 122 | 'innodb_file_per_table', 123 | 'innodb_stats_persistent_sample_pages', 124 | 'innodb_autoinc_lock_mode', 125 | 'innodb_online_alter_log_max_size', 126 | 'innodb_open_files', 127 | # replication settings # 128 | 'master_info_repository', 129 | 'relay_log_info_repository', 130 | 'sync_binlog', 131 | 'gtid_mode', 132 | 'enforce_gtid_consistency', 133 | 'log_slave_updates', 134 | 'binlog_format', 135 | 'binlog_rows_query_log_events', 136 | 'relay_log', 137 | 'relay_log_recovery', 138 | 'slave_skip_errors', 139 | 'slave-rows-search-algorithms', 140 | # semi sync replication settings # 141 | 'plugin_load', 142 | 'rpl_semi_sync_master_enabled', 143 | 'rpl_semi_sync_master_timeout', 144 | 'rpl_semi_sync_slave_enabled', 145 | # password plugin # 146 | 'validate_password_policy', 147 | 'validate-password', 148 | # metalock performance settings 149 | 'metadata_locks_hash_instances', 150 | # new innodb settings # 151 | 'loose_innodb_numa_interleave', 152 | 'innodb_buffer_pool_dump_pct', 153 | 'innodb_page_cleaners', 154 | 'innodb_undo_log_truncate', 155 | 'innodb_max_undo_log_size', 156 | 'innodb_purge_rseg_truncate_frequency', 157 | # new replication settings # 158 | 'slave-parallel-type', 159 | 'slave-parallel-workers', 160 | 'slave_preserve_commit_order', 161 | 'slave_transaction_retries', 162 | # other change settings # 163 | 'binlog_gtid_simple_recovery', 164 | 'log_timestamps', 165 | 'show_compatibility_56' 166 | ) 167 | 168 | def f_get_conn(dbinfo): 169 | try: 170 | conn = MySQLdb.connect(host=dbinfo[0],user=dbinfo[1],passwd=dbinfo[2],db=dbinfo[3],port=int(dbinfo[4])) 171 | return conn 172 | except MySQLdb.Error as e: 173 | print ("Error %d: %s" % (e.args[0], e.args[1])) 174 | sys.exit(1) 175 | 176 | def f_get_query_value(conn, query): 177 | cursor = conn.cursor() 178 | getNum = cursor.execute(query) 179 | if getNum > 0: 180 | result = cursor.fetchone() 181 | else: 182 | result = ['0'] 183 | cursor.close() 184 | return result[0] 185 | 186 | def f_get_query_record(conn, query): 187 | cursor = conn.cursor() 188 | cursor.execute(query) 189 | records = cursor.fetchall() 190 | cursor.close() 191 | return records 192 | 193 | def f_print_title(title): 194 | print () 195 | print (int((linesize-4)/2 - int(len(title)/2)) * tab1, title, int((linesize-4)/2+1 - int(len(title)/2)) * tab1) 196 | print () 197 | 198 | def f_print_table_body(rows, style,tab): 199 | for row in rows: 200 | k = 0 201 | for col in row: 202 | k += 1 203 | print (tab,end='') 204 | if style[k].split(',')[2] == 'l': 205 | print (str(col).ljust(int(style[k].split(',')[1])),end='') 206 | elif style[k].split(',')[2] == 'r': 207 | print (str(col).rjust(int(style[k].split(',')[1])),end='') 208 | else: 209 | print (str(col).center(int(style[k].split(',')[1])),end='') 210 | print (tab) 211 | 212 | def f_print_table_txt(rows, title, style): 213 | field_names = [] 214 | f_print_title(title) 215 | table = prettytable.PrettyTable() 216 | for k in style.keys(): 217 | field_names.append(style[k].split(',')[0]) 218 | table.field_names = field_names 219 | for k in style.keys(): 220 | table.align[style[k].split(',')[0]] = style[k].split(',')[1] 221 | for row in rows: 222 | table.add_row(row) 223 | print (table) 224 | 225 | def f_print_table_html(rows, title, style): 226 | print ("""

""" + title + "

") 227 | print ("""""") 228 | 229 | print ("""""",end='') 230 | for k in style.keys(): 231 | v = style[k] 232 | print ("""""",end='') 235 | print ("""""") 236 | 237 | linenum = 0 238 | for row in rows: 239 | k = 0 240 | linenum += 1 241 | print ("",end='') 242 | if linenum % 2 == 0: 243 | classs='awrc' 244 | else: 245 | classs='awrnc' 246 | 247 | for col in row: 248 | k += 1 249 | if style[k].split(',')[1] == 'r': 250 | print ("""",end='') 251 | else: 252 | print ("""",end='') 253 | print ("") 254 | print ("""
""",end='') 233 | print (v.split(',')[0],end='') 234 | print ("""
"+str(col)+""+str(col)+"
255 |
Back to Top 256 |

257 |

258 | """) 259 | 260 | def f_print_table(rows,title,style,save_as): 261 | if save_as == "txt": 262 | f_print_table_txt(rows, title, style) 263 | elif save_as == "html": 264 | f_print_table_html(rows, title, style) 265 | 266 | def f_print_query_table(conn, title, query, style,save_as): 267 | rows = f_get_query_record(conn, query) 268 | f_print_table(rows,title,style,save_as) 269 | 270 | def f_is_sys_schema_exist(conn): 271 | query = "SHOW DATABASES" 272 | rows = f_get_query_record(conn, query) 273 | exist=False 274 | for row in rows: 275 | if row[0]=='sys': 276 | exist = True 277 | break 278 | return exist 279 | 280 | def f_print_optimizer_switch(conn,save_as,perfor_or_infor): 281 | title = "Optimizer Switch" 282 | style = {1: 'switch_name,l', 2: 'value,r'} 283 | rows =[] 284 | query="select variable_value from "+perfor_or_infor+".global_variables where variable_name='optimizer_switch'" 285 | recode = f_get_query_record(conn, query) 286 | for col in recode[0][0].split(','): 287 | rows.append([col.split('=')[0],col.split('=')[1]]) 288 | f_print_table(rows, title, style,save_as) 289 | 290 | def f_print_log_error(conn,perfor_or_infor,save_as): 291 | title = "Log file Statistics" 292 | style = {1: 'start & shutdown:,l'} 293 | rows =[] 294 | WarnLog = 0 295 | ErrLog = 0 296 | query = "SELECT variable_value FROM " + perfor_or_infor + ".global_variables where variable_name ='log_error'" 297 | filename = f_get_query_value(conn, query) 298 | if os.path.exists(filename): 299 | with open(filename, 'r') as f: 300 | for line in f: 301 | if ('ready for connections' in line or 'Shutdown completed' in line): 302 | rows.append([line]) 303 | if ('Warning' in line): 304 | WarnLog += 1 305 | if ('error' in line): 306 | ErrLog += 1 307 | else: 308 | rows.append([filename + " not exists"]) 309 | 310 | rows.append(['Warning & Error Statistics:']) 311 | rows.append([filename + ' contains ' + str(WarnLog) + ' warning(s).']) 312 | rows.append([filename + ' contains ' + str(ErrLog) + ' error(s).']) 313 | f_print_table(rows, title, style,save_as) 314 | 315 | def f_print_caption(dbinfo,mysql_version,save_as): 316 | if save_as == "txt": 317 | print (tab2 * linesize) 318 | print (tab2, 'MySQL Watcher V1.3.0'.center(linesize - 4), tab2) 319 | print (tab2, 'Kinghow@hotmail.com'.center(linesize - 4), tab2) 320 | print (tab2, 'https://github.com/kinghows/MySQL_Watcher'.center(linesize - 4), tab2) 321 | print (tab2 * linesize) 322 | elif save_as == "html": 323 | print (""" 324 | MySQL Watcher V1.2.0 Kinghow@hotmail.com https://github.com/kinghows/MySQL_Watcher 325 | 353 |

354 | WORKLOAD REPOSITORY report for 355 |

356 | """) 357 | 358 | title = "Basic Information" 359 | style = {1: 'host,c', 2: 'user,c', 3: 'db,c', 4: 'mysql version,c'} 360 | rows = [[dbinfo[0], dbinfo[1], dbinfo[3], mysql_version]] 361 | f_print_table(rows, title, style,save_as) 362 | 363 | def f_print_ending(save_as): 364 | if save_as == "txt": 365 | f_print_title('--@-- End --@--') 366 | elif save_as == "html": 367 | print (""" 368 |

369 | End of Report 370 | 371 | """) 372 | 373 | def size(device): 374 | nr_sectors = open(device+'/size').read().rstrip('\n') 375 | sect_size = open(device+'/queue/hw_sector_size').read().rstrip('\n') 376 | return (float(nr_sectors)*float(sect_size))/(1024.0*1024.0*1024.0) 377 | 378 | def f_print_linux_info(save_as): 379 | title = "Linux info" 380 | style = {1: 'Linux,l',2: 'Info,l'} 381 | rows =[] 382 | #version 383 | rows.append(["Version",platform.uname()[0]+' '+platform.uname()[2]+' '+platform.uname()[4]]) 384 | #cpu 385 | cpu_count = 0 386 | with open('/proc/cpuinfo') as f: 387 | for line in f: 388 | if line.strip(): 389 | if line.rstrip('\n').startswith('model name'): 390 | model_name = line.rstrip('\n').split(':')[1] 391 | cpu_count +=1 392 | rows.append(["CPU",model_name + ' X '+str(cpu_count)]) 393 | #mem 394 | meminfo = OrderedDict() 395 | with open('/proc/meminfo') as f: 396 | for line in f: 397 | meminfo[line.split(':')[0]] = line.split(':')[1].strip() 398 | rows.append(["Memory",'Total: {0}'.format(meminfo['MemTotal'])+' Free: {0}'.format(meminfo['MemFree'])]) 399 | #net 400 | with open('/proc/net/dev') as f: 401 | net_dump = f.readlines() 402 | device_data = {} 403 | data = namedtuple('data', ['rx', 'tx']) 404 | for line in net_dump[2:]: 405 | line = line.split(':') 406 | if line[0].strip() != 'lo': 407 | device_data[line[0].strip()] = data(float(line[1].split()[0]) / (1024.0 * 1024.0), 408 | float(line[1].split()[8]) / (1024.0 * 1024.0)) 409 | for dev in device_data.keys(): 410 | rows.append(["Net",'{0}: {1} MiB {2} MiB'.format(dev, device_data[dev].rx, device_data[dev].tx)]) 411 | #Device 412 | dev_pattern = ['sd.*', 'mmcblk*'] 413 | for device in glob.glob('/sys/block/*'): 414 | for pattern in dev_pattern: 415 | if re.compile(pattern).match(os.path.basename(device)): 416 | rows.append(["Device",'{0}, Size: {1} GiB'.format(device, size(device))]) 417 | #process 418 | pids = [] 419 | for subdir in os.listdir('/proc'): 420 | if subdir.isdigit(): 421 | pids.append(subdir) 422 | rows.append(["Processes",'Total number of running : {0}'.format(len(pids))]) 423 | 424 | f_print_table(rows, title, style,save_as) 425 | 426 | def f_print_filesystem_info(save_as): 427 | title = "Filesystem info" 428 | style = {1: 'Filesystem,l',2: 'Size,r',3: 'Used,r',4: 'Avail,r',5: 'Use %,r',6: ' Mounted on,l'} 429 | rows =[] 430 | file_info = [] 431 | j = 0 432 | for line in os.popen('df -h').readlines(): 433 | for eachList in line.strip().split(): 434 | file_info.append(eachList) 435 | j +=1 436 | i = 6 437 | while i= topN: 492 | break 493 | rows.append([i + 1, item['name'], item['pid'], format(item['memory_percent'] / 100, '.2%')]) 494 | 495 | style = {1: 'No,r', 2: 'Name,l',3: 'Pid,r', 4: 'Memory percent,r'} 496 | title = "Host memory top"+str(topN) 497 | f_print_table(rows, title, style, save_as) 498 | 499 | def f_sec2dhms(sec): 500 | day = 24*60*60 501 | hour = 60*60 502 | min = 60 503 | if sec <60: 504 | return "%ds"%math.ceil(sec) 505 | elif sec > day: 506 | days = divmod(sec,day) 507 | return "%dd%s"%(int(days[0]),f_sec2dhms(days[1])) 508 | elif sec > hour: 509 | hours = divmod(sec,hour) 510 | return '%dh%s'%(int(hours[0]),f_sec2dhms(hours[1])) 511 | else: 512 | mins = divmod(sec,min) 513 | return "%dm%ds"%(int(mins[0]),math.ceil(mins[1])) 514 | 515 | def f_get_mysql_status(conn): 516 | query = "SHOW GLOBAL STATUS" 517 | rows = f_get_query_record(conn, query) 518 | mysqlstatus = dict(rows) 519 | return mysqlstatus 520 | 521 | def f_print_mysql_status(conn,perfor_or_infor,interval,save_as): 522 | ###获取参数################################################################### 523 | mysqlstatus1 = f_get_mysql_status(conn) 524 | time.sleep(interval) 525 | mysqlstatus2 = f_get_mysql_status(conn) 526 | 527 | # 执行查询的总次数 528 | Questions1 = int(mysqlstatus1["Questions"]) 529 | Questions2 = int(mysqlstatus2["Questions"]) 530 | # 服务器已经运行的时间(以秒为单位) 531 | Uptime2 = int(mysqlstatus2["Uptime"]) 532 | Com_commit1 = int(mysqlstatus1["Com_commit"]) 533 | Com_commit2 = int(mysqlstatus2["Com_commit"]) 534 | Com_rollback1 = int(mysqlstatus1["Com_rollback"]) 535 | Com_rollback2 = int(mysqlstatus2["Com_rollback"]) 536 | # 从硬盘读取键的数据块的次数。如果Key_reads较大,则Key_buffer_size值可能太小。 537 | # 可以用Key_reads/Key_read_requests计算缓存损失率 538 | #Key_reads1 = int(mysqlstatus1["Key_reads"]) 539 | #Key_reads2 = int(mysqlstatus2["Key_reads"]) 540 | # 从缓存读键的数据块的请求数 541 | #Key_read_requests1 = int(mysqlstatus1["Key_read_requests"]) 542 | #Key_read_requests2 = int(mysqlstatus2["Key_read_requests"]) 543 | # 向硬盘写入将键的数据块的物理写操作的次数 544 | #Key_writes1 = int(mysqlstatus1["Key_writes"]) 545 | #Key_writes2 = int(mysqlstatus2["Key_writes"]) 546 | # 将键的数据块写入缓存的请求数 547 | #Key_write_requests1 = int(mysqlstatus1["Key_write_requests"]) 548 | #Key_write_requests2 = int(mysqlstatus2["Key_write_requests"]) 549 | # 不能满足InnoDB必须单页读取的缓冲池中的逻辑读数量。 550 | Innodb_buffer_pool_reads1 = int(mysqlstatus1["Innodb_buffer_pool_reads"]) 551 | Innodb_buffer_pool_reads2 = int(mysqlstatus2["Innodb_buffer_pool_reads"]) 552 | # InnoDB已经完成的逻辑读请求数 553 | Innodb_buffer_pool_read_requests1 = int(mysqlstatus1["Innodb_buffer_pool_read_requests"]) 554 | Innodb_buffer_pool_read_requests2 = int(mysqlstatus2["Innodb_buffer_pool_read_requests"]) 555 | 556 | # 当前打开的表的数量 557 | Open_tables1 = int(mysqlstatus2["Open_tables"])-int(mysqlstatus1["Open_tables"]) 558 | Open_tables2 = int(mysqlstatus2["Open_tables"]) 559 | # 已经打开的表的数量。如果Opened_tables较大,table_cache 值可能太小 560 | Opened_tables1 = int(mysqlstatus2["Opened_tables"])-int(mysqlstatus1["Opened_tables"]) 561 | Opened_tables2 = int(mysqlstatus2["Opened_tables"]) 562 | # 创建用来处理连接的线程数。如果Threads_created较大,你可能要 563 | # 增加thread_cache_size值。缓存访问率的计算方法Threads_created/Connections 564 | Threads_created1 = int(mysqlstatus1["Threads_created"]) 565 | Threads_created2 = int(mysqlstatus2["Threads_created"]) 566 | # 试图连接到(不管是否成功)MySQL服务器的连接数。缓存访问率的计算方法Threads_created/Connections 567 | Connections1 = int(mysqlstatus1["Connections"]) 568 | Connections2 = int(mysqlstatus2["Connections"]) 569 | Threads_connected1 = str(int(mysqlstatus2["Threads_connected"])-int(mysqlstatus1["Threads_connected"])) 570 | Threads_connected2 = mysqlstatus2["Threads_connected"] 571 | Aborted_connects1 = str(int(mysqlstatus2["Aborted_connects"])-int(mysqlstatus1["Aborted_connects"])) 572 | Aborted_connects2 = mysqlstatus2["Aborted_connects"] 573 | # Com_select/s:平均每秒select语句执行次数 574 | # Com_insert/s:平均每秒insert语句执行次数 575 | # Com_update/s:平均每秒update语句执行次数 576 | # Com_delete/s:平均每秒delete语句执行次数 577 | Com_select1 = int(mysqlstatus1["Com_select"]) 578 | Com_select2 = int(mysqlstatus2["Com_select"]) 579 | Com_insert1 = int(mysqlstatus1["Com_insert"]) 580 | Com_insert2 = int(mysqlstatus2["Com_insert"]) 581 | Com_update1 = int(mysqlstatus1["Com_update"]) 582 | Com_update2 = int(mysqlstatus2["Com_update"]) 583 | Com_delete1 = int(mysqlstatus1["Com_delete"]) 584 | Com_delete2 = int(mysqlstatus2["Com_delete"]) 585 | Com_replace1 = int(mysqlstatus1["Com_replace"]) 586 | Com_replace2 = int(mysqlstatus2["Com_replace"]) 587 | # 不能立即获得的表的锁的次数。如果该值较高,并且有性能问题,你应首先优化查询,然后拆分表或使用复制。 588 | #Table_locks_waited1 = int(mysqlstatus1["Table_locks_waited"]) 589 | #Table_locks_waited2 = int(mysqlstatus2["Table_locks_waited"]) 590 | # 立即获得的表的锁的次数 591 | #Table_locks_immediate1 = int(mysqlstatus1["Table_locks_immediate"]) 592 | #Table_locks_immediate2 = int(mysqlstatus2["Table_locks_immediate"]) 593 | # 服务器执行语句时自动创建的内存中的临时表的数量。如果Created_tmp_disk_tables较大, 594 | # 你可能要增加tmp_table_size值使临时 表基于内存而不基于硬盘 595 | Created_tmp_tables1 = int(mysqlstatus1["Created_tmp_tables"]) 596 | Created_tmp_tables2 = int(mysqlstatus2["Created_tmp_tables"]) 597 | # 服务器执行语句时在硬盘上自动创建的临时表的数量 598 | Created_tmp_disk_tables1 = int(mysqlstatus1["Created_tmp_disk_tables"]) 599 | Created_tmp_disk_tables2 = int(mysqlstatus2["Created_tmp_disk_tables"]) 600 | # 查询时间超过long_query_time秒的查询的个数 缓慢查询个数 601 | Slow_queries1 = int(mysqlstatus1["Slow_queries"]) 602 | Slow_queries2 = int(mysqlstatus2["Slow_queries"]) 603 | # 没有主键(key)联合(Join)的执行。该值可能是零。这是捕获开发错误的好方法,因为一些这样的查询可能降低系统的性能。 604 | Select_full_join1 = int(mysqlstatus1["Select_full_join"]) 605 | Select_full_join2 = int(mysqlstatus2["Select_full_join"]) 606 | # Percentage of full table scans 607 | Handler_read_rnd_next1 = int(mysqlstatus1["Handler_read_rnd_next"]) 608 | Handler_read_rnd_next2 = int(mysqlstatus2["Handler_read_rnd_next"]) 609 | Handler_read_rnd1 = int(mysqlstatus1["Handler_read_rnd"]) 610 | Handler_read_rnd2 = int(mysqlstatus2["Handler_read_rnd"]) 611 | Handler_read_first1 = int(mysqlstatus1["Handler_read_first"]) 612 | Handler_read_first2 = int(mysqlstatus2["Handler_read_first"]) 613 | Handler_read_next1 = int(mysqlstatus1["Handler_read_next"]) 614 | Handler_read_next2 = int(mysqlstatus2["Handler_read_next"]) 615 | Handler_read_key1 = int(mysqlstatus1["Handler_read_key"]) 616 | Handler_read_key2 = int(mysqlstatus2["Handler_read_key"]) 617 | Handler_read_prev1 = int(mysqlstatus1["Handler_read_prev"]) 618 | Handler_read_prev2 = int(mysqlstatus2["Handler_read_prev"]) 619 | # 缓冲池利用率 620 | Innodb_buffer_pool_pages_total1 = int(mysqlstatus1["Innodb_buffer_pool_pages_total"]) 621 | Innodb_buffer_pool_pages_total2 = int(mysqlstatus2["Innodb_buffer_pool_pages_total"]) 622 | Innodb_buffer_pool_pages_free1 = int(mysqlstatus1["Innodb_buffer_pool_pages_free"]) 623 | Innodb_buffer_pool_pages_free2 = int(mysqlstatus2["Innodb_buffer_pool_pages_free"]) 624 | 625 | ###计算参数################################################################### 626 | Uptimes1 = str(interval) + "s" 627 | Uptimes2 = f_sec2dhms(Uptime2) 628 | # QPS = Questions / Seconds 629 | QPS1 = str(round((Questions2-Questions1) * 1.0 / interval, 2))+' ('+str(Questions2-Questions1)+'/'+str(interval)+')' 630 | QPS2 = str(round(Questions2* 1.0 / Uptime2, 2))+' ('+str(Questions2)+'/'+str(Uptime2)+')' 631 | 632 | TPS1 = str(round((Com_commit2 + Com_rollback2-Com_commit1 - Com_rollback1) * 1.0 / interval, 2))+' (('+str(Com_commit2 -Com_commit1)+'+'+str(Com_rollback2- Com_rollback1)+')/'+str(interval)+')' 633 | TPS2 = str(round((Com_commit2 + Com_rollback2)* 1.0 / Uptime2, 2))+' (('+str(Com_commit2)+'+'+str(Com_rollback2)+')/'+str(Uptime2)+')' 634 | 635 | Read1 = Com_select2 -Com_select1 636 | Read2 = Com_select2 637 | ReadS1 = str(round(Read1 * 1.0 / interval, 2))+' ('+str(Read1)+'/'+str(interval)+')' 638 | ReadS2 = str(round(Read2* 1.0 / Uptime2, 2))+' ('+str(Read2)+'/'+str(Uptime2)+')' 639 | 640 | Write1 = Com_insert2 + Com_update2 + Com_delete2 + Com_replace2-Com_insert1 - Com_update1 - Com_delete1 - Com_replace1 641 | Write2 = Com_insert2 + Com_update2 + Com_delete2 + Com_replace2 642 | WriteS1 = str(round(Write1 * 1.0 / interval, 2))+' ('+str(Write1)+'/'+str(interval)+')' 643 | WriteS2 = str(round(Write2* 1.0 / Uptime2, 2))+' ('+str(Write2)+'/'+str(Uptime2)+')' 644 | # Read/Write Ratio 645 | if Write1!=0: 646 | rwr1 = str(round(Read1 * 1.0 / Write1,2))+' ('+str(Read1)+'/'+str(Write1)+')' 647 | else: 648 | rwr1 ='0.0%' 649 | 650 | if Write2!=0: 651 | rwr2 = str(round(Read2 * 1.0 / Write2,2))+' ('+str(Read2)+'/'+str(Write2)+')' 652 | else: 653 | rwr2 ='0.0%' 654 | 655 | Slow_queries_per_second1 = str(round((Slow_queries2-Slow_queries1) * 1.0 / interval, 2))+' ('+str(Slow_queries2-Slow_queries1)+'/'+str(interval)+')' 656 | Slow_queries_per_second2 = str(round(Slow_queries2 * 1.0 / Uptime2, 2))+' ('+str(Slow_queries2)+'/'+str(Uptime2)+')' 657 | #Slow_queries / Questions 658 | SQ1 = str(round(((Slow_queries2-Slow_queries1) * 1.0 / (Questions2-Questions1)) * 100, 2)) + "%"+' ('+str(Slow_queries2-Slow_queries1)+'/'+str(Questions2-Questions1)+')' 659 | SQ2 = str(round((Slow_queries2 * 1.0 / Questions2) * 100, 2)) + "%"+' ('+str(Slow_queries2)+'/'+str(Questions2)+')' 660 | 661 | if (Connections2-Connections1) != 0: 662 | Thread_cache_hits1 = str(round((1 - (Threads_created2-Threads_created1)* 1.0 / (Connections2-Connections1)) * 100, 2)) + "%" 663 | else: 664 | Thread_cache_hits1 = '0.0%' 665 | Thread_cache_hits2 = str(round((1 - Threads_created2 * 1.0 / Connections2) * 100, 2)) + "%" 666 | 667 | if (Innodb_buffer_pool_read_requests2-Innodb_buffer_pool_read_requests1) != 0: 668 | Innodb_buffer_read_hits1 = str(round((1 - (Innodb_buffer_pool_reads2-Innodb_buffer_pool_reads1) * 1.0 / (Innodb_buffer_pool_read_requests2-Innodb_buffer_pool_read_requests1)) * 100, 2)) + "%"+ "%"+' (1-'+str(Innodb_buffer_pool_reads2-Innodb_buffer_pool_reads1)+'/'+str(Innodb_buffer_pool_read_requests2-Innodb_buffer_pool_read_requests1)+')' 669 | else: 670 | Innodb_buffer_read_hits1 = '0.0%' 671 | Innodb_buffer_read_hits2 = str(round((1 - Innodb_buffer_pool_reads2* 1.0 / Innodb_buffer_pool_read_requests2) * 100, 2)) + "%"+' (1-'+str(Innodb_buffer_pool_reads2)+'/'+str(Innodb_buffer_pool_read_requests2)+')' 672 | 673 | Innodb_buffer_pool_utilization1 = str(round((Innodb_buffer_pool_pages_total1 - Innodb_buffer_pool_pages_free1) * 1.0 / Innodb_buffer_pool_pages_total1 * 100,2)) + "%"+' ('+str(Innodb_buffer_pool_pages_total1 - Innodb_buffer_pool_pages_free1)+'/'+str(Innodb_buffer_pool_pages_total1)+')' 674 | Innodb_buffer_pool_utilization2 = str(round((Innodb_buffer_pool_pages_total2 - Innodb_buffer_pool_pages_free2) * 1.0 / Innodb_buffer_pool_pages_total2 * 100,2)) + "%"+' ('+str(Innodb_buffer_pool_pages_total2 - Innodb_buffer_pool_pages_free2)+'/'+str(Innodb_buffer_pool_pages_total2)+')' 675 | 676 | """ 677 | if (Key_read_requests2-Key_read_requests1) != 0: 678 | Key_buffer_read_hits1 = str(round((1 - (Key_reads2-Key_reads1) * 1.0 / (Key_read_requests2-Key_read_requests1)) * 100, 2)) + "%" 679 | else: 680 | Key_buffer_read_hits1 = '0.0%' 681 | if Key_read_requests2 != 0: 682 | Key_buffer_read_hits2 = str(round((1 - Key_reads2* 1.0 / Key_read_requests2) * 100, 2)) + "%" 683 | else: 684 | Key_buffer_read_hits2 = '0.0%' 685 | 686 | if (Key_write_requests2-Key_write_requests1)!=0: 687 | Key_buffer_write_hits1 = str(round((1 - (Key_writes2-Key_writes1)* 1.0 / (Key_write_requests2-Key_write_requests1)) * 100, 2)) + "%" 688 | else: 689 | Key_buffer_write_hits1 = '0.0%' 690 | if Key_write_requests2!=0: 691 | Key_buffer_write_hits2 = str(round((1 - Key_writes2* 1.0 / Key_write_requests2) * 100, 2)) + "%" 692 | else: 693 | Key_buffer_write_hits2 = '0.0%' 694 | """ 695 | if (Select_full_join2-Select_full_join1) > 0: 696 | Select_full_join_per_second1 = str(round((Select_full_join2-Select_full_join1) * 1.0 / interval, 2))+' ('+str(Select_full_join2-Select_full_join1)+'/'+str(interval)+')' 697 | else: 698 | Select_full_join_per_second1 = '0.0%' 699 | Select_full_join_per_second2 = str(round(Select_full_join2 * 1.0 / Uptime2, 2))+' ('+str(Select_full_join2)+'/'+str(Uptime2)+')' 700 | 701 | if (Com_select2-Com_select1) > 0: 702 | full_select_in_all_select1 = str(round(((Select_full_join2-Select_full_join1) * 1.0 / (Com_select2-Com_select1)) * 100, 2)) + "%"+' ('+str(Select_full_join2-Select_full_join1)+'/'+str(Com_select2-Com_select1)+')' 703 | else: 704 | full_select_in_all_select1 = '0.0%' 705 | full_select_in_all_select2 = str(round((Select_full_join2 * 1.0 / Com_select2) * 100, 2)) + "%"+' ('+str(Select_full_join2)+'/'+str(Com_select2)+')' 706 | 707 | #((Handler_read_rnd_next + Handler_read_rnd) / (Handler_read_rnd_next + Handler_read_rnd + Handler_read_first + Handler_read_next + Handler_read_key + Handler_read_prev)). 708 | if (Handler_read_rnd_next2 -Handler_read_rnd_next1+ Handler_read_rnd2-Handler_read_rnd1 + Handler_read_first2 -Handler_read_first1+ Handler_read_next2-Handler_read_next1 + Handler_read_key2-Handler_read_key1 + Handler_read_prev2-Handler_read_prev1) > 0: 709 | full_table_scans1=str(round((Handler_read_rnd_next2 + Handler_read_rnd2-Handler_read_rnd_next1 - Handler_read_rnd1)* 1.0 / (Handler_read_rnd_next2 -Handler_read_rnd_next1+ Handler_read_rnd2-Handler_read_rnd1 + Handler_read_first2 -Handler_read_first1+ Handler_read_next2-Handler_read_next1 + Handler_read_key2-Handler_read_key2 + Handler_read_prev2-Handler_read_prev1)* 100, 2)) + "%" 710 | else: 711 | full_table_scans1 = '0.0%' 712 | full_table_scans2=str(round((Handler_read_rnd_next2 + Handler_read_rnd2)* 1.0 / (Handler_read_rnd_next2 + Handler_read_rnd2 + Handler_read_first2 + Handler_read_next2 + Handler_read_key2 + Handler_read_prev2)* 100, 2)) + "%" 713 | """ 714 | if (Table_locks_immediate2-Table_locks_immediate1) > 0: 715 | lock_contention1 = str(round(((Table_locks_waited2-Table_locks_waited1) * 1.00 / (Table_locks_immediate2-Table_locks_immediate1)) * 100, 2)) + "%" 716 | else: 717 | lock_contention1 = '0.0%' 718 | lock_contention2 = str(round((Table_locks_waited2 * 1.00 / Table_locks_immediate2) * 100, 2)) + "%" 719 | """ 720 | if (Created_tmp_tables2-Created_tmp_tables1) > 0: 721 | Temp_tables_to_disk1 = str(round(((Created_tmp_disk_tables2-Created_tmp_disk_tables1) * 1.0 / (Created_tmp_tables2-Created_tmp_tables1)) * 100, 2)) + "%"+' ('+str(Created_tmp_disk_tables2-Created_tmp_disk_tables1)+'/'+str(Created_tmp_tables2-Created_tmp_tables1)+')' 722 | else: 723 | Temp_tables_to_disk1 = '0.0%' 724 | Temp_tables_to_disk2 = str(round((Created_tmp_disk_tables2 * 1.0 / Created_tmp_tables2) * 100, 2)) + "%"+' ('+str(Created_tmp_disk_tables2)+'/'+str(Created_tmp_tables2)+')' 725 | 726 | ###打印参数################################################################### 727 | title = "MySQL Overview" 728 | style = {1: 'Key,l', 2: 'In '+Uptimes1+',r', 3: 'Total,r'} 729 | rows=[ 730 | ["Uptimes",Uptimes1,Uptimes2], 731 | ["QPS (Questions / Seconds)", QPS1, QPS2], 732 | ["TPS ((Commit + Rollback)/ Seconds)", TPS1, TPS2], 733 | ["Reads per second", ReadS1, ReadS2], 734 | ["Writes per second", WriteS1, WriteS2], 735 | ["Read/Writes", rwr1,rwr2], 736 | ["Slow queries per second", Slow_queries_per_second1, Slow_queries_per_second2], 737 | ["Slow_queries/Questions", SQ1,SQ2], 738 | ["Threads connected", Threads_connected1, Threads_connected2], 739 | ["Aborted connects", Aborted_connects1, Aborted_connects2], 740 | ["Thread cache hits (>90%)", Thread_cache_hits1, Thread_cache_hits2], 741 | ["Innodb buffer hits(96% - 99%)", Innodb_buffer_read_hits1,Innodb_buffer_read_hits2], 742 | ["Innodb buffer pool utilization", Innodb_buffer_pool_utilization1,Innodb_buffer_pool_utilization2], 743 | #["Key buffer read hits(99.3% - 99.9%)",str(Key_buffer_read_hits1), str(Key_buffer_read_hits2)], 744 | #["Key buffer write hits(99.3% - 99.9%)", str(Key_buffer_write_hits1), str(Key_buffer_write_hits2)], 745 | ["Select full join per second", Select_full_join_per_second1, Select_full_join_per_second2], 746 | ["full select in all select", full_select_in_all_select1, full_select_in_all_select2], 747 | ["full table scans", full_table_scans1, full_table_scans2], 748 | #["MyISAM Lock waiting ratio", lock_contention1, lock_contention2], 749 | ["Current open tables", str(Open_tables1), str(Open_tables2)], 750 | ["Accumulative open tables", str(Opened_tables1), str(Opened_tables2)], 751 | ["Temp tables to disk(<10%)", Temp_tables_to_disk1, Temp_tables_to_disk2] 752 | ] 753 | 754 | f_print_table(rows, title, style,save_as) 755 | 756 | if __name__=="__main__": 757 | dbinfo=["127.0.0.1","root","","mysql",3306] #host,user,passwd,db,port 758 | config_file="dbset.ini" 759 | mysql_version="" 760 | option = [] 761 | save_as = "txt" 762 | 763 | opts, args = getopt.getopt(sys.argv[1:], "p:s:") 764 | for o,v in opts: 765 | if o == "-p": 766 | config_file = v 767 | elif o == "-s": 768 | save_as = v 769 | 770 | config = configparser.ConfigParser() 771 | config.read(config_file) 772 | dbinfo[0] = config.get("database","host") 773 | dbinfo[1] = config.get("database","user") 774 | dbinfo[2] = config.get("database","passwd") 775 | dbinfo[3] = config.get("database","db") 776 | dbinfo[4] = config.get("database", "port") 777 | interval = int(config.get("option", "interval")) 778 | 779 | conn = f_get_conn(dbinfo) 780 | query ="select @@version" 781 | mysql_version = f_get_query_value(conn, query) 782 | f_print_caption(dbinfo,mysql_version,save_as) 783 | 784 | if "5.6" in mysql_version: 785 | perfor_or_infor = "information_schema" 786 | else: 787 | perfor_or_infor = "performance_schema" 788 | 789 | sys_schema_exist = f_is_sys_schema_exist(conn) 790 | 791 | if config.get("option","linux_info")=='ON': 792 | f_print_linux_info(save_as) 793 | 794 | if config.get("option","filesystem_info")=='ON': 795 | f_print_filesystem_info(save_as) 796 | 797 | if config.get("option","linux_overview")=='ON': 798 | f_print_linux_status(save_as) 799 | 800 | if config.get("option","host_memory_topN")!='OFF': 801 | topN=int(config.get("option","host_memory_topN")) 802 | f_print_host_memory_topN(topN,save_as) 803 | 804 | if config.get("option","mysql_overview")=='ON': 805 | f_print_mysql_status(conn,perfor_or_infor,interval,save_as) 806 | 807 | if config.get("option","sys_parm")=='ON': 808 | title = "System Parameter " 809 | query = "SELECT variable_name,IF(INSTR(variable_name,'size'), \ 810 | CASE \ 811 | WHEN variable_value>=1024*1024*1024*1024*1024 THEN CONCAT(variable_value/1024/1024/1024/1024/1024,'P') \ 812 | WHEN variable_value>=1024*1024*1024*1024 THEN CONCAT(variable_value/1024/1024/1024/1024,'T') \ 813 | WHEN variable_value>=1024*1024*1024 THEN CONCAT(variable_value/1024/1024/1024,'G') \ 814 | WHEN variable_value>=1024*1024 THEN CONCAT(variable_value/1024/1024,'M') \ 815 | WHEN variable_value>=1024 THEN CONCAT(variable_value/1024,'K') \ 816 | ELSE variable_value END , \ 817 | variable_value) \ 818 | FROM "+perfor_or_infor+".global_variables \ 819 | where variable_name in ('" + "','".join(list(SYS_PARM_FILTER)) + "')" 820 | style = {1: 'parameter_name,l', 2: 'value,r'} 821 | f_print_query_table(conn, title, query, style,save_as) 822 | f_print_optimizer_switch(conn,save_as,perfor_or_infor) 823 | 824 | if config.get("option","log_error_statistics")=='ON': 825 | f_print_log_error(conn,perfor_or_infor,save_as) 826 | 827 | if config.get ( "option", "replication" ) == 'ON': 828 | title = "Replication" 829 | query = """SELECT USER,HOST,command,CONCAT(FLOOR(TIME/86400),'d',FLOOR(TIME/3600)%24,'h',FLOOR(TIME/60)%60,'m',TIME%60,'s') TIMES,state 830 | FROM information_schema.processlist WHERE COMMAND = 'Binlog Dump' OR COMMAND = 'Binlog Dump GTID'""" 831 | style = {1: 'USER,l', 2: 'HOST,l', 3: 'command,l', 4: 'TIMES,r', 5: 'state,r'} 832 | f_print_query_table(conn, title, query, style,save_as) 833 | 834 | if config.get ( "option", "connect_count" ) == 'ON': 835 | title = "Connect Count" 836 | query = """SELECT SUBSTRING_INDEX(HOST,':',1) HOSTS,USER,db,command,COUNT(*),SUM(TIME) 837 | FROM information_schema.processlist 838 | WHERE Command !='' AND DB !='information_schema' 839 | GROUP BY HOSTS,USER,db,command""" 840 | style = {1: 'HOSTS,l', 2: 'USER,l', 3: 'db,l', 4: 'command,l', 5: 'COUNT(*),r', 6: 'SUM(TIME),r'} 841 | f_print_query_table(conn, title, query, style,save_as) 842 | 843 | if config.get ( "option", "avg_query_time" ) == 'ON' and not ("5.6" in mysql_version): 844 | title = "Avg Query Time" 845 | query = """SELECT schema_name,SUM(count_star) COUNT, ROUND((SUM(sum_timer_wait)/SUM(count_star))/1000000) avg_microsec 846 | FROM performance_schema.events_statements_summary_by_digest 847 | WHERE schema_name IS NOT NULL 848 | GROUP BY schema_name""" 849 | style = {1: 'schema_name,l', 2: 'COUNT,r', 3: 'avg_microsec,r'} 850 | f_print_query_table(conn, title, query, style,save_as) 851 | 852 | if config.get ( "option", "slow_query_topN" ) != 'OFF' and sys_schema_exist: 853 | topN = int(config.get("option", "slow_query_topN")) 854 | title = "Slow Query Top"+str(topN) 855 | query = "SELECT QUERY,db,exec_count,total_latency,max_latency,avg_latency FROM sys.statements_with_runtimes_in_95th_percentile LIMIT "+str(topN) 856 | style = {1: 'QUERY,l', 2: 'db,r', 3: 'exec_count,r', 4: 'total_latency,r', 5: 'max_latency,r', 6: 'avg_latency,r'} 857 | f_print_query_table(conn, title, query, style,save_as) 858 | 859 | if config.get ( "option", "err_sql_count" ) == 'ON' and ("5.7" in mysql_version): 860 | title = "Err Sql Count" 861 | query = """SELECT schema_name,SUM(sum_errors) err_count 862 | FROM performance_schema.events_statements_summary_by_digest 863 | WHERE sum_errors > 0 864 | GROUP BY schema_name""" 865 | style = {1: 'schema_name,l', 2: 'err_count,r'} 866 | f_print_query_table(conn, title, query, style,save_as) 867 | 868 | if config.get ( "option", "err_sql_topN" ) != 'OFF' and sys_schema_exist: 869 | topN = int(config.get("option", "err_sql_topN")) 870 | title = "Err SQL Top"+str(topN) 871 | query = "SELECT QUERY,db,exec_count,ERRORS FROM sys.statements_with_errors_or_warnings ORDER BY ERRORS DESC LIMIT "+str(topN) 872 | style = {1: 'QUERY,l', 2: 'db,r', 3: 'exec_count,r', 4: 'ERRORS,r'} 873 | f_print_query_table(conn, title, query, style,save_as) 874 | 875 | if config.get ( "option", "query_analysis_topN" ) != 'OFF' and sys_schema_exist: 876 | topN = int(config.get("option", "query_analysis_topN")) 877 | title = "query analysis top"+str(topN) 878 | query = """SELECT QUERY,full_scan,exec_count,total_latency,lock_latency,rows_sent_avg,rows_examined_avg, 879 | tmp_tables,tmp_disk_tables,rows_sorted,last_seen 880 | FROM sys.statement_analysis 881 | where db='""" + dbinfo[3] + "' ORDER BY total_latency DESC LIMIT "+str(topN) 882 | style = {1: 'QUERY,l', 2: 'fscan,l', 3: 'ex_cot,r', 4: 'total_ltc,r', 5:'lock_ltc,r', 6: 'rw_st_avg,r', 883 | 7: 'rw_exm_avg,9,r',8: 'tmp_table,9,r',9: 'tp_dk_tab,9,r',10: 'rows_sort,9,r',11: 'last_seen,19,r'} 884 | f_print_query_table(conn, title, query, style,save_as) 885 | 886 | if config.get ( "option", "query_full_table_scans_topN" ) != 'OFF' and sys_schema_exist: 887 | topN = int(config.get("option", "query_full_table_scans_topN")) 888 | title = "query full table scans top"+str(topN) 889 | query = """SELECT QUERY,exec_count,total_latency,no_index_used_count,no_good_index_used_count,no_index_used_pct,rows_sent_avg,rows_examined_avg,last_seen 890 | FROM sys.statements_with_full_table_scans 891 | where db='""" + dbinfo[3] + "' ORDER BY total_latency DESC LIMIT "+str(topN) 892 | style = {1: 'QUERY,l', 2: 'ex_cot,r', 3: 'total_ltc,r', 4:'no_idx_use,r', 5: 'n_g_idx_use,r',6: 'n_i_u_pct,r', 893 | 7: 'rw_st_avg,r',8: 'rw_exm_avg,r',9: 'last_seen,r'} 894 | f_print_query_table(conn, title, query, style,save_as) 895 | 896 | if config.get ( "option", "query_sorting_topN" ) != 'OFF' and sys_schema_exist: 897 | topN = int(config.get("option", "query_sorting_topN")) 898 | title = "query sorting top"+str(topN) 899 | query = """SELECT QUERY,exec_count,total_latency,sort_merge_passes,avg_sort_merges,sorts_using_scans,sort_using_range, 900 | rows_sorted,avg_rows_sorted,last_seen 901 | FROM sys.statements_with_sorting 902 | where db='""" + dbinfo[3] + "' ORDER BY avg_rows_sorted DESC LIMIT "+str(topN) 903 | style = {1: 'QUERY,l', 2: 'ex_cot,r', 3: 'total_ltc,r', 4:'st_mg_ps,r', 5: 'avg_st_mg,r',6: 'st_us_scan,r', 904 | 7: 'st_us_rag,r',8: 'rows_sort,r',9: 'avg_rw_st,r',10: 'last_seen,r'} 905 | f_print_query_table(conn, title, query, style,save_as) 906 | 907 | if config.get ( "option", "query_with_temp_tables_topN" ) != 'OFF' and sys_schema_exist: 908 | topN = int(config.get("option", "query_with_temp_tables_topN")) 909 | title = "query with temp tables top"+str(topN) 910 | query = """SELECT QUERY,exec_count,total_latency,memory_tmp_tables,disk_tmp_tables,avg_tmp_tables_per_query,tmp_tables_to_disk_pct,last_seen 911 | FROM sys.statements_with_temp_tables 912 | where db='""" + dbinfo[3] + "' ORDER BY avg_tmp_tables_per_query DESC LIMIT "+str(topN) 913 | style = {1: 'QUERY,l', 2: 'ex_cot,r', 3: 'total_ltc,r', 4:'mem_tmp_tab,r', 5: 'dsk_tmp_tab,r',6: 'avg_tt_per_qry,r', 914 | 7: 'tt_to_dk_pct,r',8:'last_seen,r'} 915 | f_print_query_table(conn, title, query, style,save_as) 916 | 917 | if config.get ( "option", "database_size" ) == 'ON': 918 | title = "Database Size" 919 | query = """SELECT table_schema, 920 | CONCAT(ROUND(SUM(data_length)/(1024*1024),2),'MB') AS 'Table Size', 921 | CONCAT(ROUND(SUM(index_length)/(1024*1024),2),'MB') AS 'Index Size' , 922 | CONCAT(ROUND(SUM(data_length)/(1024*1024),2) + ROUND(SUM(index_length)/(1024*1024),2),'MB') AS 'DB Size' 923 | FROM information_schema.tables GROUP BY table_schema 924 | UNION 925 | SELECT '*** all ***' table_schema, 926 | CONCAT(ROUND(SUM(data_length)/(1024*1024),2),'MB') AS 'Table Size', 927 | CONCAT(ROUND(SUM(index_length)/(1024*1024),2),'MB') AS 'Index Size' , 928 | CONCAT(ROUND(SUM(data_length)/(1024*1024),2) + ROUND(SUM(index_length)/(1024*1024),2),'MB') AS 'DB Size' 929 | FROM information_schema.tables""" 930 | style = {1: 'table_schema,l', 2: 'Table Size,r', 3: 'Index Size,r', 4: 'DB Size,r'} 931 | f_print_query_table(conn, title, query, style,save_as) 932 | 933 | if config.get("option","object_count")=='ON': 934 | title = "Object Count" 935 | query = "SELECT information_schema.routines.ROUTINE_TYPE AS object_type, COUNT(0) AS COUNT FROM information_schema.routines \ 936 | WHERE information_schema.routines.ROUTINE_SCHEMA='" + dbinfo[3] + "' GROUP BY information_schema.routines.ROUTINE_TYPE UNION \ 937 | SELECT information_schema.tables.TABLE_TYPE AS object_type, COUNT(0) AS COUNT FROM information_schema.tables \ 938 | WHERE information_schema.tables.TABLE_SCHEMA='" + dbinfo[3] + "' GROUP BY information_schema.tables.TABLE_TYPE UNION \ 939 | SELECT CONCAT('INDEX (',information_schema.statistics.INDEX_TYPE,')') AS object_type,COUNT(0) AS COUNT FROM information_schema.statistics \ 940 | WHERE information_schema.statistics.TABLE_SCHEMA='" + dbinfo[3] + "' GROUP BY information_schema.statistics.INDEX_TYPE UNION \ 941 | SELECT 'TRIGGER' AS `TRIGGER`,COUNT(0) AS COUNT FROM information_schema.triggers \ 942 | WHERE information_schema.triggers.TRIGGER_SCHEMA='" + dbinfo[3] + "' UNION \ 943 | SELECT 'EVENT' AS object_type, COUNT(0) AS COUNT FROM information_schema.events \ 944 | WHERE information_schema.events.EVENT_SCHEMA='" + dbinfo[3] + "'" 945 | style = {1:'object_type,l',2: 'COUNT,r'} 946 | if save_as == "txt": 947 | f_print_query_table(conn, title, query, style,save_as) 948 | 949 | if config.get ( "option", "table_info" ) == 'ON': 950 | title = "Table Info" 951 | query = """select table_name,engine,row_format as format,table_rows,avg_row_length as avg_row, 952 | round((data_length)/1024/1024,2) as data_mb, 953 | round((index_length)/1024/1024,2) as index_mb, 954 | round((data_length+index_length)/1024/1024,2) as total_mb 955 | from information_schema.tables 956 | where table_schema='""" + dbinfo[3] + "'" 957 | style = {1: 'table_name,l', 2: 'engine,l', 3: 'format,l', 4: 'table_rows,r', 5: 'avg_row,r', 958 | 6: 'data_mb,r', 7: 'index_mb,r', 8: 'total_mb,r'} 959 | f_print_query_table(conn, title, query, style,save_as) 960 | 961 | if config.get ( "option", "index_info" ) == 'ON': 962 | title = "Index Info" 963 | query = """select index_name,non_unique,seq_in_index,column_name,collation,cardinality,nullable,index_type 964 | from information_schema.statistics 965 | where table_schema='""" + dbinfo[3] + "'" 966 | style = {1: 'index_name,l', 2: 'non_unique,l', 3: 'seq_in_index,l', 4: 'column_name,l', 967 | 5: 'collation,r', 6: 'cardinality,r', 7: 'nullable,r', 8: 'index_type,r'} 968 | f_print_query_table(conn, title, query, style,save_as) 969 | 970 | if config.get("option", "schema_index_statistics") == 'ON' and sys_schema_exist: 971 | title = "schema_index_statistics" 972 | query = """SELECT table_name,index_name ,rows_selected,select_latency,rows_inserted,insert_latency,rows_updated, 973 | update_latency,rows_deleted,delete_latency 974 | FROM sys.schema_index_statistics where table_schema='""" + dbinfo[3] + "' ORDER BY table_name" 975 | style = {1: 'table_name,l', 2: 'index_name,l', 3: 'rows_selected,r', 4: 'select_latency,r',5: 'rows_inserted,r', 976 | 6: 'insert_latency,r', 7: 'rows_updated,r', 8: 'update_latency,r', 9: 'rows_deleted,r',10: 'delete_latency,r'} 977 | f_print_query_table(conn, title, query, style,save_as) 978 | 979 | if config.get("option", "schema_table_statistics") == 'ON' and sys_schema_exist: 980 | title = "schema_table_statistics" 981 | query = """SELECT table_name,total_latency ,rows_fetched,fetch_latency,rows_inserted,insert_latency,rows_updated, 982 | update_latency,rows_deleted,delete_latency,io_read_requests,io_read,io_read_latency,io_write_requests, 983 | io_write,io_write_latency,io_misc_requests,io_misc_latency 984 | FROM sys.schema_table_statistics where table_schema='""" + dbinfo[3] + "' ORDER BY table_name" 985 | style = {1: 'table_name,l', 2: 'tal_ltc,r', 3: 'rw_ftc,r', 4: 'ftc_ltc,r', 986 | 5: 'rw_ins,r', 6: 'ins_ltc,r', 7: 'rw_upd,r', 8: 'upd_ltc,r', 987 | 9: 'rw_del,r', 10: 'del_ltc,r', 11: 'io_rd_rq,r', 12: 'io_read,r', 988 | 13: 'io_rd_ltc,r', 14: 'io_wt_rq,r', 15: 'io_write,r',16: 'io_wt_ltc,r', 989 | 17: 'io_ms_rq,r',18: 'io_ms_ltc,r'} 990 | f_print_query_table(conn, title, query, style,save_as) 991 | 992 | if config.get("option", "schema_table_statistics_with_buffer") == 'ON' and sys_schema_exist: 993 | title = "schema_table_statistics_with_buffer" 994 | query = """SELECT table_name,innodb_buffer_allocated,innodb_buffer_data,innodb_buffer_free,innodb_buffer_pages, 995 | innodb_buffer_pages_hashed,innodb_buffer_pages_old,innodb_buffer_rows_cached 996 | FROM sys.schema_table_statistics_with_buffer where table_schema='""" + dbinfo[3] + "' ORDER BY table_name" 997 | style = {1: 'table_name,l', 2: 'indb_buf_alc,r', 3: 'indb_buf_data,r', 4: 'indb_buf_free,r', 5: 'indb_buf_page,r', 998 | 6: 'indb_buf_page_hash,r', 7: 'indb_buf_page_old,r', 8: 'indb_buf_rw_cach,r'} 999 | f_print_query_table(conn, title, query, style, save_as) 1000 | 1001 | if config.get("option", "schema_tables_with_full_table_scans") == 'ON' and sys_schema_exist: 1002 | title = "schema_tables_with_full_table_scans" 1003 | query = """SELECT object_schema,object_name,rows_full_scanned,latency FROM sys.schema_tables_with_full_table_scans 1004 | where object_schema='""" + dbinfo[3] + "' ORDER BY object_name" 1005 | style = {1: 'object_schema,l', 2: 'object_name,l', 3: 'rows_full_scanned,r', 4: 'latency,r'} 1006 | f_print_query_table(conn, title, query, style,save_as) 1007 | 1008 | if config.get("option", "schema_unused_indexes") == 'ON' and sys_schema_exist: 1009 | title = "Schema Unused Indexes" 1010 | query = "SELECT object_schema,object_name,index_name FROM sys.schema_unused_indexes where object_schema='" + dbinfo[3] + "'" 1011 | style = {1: 'object_schema,l', 2: 'object_name,l', 3: 'index_name,l'} 1012 | f_print_query_table(conn, title, query, style,save_as) 1013 | 1014 | if config.get("option", "host_summary") == 'ON' and sys_schema_exist: 1015 | title = "host_summary" 1016 | #host 监听连接过的主机 statements 当前主机执行的语句总数 statement_latency 语句等待时间(延迟时间) statement_avg_latency 执行语句平均延迟时间 table_scans 表扫描次数 1017 | #file_ios io时间总数 file_io_latency 文件io延迟 current_connections 当前连接数 total_connections 总链接数 unique_users 该主机的唯一用户数 current_memory 当前账户分配的内存 1018 | #total_memory_allocated 该主机分配的内存总数 1019 | if "5.6" in mysql_version: 1020 | query = """SELECT host,statements,statement_latency,statement_avg_latency,table_scans,file_ios,file_io_latency,current_connections, 1021 | total_connections,unique_users 1022 | FROM sys.host_summary""" 1023 | style = {1: 'host,l', 2: 'statements,r', 3: 'st_ltc,r', 4: 'st_avg_ltc,r', 5: 'table_scan,r', 6: 'file_ios,r', 1024 | 7: 'f_io_ltc,r', 8: 'cur_conns,r', 9: 'total_conn,r', 10: 'unq_users,r'} 1025 | else: 1026 | query = """SELECT host,statements,statement_latency,statement_avg_latency,table_scans,file_ios,file_io_latency,current_connections, 1027 | total_connections,unique_users,current_memory,total_memory_allocated 1028 | FROM sys.host_summary""" 1029 | style = {1: 'host,l', 2: 'statements,r', 3: 'st_ltc,r', 4: 'st_avg_ltc,r', 5: 'table_scan,r', 6: 'file_ios,r', 1030 | 7: 'f_io_ltc,r', 8: 'cur_conns,r', 9: 'total_conn,r', 10: 'unq_users,r', 11: 'cur_mem,r', 1031 | 12: 'tal_mem_alc,r'} 1032 | f_print_query_table(conn, title, query, style,save_as) 1033 | 1034 | if config.get("option", "host_summary_by_file_io_type") == 'ON' and sys_schema_exist: 1035 | title = "host_summary_by_file_io_type" 1036 | #•host 主机 event_name IO事件名称 total 该主机发生的事件 total_latency 该主机发生IO事件总延迟时间 max_latency 该主机IO事件中最大的延迟时间 1037 | query = """SELECT host,event_name,total,total_latency,max_latency 1038 | FROM sys.host_summary_by_file_io_type""" 1039 | style = {1: 'host,l', 2: 'event_name,l', 3: 'total,r', 4: 'total_ltc,r', 5: 'max_ltc,r'} 1040 | f_print_query_table(conn, title, query, style,save_as) 1041 | 1042 | if config.get("option", "host_summary_by_file_io") == 'ON' and sys_schema_exist: 1043 | title = "host_summary_by_file_io_type" 1044 | #•host 主机 ios IO事件总数 io_latency IO总的延迟时间 1045 | query = """SELECT host,ios,io_latency 1046 | FROM sys.host_summary_by_file_io""" 1047 | style = {1: 'host,l', 2: 'ios,r', 3: 'io_latency,r'} 1048 | f_print_query_table(conn, title, query, style,save_as) 1049 | 1050 | if config.get("option", "host_summary_by_stages") == 'ON' and sys_schema_exist: 1051 | title = "host_summary_by_stages" 1052 | #•host 主机 event_name stage event名称 total stage event发生的总数 total_latency stage event总的延迟时间 avg_latency stage event平均延迟时间 1053 | query = """SELECT host,event_name,total,total_latency,avg_latency 1054 | FROM sys.host_summary_by_stages""" 1055 | style = {1: 'host,l', 2: 'event_name,l', 3: 'total,r', 4: 'total_latency,r', 5: 'avg_latency,r'} 1056 | f_print_query_table(conn, title, query, style,save_as) 1057 | 1058 | if config.get("option", "host_summary_by_statement_latency") == 'ON' and sys_schema_exist: 1059 | title = "host_summary_by_statement_latency" 1060 | #host 主机 total 这个主机的语句总数 total_latency 这个主机总的延迟时间 max_latency 主机最大的延迟时间 lock_latency 等待锁的锁延迟时间 1061 | #rows_sent 该主机通过语句返回的总行数 rows_examined 在存储引擎上通过语句返回的行数 rows_affected 该主机通过语句影响的总行数 full_scans 全表扫描的语句总数 1062 | query = """SELECT host,total,total_latency,max_latency,lock_latency,rows_sent,rows_examined,rows_affected,full_scans 1063 | FROM sys.host_summary_by_statement_latency""" 1064 | style = {1: 'host,l', 2: 'total,r', 3: 'total_latency,r', 4: 'max_latency,r', 5: 'lock_latency,r', 1065 | 6: 'rows_sent,r', 7: 'rows_examined,r', 8: 'rows_affected,r',9: 'full_scans,r'} 1066 | f_print_query_table(conn, title, query, style,save_as) 1067 | 1068 | if config.get("option", "host_summary_by_statement_type") == 'ON' and sys_schema_exist: 1069 | title = "host_summary_by_statement_type" 1070 | #host 主机 statement 最后的语句事件名称 total sql语句总数 total_latency sql语句总延迟数 max_latency 最大的sql语句延迟数 1071 | # lock_latency 锁延迟总数 rows_sent 语句返回的行总数 rows_examined 通过存储引擎的sql语句的读取的总行数 rows_affected 语句影响的总行数 full_scans 全表扫描的语句事件总数 1072 | query = """SELECT host,statement,total,total_latency,max_latency,lock_latency,rows_sent,rows_examined,rows_affected,full_scans 1073 | FROM sys.host_summary_by_statement_type""" 1074 | style = {1: 'host,l', 2: 'statement,l', 3: 'total,r', 4: 'total_latency,r', 5: 'max_latency,r', 1075 | 6: 'lock_latency,r', 7: 'rows_sent,r', 8: 'rows_examined,r',9: 'rows_affected,r',10: 'full_scans,r'} 1076 | f_print_query_table(conn, title, query, style,save_as) 1077 | 1078 | if config.get("option", "user_summary") == 'ON' and sys_schema_exist: 1079 | title = "user_summary" 1080 | # statements 当前用户执行的语句总数 statement_latency 语句等待时间(延迟时间) statement_avg_latency 执行语句平均延迟时间 table_scans 表扫描次数 1081 | #file_ios io时间总数 file_io_latency 文件io延迟 current_connections 当前连接数 total_connections 总链接数 unique_users 该用户的唯一主机数 current_memory 当前账户分配的内存 1082 | #total_memory_allocated 该主机分配的内存总数 1083 | if "5.6" in mysql_version: 1084 | 1085 | query = """SELECT user,statements,statement_latency,statement_avg_latency,table_scans,file_ios,file_io_latency,current_connections, 1086 | total_connections,unique_hosts 1087 | FROM sys.user_summary""" 1088 | style = {1: 'user,l', 2: 'statements,r', 3: 'st_ltc,r', 4: 'st_avg_ltc,r', 5: 'table_scan,r', 6: 'file_ios,r', 1089 | 7: 'f_io_ltc,r', 8: 'cur_conns,r', 9: 'total_conn,r', 10: 'unq_hosts,r'} 1090 | else: 1091 | query = """SELECT user,statements,statement_latency,statement_avg_latency,table_scans,file_ios,file_io_latency,current_connections, 1092 | total_connections,unique_hosts,current_memory,total_memory_allocated 1093 | FROM sys.user_summary""" 1094 | style = {1: 'user,l', 2: 'statements,r', 3: 'st_ltc,r', 4: 'st_avg_ltc,r', 5: 'table_scan,r', 6: 'file_ios,r', 1095 | 7: 'f_io_ltc,r', 8: 'cur_conns,r', 9: 'total_conn,r', 10: 'unq_hosts,r', 11: 'cur_mem,r', 12: 'tal_mem_alc,r'} 1096 | f_print_query_table(conn, title, query, style,save_as) 1097 | 1098 | if config.get("option", "user_summary_by_file_io_type") == 'ON' and sys_schema_exist: 1099 | title = "user_summary_by_file_io_type" 1100 | #event_name IO事件名称 total 该用户发生的事件 total_latency 该用户发生IO事件总延迟时间 max_latency 该用户IO事件中最大的延迟时间 1101 | query = """SELECT user,event_name,total,latency,max_latency 1102 | FROM sys.user_summary_by_file_io_type""" 1103 | style = {1: 'user,l', 2: 'event_name,l', 3: 'total,r', 4: 'latency,r', 5: 'max_ltc,r'} 1104 | f_print_query_table(conn, title, query, style,save_as) 1105 | 1106 | if config.get("option", "user_summary_by_file_io") == 'ON' and sys_schema_exist: 1107 | title = "user_summary_by_file_io_type" 1108 | # ios IO事件总数 io_latency IO总的延迟时间 1109 | query = """SELECT user,ios,io_latency 1110 | FROM sys.user_summary_by_file_io""" 1111 | style = {1: 'user,l', 2: 'ios,r', 3: 'io_latency,r'} 1112 | f_print_query_table(conn, title, query, style,save_as) 1113 | 1114 | if config.get("option", "user_summary_by_stages") == 'ON' and sys_schema_exist: 1115 | title = "user_summary_by_stages" 1116 | # event_name stage event名称 total stage event发生的总数 total_latency stage event总的延迟时间 avg_latency stage event平均延迟时间 1117 | query = """SELECT user,event_name,total,total_latency,avg_latency 1118 | FROM sys.user_summary_by_stages""" 1119 | style = {1: 'user,l', 2: 'event_name,l', 3: 'total,r', 4: 'total_latency,r', 5: 'avg_latency,r'} 1120 | f_print_query_table(conn, title, query, style,save_as) 1121 | 1122 | if config.get("option", "user_summary_by_statement_latency") == 'ON' and sys_schema_exist: 1123 | title = "user_summary_by_statement_latency" 1124 | # total 这个主机的语句总数 total_latency 这个主机总的延迟时间 max_latency 主机最大的延迟时间 lock_latency 等待锁的锁延迟时间 1125 | #rows_sent 该主机通过语句返回的总行数 rows_examined 在存储引擎上通过语句返回的行数 rows_affected 该主机通过语句影响的总行数 full_scans 全表扫描的语句总数 1126 | query = """SELECT user,total,total_latency,max_latency,lock_latency,rows_sent,rows_examined,rows_affected,full_scans 1127 | FROM sys.user_summary_by_statement_latency""" 1128 | style = {1: 'user,l', 2: 'total,r', 3: 'total_latency,r', 4: 'max_latency,r', 5: 'lock_latency,r', 1129 | 6: 'rows_sent,r', 7: 'rows_examined,r', 8: 'rows_affected,r',9: 'full_scans,r'} 1130 | f_print_query_table(conn, title, query, style,save_as) 1131 | 1132 | if config.get("option", "user_summary_by_statement_type") == 'ON' and sys_schema_exist: 1133 | title = "user_summary_by_statement_type" 1134 | #statement 最后的语句事件名称 total sql语句总数 total_latency sql语句总延迟数 max_latency 最大的sql语句延迟数 1135 | # lock_latency 锁延迟总数 rows_sent 语句返回的行总数 rows_examined 通过存储引擎的sql语句的读取的总行数 rows_affected 语句影响的总行数 full_scans 全表扫描的语句事件总数 1136 | query = """SELECT user,statement,total,total_latency,max_latency,lock_latency,rows_sent,rows_examined,rows_affected,full_scans 1137 | FROM sys.user_summary_by_statement_type""" 1138 | style = {1: 'user,l', 2: 'statement,l', 3: 'total,r', 4: 'total_latency,r', 5: 'max_latency,r', 1139 | 6: 'lock_latency,r', 7: 'rows_sent,r', 8: 'rows_examined,r',9: 'rows_affected,r',10: 'full_scans,r'} 1140 | f_print_query_table(conn, title, query, style,save_as) 1141 | 1142 | if config.get("option", "innodb_buffer_stats_by_schema") == 'ON' and sys_schema_exist: 1143 | title = "innodb_buffer_stats_by_schema" 1144 | #object_schema 数据库名称 allocated 分配给当前数据库的总的字节数 data 分配给当前数据库的数据字节数 pages 分配给当前数据库的总页数 1145 | # pages_hashed 分配给当前数据库的hash页数 pages_old 分配给当前数据库的旧页数 rows_cached 当前数据库缓存的行数 1146 | query = """SELECT object_schema,allocated,data,pages,pages_hashed,pages_old,rows_cached 1147 | FROM sys.innodb_buffer_stats_by_schema""" 1148 | style = {1: 'object_schema,l', 2: 'allocated,r', 3: 'data,r', 4: 'pages,r', 5: 'pages_hashed,r', 1149 | 6: 'pages_old,r', 7: 'rows_cached,r'} 1150 | f_print_query_table(conn, title, query, style,save_as) 1151 | 1152 | if config.get("option", "innodb_buffer_stats_by_table") == 'ON' and sys_schema_exist: 1153 | title = "innodb_buffer_stats_by_table" 1154 | # object_schema 数据库名称 object_name 表名称 allocated 分配给表的总字节数 data 分配该表的数据字节数 pages 分配给表的页数 1155 | # pages_hashed 分配给表的hash页数 pages_old 分配给表的旧页数 rows_cached 表的行缓存数 1156 | query = """SELECT object_schema,object_name,allocated,data,pages,pages_hashed,pages_old,rows_cached 1157 | FROM sys.innodb_buffer_stats_by_table""" 1158 | style = {1: 'object_schema,l', 2: 'object_name,l', 3: 'allocated,r', 4: 'data,r', 5: 'pages,r', 1159 | 6: 'pages_hashed,r', 7: 'pages_old,r', 8: 'rows_cached,r'} 1160 | f_print_query_table(conn, title, query, style,save_as) 1161 | 1162 | if config.get("option", "io_by_thread_by_latency_topN") != 'OFF' and sys_schema_exist: 1163 | topN = int(config.get("option", "io_by_thread_by_latency_topN")) 1164 | title = "io_by_thread_by_latency top"+str(topN) 1165 | #user 对于当前线程来说,这个值是线程被分配的账户,对于后台线程来讲,就是线程的名称 total IO事件的总数 total_latency IO事件的总延迟 1166 | # min_latency 单个最小的IO事件延迟 avg_latency 平均IO延迟 max_latency 最大IO延迟 thread_id 线程ID processlist_id 对于当前线程就是此时的ID,对于后台就是null 1167 | query = """SELECT user,total,total_latency,min_latency,avg_latency,max_latency,thread_id,processlist_id 1168 | FROM sys.io_by_thread_by_latency LIMIT """+str(topN) 1169 | style = {1: 'user,l', 2: 'total,r', 3: 'total_latency,r', 4: 'min_latency,r', 5: 'avg_latency,r', 1170 | 6: 'max_latency,r', 7: 'thread_id,r', 8: 'processlist_id,r'} 1171 | f_print_query_table(conn, title, query, style,save_as) 1172 | 1173 | if config.get("option", "io_global_by_file_by_bytes_topN") != 'OFF' and sys_schema_exist: 1174 | topN = int(config.get("option", "io_global_by_file_by_bytes_topN")) 1175 | title = "io_global_by_file_by_bytes top"+str(topN) 1176 | query = """SELECT file,count_read,total_read,avg_read,count_write,total_written,avg_write,total,write_pct 1177 | FROM sys.io_global_by_file_by_bytes LIMIT """+str(topN) 1178 | style = {1: 'file,l', 2: 'count_read,r', 3: 'total_read,r', 4: 'avg_read,r', 5: 'count_write,r', 1179 | 6: 'total_written,r', 7: 'avg_write,r', 8: 'total,r', 9: 'write_pct,r'} 1180 | f_print_query_table(conn, title, query, style,save_as) 1181 | 1182 | if config.get("option", "io_global_by_file_by_latency_topN") != 'OFF' and sys_schema_exist: 1183 | topN = int(config.get("option", "io_global_by_file_by_latency_topN")) 1184 | title = "io_global_by_file_by_latency top"+str(topN) 1185 | query = """SELECT file,total,total_latency,count_read,read_latency,count_write,write_latency,count_misc,misc_latency 1186 | FROM sys.io_global_by_file_by_latency LIMIT """+str(topN) 1187 | style = {1: 'file,l', 2: 'total,r', 3: 'total_latency,r', 4: 'count_read,r', 5: 'read_latency,r', 1188 | 6: 'count_write,r', 7: 'write_latency,r', 8: 'count_misc,r', 9: 'misc_latency,r'} 1189 | f_print_query_table(conn, title, query, style,save_as) 1190 | 1191 | if config.get("option", "io_global_by_wait_by_bytes_topN") != 'OFF' and sys_schema_exist: 1192 | topN = int(config.get("option", "io_global_by_wait_by_bytes_topN")) 1193 | title = "io_global_by_wait_by_bytes top"+str(topN) 1194 | query = """SELECT event_name,total,total_latency,min_latency,avg_latency,max_latency,count_read,total_read,avg_read,count_write, 1195 | total_written,avg_written,total_requested 1196 | FROM sys.io_global_by_wait_by_bytes LIMIT """+str(topN) 1197 | style = {1: 'event_name,l', 2: 'total,r', 3: 'total_latency,r', 4: 'min_latency,r', 5: 'avg_latency,r', 1198 | 6: 'max_latency,r', 7: 'count_read,r', 8: 'total_read,r', 9: 'avg_read,r', 10: 'count_write,r', 1199 | 11: 'total_written,r', 12: 'avg_written,r', 13: 'total_requested,r'} 1200 | f_print_query_table(conn, title, query, style,save_as) 1201 | 1202 | if config.get("option", "io_global_by_wait_by_latency_topN") != 'OFF' and sys_schema_exist: 1203 | topN = int(config.get("option", "io_global_by_wait_by_latency_topN")) 1204 | title = "io_global_by_wait_by_latency top"+str(topN) 1205 | query = """SELECT event_name,total,total_latency,avg_latency,max_latency,read_latency,write_latency,misc_latency,count_read, 1206 | total_read,avg_read,count_write,total_written,avg_written 1207 | FROM sys.io_global_by_wait_by_latency LIMIT """+str(topN) 1208 | style = {1: 'event_name,l', 2: 'total,r', 3: 'total_latency,r', 4: 'avg_latency,r', 5: 'max_latency,r', 1209 | 6: 'read_latency,r', 7: 'write_latency,r', 8: 'misc_latency,r', 9: 'count_read,r', 10: 'total_read,r', 1210 | 11: 'avg_read,r', 12: 'count_write,r', 13: 'total_written,r', 14: 'avg_written,r'} 1211 | f_print_query_table(conn, title, query, style,save_as) 1212 | 1213 | if config.get("option", "wait_classes_global_by_avg_latency") == 'ON' and sys_schema_exist: 1214 | title = "wait_classes_global_by_avg_latency" 1215 | query = """SELECT event_class,total,total_latency,min_latency,avg_latency,max_latency 1216 | FROM sys.wait_classes_global_by_avg_latency""" 1217 | style = {1: 'event_class,l', 2: 'total,r', 3: 'total_latency,r',4: 'min_latency,r', 5: 'avg_latency,r', 6: 'max_latency,r'} 1218 | f_print_query_table(conn, title, query, style,save_as) 1219 | 1220 | if config.get("option", "wait_classes_global_by_latency") == 'ON' and sys_schema_exist: 1221 | title = "wait_classes_global_by_latency" 1222 | query = """SELECT event_class,total,total_latency,min_latency,avg_latency,max_latency 1223 | FROM sys.wait_classes_global_by_latency""" 1224 | style = {1: 'event_class,l', 2: 'total,r', 3: 'total_latency,r',4: 'min_latency,r', 5: 'avg_latency,r', 6: 'max_latency,r'} 1225 | f_print_query_table(conn, title, query, style,save_as) 1226 | 1227 | if config.get("option", "waits_by_host_by_latency") == 'ON' and sys_schema_exist: 1228 | title = "waits_by_host_by_latency" 1229 | query = """SELECT HOST,EVENT,total,total_latency,avg_latency,max_latency 1230 | FROM sys.waits_by_host_by_latency """ 1231 | style = {1: 'host,l',2: 'event,l', 3: 'total,r', 4: 'total_latency,r',5: 'avg_latency,r', 6: 'max_latency,r'} 1232 | f_print_query_table(conn, title, query, style,save_as) 1233 | 1234 | if config.get("option", "waits_by_user_by_latency") == 'ON' and sys_schema_exist: 1235 | title = "waits_by_user_by_latency" 1236 | query = """SELECT USER,EVENT,total,total_latency,avg_latency,max_latency 1237 | FROM sys.waits_by_user_by_latency """ 1238 | style = {1: 'user,l',2: 'event,l', 3: 'total,r', 4: 'total_latency,r',5: 'avg_latency,r', 6: 'max_latency,r'} 1239 | f_print_query_table(conn, title, query, style,save_as) 1240 | 1241 | if config.get("option", "waits_global_by_latency") == 'ON' and sys_schema_exist: 1242 | title = "waits_global_by_latency" 1243 | query = """SELECT EVENTS,total,total_latency,avg_latency,max_latency 1244 | FROM sys.waits_global_by_latency """ 1245 | style = {1: 'event,l', 2: 'total,r', 3: 'total_latency,r',4: 'avg_latency,r', 5: 'max_latency,r'} 1246 | f_print_query_table(conn, title, query, style,save_as) 1247 | 1248 | if config.get("option", "schema_table_lock_waits") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1249 | title = "schema_table_lock_waits" 1250 | query = """SELECT object_schema,object_name,waiting_account,waiting_lock_type, 1251 | waiting_lock_duration,waiting_query,waiting_query_secs,waiting_query_rows_affected,waiting_query_rows_examined, 1252 | blocking_account,blocking_lock_type,blocking_lock_duration 1253 | FROM sys.schema_table_lock_waits""" 1254 | #,sql_kill_blocking_query,sql_kill_blocking_connection 1255 | style = {1: 'object_schema,l', 2: 'object_name,r', 3: 'wait_account,r', 4: 'wt_lk_tp,l', 5: 'w_l_dur,l', 1256 | 6: 'waiting_query,l', 7: 'w_qry_s,l', 8: 'w_q_r_a,l',9: 'w_q_r_e,l',10: 'blk_account,l', 1257 | 11: 'bk_lk_tp,l',12: 'b_l_dur,l'} 1258 | f_print_query_table(conn, title, query, style,save_as) 1259 | 1260 | if config.get("option", "innodb_lock_waits") == 'ON' and sys_schema_exist: 1261 | title = "innodb_lock_waits" 1262 | #wait_started 锁等待发生的时间 wait_age 锁已经等待了多长时间 wait_age_secs 以秒为单位显示锁已经等待的时间 1263 | #locked_table 被锁的表 locked_index 被锁住的索引 locked_type 锁类型 waiting_trx_id 正在等待的事务ID waiting_trx_started 等待事务开始的时间 1264 | #waiting_trx_age 已经等待事务多长时间 waiting_trx_rows_locked 正在等待的事务被锁的行数量 waiting_trx_rows_modified 正在等待行重定义的数量 1265 | #waiting_pid 正在等待事务的线程id waiting_query 正在等待锁的查询 waiting_lock_id 正在等待锁的ID waiting_lock_mode 等待锁的模式 1266 | #blocking_trx_id 阻塞等待锁的事务id blocking_pid 正在锁的线程id blocking_query 正在锁的查询 blocking_lock_id 正在阻塞等待锁的锁id. 1267 | #blocking_lock_mode 阻塞锁模式 blocking_trx_started 阻塞事务开始的时间 blocking_trx_age 阻塞的事务已经执行的时间 blocking_trx_rows_locked 阻塞事务锁住的行的数量 1268 | # blocking_trx_rows_modified 阻塞事务重定义行的数量 sql_kill_blocking_query kill 语句杀死正在运行的阻塞事务 sql_kill_blocking_connection kill 语句杀死会话中正在运行的阻塞事务 1269 | query = """SELECT wait_started,wait_age,locked_table,locked_index,locked_type,waiting_query,waiting_lock_mode,blocking_query,blocking_lock_mode 1270 | FROM sys.innodb_lock_waits""" 1271 | style = {1: 'wait_start,l', 2: 'wait_age,r', 3: 'locked_table,r', 4: 'locked_index,l', 5: 'locked_type,l', 1272 | 6: 'waiting_query,l', 7: 'wt_lk_md,l', 8: 'blocking_query,l',9: 'bk_lk_md,l'} 1273 | f_print_query_table(conn, title, query, style,save_as) 1274 | 1275 | if config.get("option", "memory_by_host_by_current_bytes") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1276 | title = "memory_by_host_by_current_bytes" 1277 | query = """SELECT HOST,current_count_used,current_allocated,current_avg_alloc,current_max_alloc,total_allocated 1278 | FROM sys.memory_by_host_by_current_bytes""" 1279 | style = {1: 'HOST,l', 2: 'crt_count_used,r', 3: 'crt_allocatedc,r',4: 'crt_avg_alloc,r', 5: 'crt_max_alloc,r',6: 'tal_alloc,r'} 1280 | f_print_query_table(conn, title, query, style,save_as) 1281 | 1282 | if config.get("option", "memory_by_thread_by_current_bytes") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1283 | title = "memory_by_thread_by_current_bytes" 1284 | query = """SELECT thread_id,USER,current_count_used,current_allocated,current_avg_alloc,current_max_alloc,total_allocated 1285 | FROM sys.memory_by_thread_by_current_bytes ORDER BY thread_id""" 1286 | style = {1: 'thread_id,r', 2: 'USER,l', 3: 'crt_count_used,r', 4: 'crt_allocatedc,r',5: 'crt_avg_alloc,r', 6: 'crt_max_alloc,r',7: 'tal_alloc,r'} 1287 | f_print_query_table(conn, title, query, style,save_as) 1288 | 1289 | if config.get("option", "memory_by_user_by_current_bytes") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1290 | title = "memory_by_user_by_current_bytes" 1291 | query = """SELECT USER,current_count_used,current_allocated,current_avg_alloc,current_max_alloc,total_allocated 1292 | FROM sys.memory_by_user_by_current_bytes""" 1293 | style = {1: 'USER,l', 2: 'crt_count_used,r', 3: 'crt_alloc,r',4: 'crt_avg_alloc,r', 5: 'crt_max_alloc,r',6: 'tal_alloc,r'} 1294 | f_print_query_table(conn, title, query, style,save_as) 1295 | 1296 | if config.get("option", "memory_global_by_current_bytes") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1297 | title = "memory_global_by_current_bytes" 1298 | query = """SELECT event_name,current_count,current_alloc,current_avg_alloc,high_count,high_alloc,high_avg_alloc 1299 | FROM sys.memory_global_by_current_bytes ORDER BY current_alloc DESC""" 1300 | style = {1: 'event_name,l', 2: 'crt_count,r', 3: 'crt_alloc,r',4: 'crt_avg_alloc,r', 5: 'high_count,r',6: 'high_alloc,r',7: 'high_avg_alloc,r'} 1301 | f_print_query_table(conn, title, query, style,save_as) 1302 | 1303 | if config.get("option", "memory_global_total") == 'ON' and sys_schema_exist and not "5.6" in mysql_version: 1304 | title = "memory_global_total" 1305 | query = """SELECT total_allocated FROM sys.memory_global_total""" 1306 | style = {1: 'total_allocated,r'} 1307 | f_print_query_table(conn, title, query, style,save_as) 1308 | 1309 | if config.get ( "option", "processlist" ) == 'ON' and sys_schema_exist: 1310 | title = "processlist" 1311 | query = """SELECT thd_id,USER,command,TIME,current_statement,statement_latency,full_scan,last_statement,last_statement_latency 1312 | FROM sys.processlist 1313 | where db='""" + dbinfo[3] + "'" 1314 | style = {1: 'thd_id,r', 2: 'USER,l', 3: 'command,r', 4:'TIME,r', 5: 'current_sql,r',6: 'sql_ltc,r', 1315 | 7: 'fscan,r',8: 'last_sql,r',9: 'lsql_ltc,r'} 1316 | f_print_query_table(conn, title, query, style,save_as) 1317 | 1318 | if config.get ( "option", "session" ) == 'ON' and sys_schema_exist: 1319 | title = "session" 1320 | query = """SELECT thd_id,USER,command,TIME,current_statement,statement_latency,lock_latency,full_scan,last_statement,last_statement_latency 1321 | FROM sys.session 1322 | where db='""" + dbinfo[3] + "'" 1323 | style = {1: 'thd_id,r', 2: 'USER,l', 3: 'command,r', 4:'TIME,r', 5: 'current_sql,r',6: 'sql_ltc,r', 1324 | 7: 'lock_ltc,r',8: 'fscan,r',9: 'last_sql,r',10: 'lsql_ltc,r'} 1325 | f_print_query_table(conn, title, query, style,save_as) 1326 | 1327 | if config.get ( "option", "metrics" ) == 'ON' and sys_schema_exist: 1328 | title = "metrics" 1329 | query = """SELECT Variable_name,Variable_value,TYPE,Enabled 1330 | FROM sys.metrics 1331 | WHERE Variable_name!='rsa_public_key' and Variable_name!='ssl_cipher_list' and Enabled='YES'""" 1332 | style = {1: 'Variable_name,l', 2: 'Variable_value,r', 3: 'TYPE,l', 4:'Enabled,r'} 1333 | f_print_query_table(conn, title, query, style,save_as) 1334 | 1335 | conn.close() 1336 | f_print_ending(save_as) -------------------------------------------------------------------------------- /txt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinghows/MySQL_Watcher/c95781fcd70a3183422b4717899ce2cb5f1b6771/txt.jpg --------------------------------------------------------------------------------