通过performance_schema视图和sys视图定位使用磁盘文件导致IO很高的SQL

思路:

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 语句。

请使用浏览器的分享功能分享到微信等