思路:
1. 执行测试的语句,使用 TOP 查看操作系统的性能状态
2. iostat
3. iotop
4. 通过 performance_schema 中的 events_waits_summary_global_by_event_name 表的等待时间排序找出
TOP 等待事件。
或通过 sys 库中的 io_global_by_wait_by_latency 表找出 TOP 等待事件
5. 查询 SYS 库的 io_global_by_file_by_bytes 表找到发生大量IO的是一个临时文件
6. 查询 SYS 库的 statements_with_temp_tables 或 statements_with_runtimes_in_95th_percentile找到 TOP
SQL
1. 执行测试的语句,使用 TOP 查看操作系统的性能状态
mysql>
use test;
create table mutex_instances_test as select * from performance_schema.mutex_instances;
insert into mutex_instances_test select a.* from mutex_instances_test a,mutex_instances_test b;
磁盘IO等待占了CPU 使用率的 78%。
2. 查看 IOSTAT 数据
磁盘忙碌度为100%,磁盘IO等待为925.88毫秒。
3. iostop 查看IO高的进程
通过 iotop 看到 IO最高的是 MYSQLD 进程。
4. 通过 performance_schema 中的 events_waits_summary_global_by_event_name 表的
等待时间排序找出 TOP 等待事件。
SELECT EVENT_NAME, COUNT_STAR, SUM_TIMER_WAIT/1000000000/1000 SUM_TIMER_WAIT_S
FROM performance_schema.events_waits_summary_global_by_event_name
WHERE SUM_TIMER_WAIT > 0 AND EVENT_NAME <>'idle'
ORDER BY SUM_TIMER_WAIT_S DESC limit 10;
wait/io/file/myisam/dfile 等待事件是等待时间最高的。
或通过 sys 库中的 io_global_by_wait_by_latency 表找出 TOP 等待事件
mysql> use sys
mysql> select * from io_global_by_wait_by_latency limit 10\G
*************************** 1. row ***************************
event_name: myisam/dfile
total: 69859
total_latency: 1.17 m
avg_latency: 1.01 ms
max_latency: 2.13 s
read_latency: 41.43 ms
write_latency: 1.17 m
misc_latency: 19.05 ms
count_read: 132
total_read: 11.47 MiB
avg_read: 88.98 KiB
count_write: 69282
total_written: 8.46 GiB
avg_written: 127.99 KiB
*************************** 2. row ***************************
event_name: innodb/innodb_data_file
total: 2128
total_latency: 6.53 s
avg_latency: 3.07 ms
max_latency: 1.29 s
read_latency: 2.02 s
write_latency: 403.63 ms
misc_latency: 4.11 s
count_read: 448
total_read: 8.97 MiB
avg_read: 20.50 KiB
count_write: 1301
total_written: 61.05 MiB
avg_written: 48.05 KiB
*************************** 3. row ***************************
event_name: innodb/innodb_log_file
total: 61
total_latency: 1.16 s
avg_latency: 19.02 ms
max_latency: 336.99 ms
read_latency: 45.95 ms
write_latency: 392.16 ms
misc_latency: 722.40 ms
count_read: 6
total_read: 68.00 KiB
avg_read: 11.33 KiB
count_write: 27
total_written: 21.55 MiB
avg_written: 817.43 KiB
通过 io_global_by_wait_by_latency 视图定位到排在首位的是 myisam/dfile 等待事件,使用了myisam 表有几种情况,一是使用myisam引擎的表,二是磁盘排序,三时大数据量表连接。
接下来定位 IO 等待很高的文件。
5. 查询 SYS 库的 io_global_by_file_by_bytes 表找到发生大量IO的是一个临时文件
sql正在执行时可以查到文件
mysql>use sys
mysql> select * from io_global_by_file_by_bytes limit 1\G
*************************** 1. row ***************************
file: @@tmpdir/#sql_a41_0.MYD
count_read: 0
total_read: 0 bytes
avg_read: 0 bytes
count_write: 24399
total_written: 2.98 GiB
avg_write: 127.99 KiB
total: 2.98 GiB
write_pct: 100.00
1 row in set (0.01 sec)
从输出的信息看到IO 等待最高的是一个临时文件,文件的后缀是 .MYD 证明是使用了MYISAM 引擎的磁盘排序临时文件。
6. 查询 SYS 库的 statements_with_temp_tables 或 statements_with_runtimes_in_95th_percentile
找到 TOP SQL
通过查询 statements_with_temp_tables 视图定位磁盘临时文件使用高的SQL(这给视图在SQL执行完后都可以查到导致问题的SQL)
mysql> select * from statements_with_temp_tables limit 1\G
*************************** 1. row ***************************
query: INSERT INTO `mutex_instances_t ... , `mutex_instances_test` `b`
db: test
exec_count: 5
total_latency: 8.78 m
memory_tmp_tables: 5
disk_tmp_tables: 5
avg_tmp_tables_per_query: 1
tmp_tables_to_disk_pct: 100
first_seen: 2016-12-20 19:50:46
last_seen: 2016-12-20 21:08:38
digest: 94f47a6ec621da457959add5ce41641c
1 row in set (0.25 sec)
通过查询 tatements_with_runtimes_in_95th_percentile 视图找出按时间倒序排序的 TOP SQL
mysql> select * from statements_with_runtimes_in_95th_percentile limit 1\G
*************************** 1. row ***************************
query: INSERT INTO `mutex_instances_t ... , `mutex_instances_test` `b`
db: test
full_scan: *
exec_count: 5
err_count: 4
warn_count: 0
total_latency: 8.78 m
max_latency: 2.35 m
avg_latency: 1.76 m
rows_sent: 0
rows_sent_avg: 0
rows_examined: 216774
rows_examined_avg: 43355
first_seen: 2016-12-20 19:50:46
last_seen: 2016-12-20 21:08:38
digest: 94f47a6ec621da457959add5ce41641c
1 row in set (0.13 sec)
通过上面两个视图都可以定位到我们测试用的使用迪凯尔积连接大量使用磁盘临时表的 SQL 语句。