├── 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 | 
27 | 
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 """""",
233 | print v.split(',')[0],
234 | 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 """"+str(col)+" | ",
251 | else:
252 | print """"+str(col)+" | ",
253 | print "
"
254 | print """
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='')
233 | print (v.split(',')[0],end='')
234 | 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 (""""+str(col)+" | ",end='')
251 | else:
252 | print (""""+str(col)+" | ",end='')
253 | print ("
")
254 | print ("""
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
--------------------------------------------------------------------------------