MySQL学习笔记(Day019:磁盘测试) @(MySQL学习)
[TOC]
一. 磁盘调度算法介绍 1. CFQ
CFQ把I/O请求按照进程
分别放入进程对应的队列中,所以A进程和B进程发出的I/O请求会在两个队列中。而各个队列内部仍然采用合并和排序
的方法,区别仅在于,每一个提交I/O请求的进程都有自己的I/O队列。 CFQ的“公平”是针对进程而言的,它以时间片算法为前提,轮转调度队列,默认从当前队列中取4个请求处理,然后处理下一个队列的4个请求。这样就可以确保每个进程享有的I/O资源是均衡的。 CFQ的缺点是先来的IO请求不一定能被及时满足,可能出现饥饿
的情况。CFQ Wiki
2. Deadline
同CFQ一样,除了维护一个拥有合并和排序功能的请求队列以外,还额外维护了两个队列,分别是读请求队列
和写请求队列
,它们都是带有超时的FIFO队列
。当新来一个I/O请求时,会被同时插入普通队列和读/写队列,然后处理普通队列中的请求。当调度器发现读/写请求队列中的请求超时的时候,会优先处理这些请求,保证尽可能不产生请求饥饿 在DeadLine算法中,每个I/O请求都有一个超时时间,默认读请求是500ms
,写请求是5s
。Deadline Wiki
3. Noop
Noop做的事情非常简单,它不会对I/O请求排序也不会进行任何其它优化(除了合并)。Noop除了对请求合并以外,不再进行任何处理,直接以类似FIFO的顺序提交I/O请求。 Noop面向的不是普通的块设备,而是随机访问设备(例如SSD),对于这种设备,不存在传统的寻道时间,那么就没有必要去做那些多余的为了减少寻道时间而采取的事情了。Noop Wiki
二. iostat(下)
三. MySQL的IO使用情况 1. iotop
注意: 上述命令只能看到MySQL的线程ID(Thread ID)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 mysql> use performance_schema; Database changed mysql> desc threads; + | Field | Type | Null | Key | Default | Extra | + | THREAD_ID | bigint(20) unsigned | NO | | NULL | | | NAME | varchar(128) | NO | | NULL | | | TYPE | varchar(10) | NO | | NULL | | | PROCESSLIST_ID | bigint(20) unsigned | YES | | NULL | | | PROCESSLIST_USER | varchar(32) | YES | | NULL | | | PROCESSLIST_HOST | varchar(60) | YES | | NULL | | | PROCESSLIST_DB | varchar(64) | YES | | NULL | | | PROCESSLIST_COMMAND | varchar(16) | YES | | NULL | | | PROCESSLIST_TIME | bigint(20) | YES | | NULL | | | PROCESSLIST_STATE | varchar(64) | YES | | NULL | | | PROCESSLIST_INFO | longtext | YES | | NULL | | | PARENT_THREAD_ID | bigint(20) unsigned | YES | | NULL | | | ROLE | varchar(64) | YES | | NULL | | | INSTRUMENTED | enum('YES','NO') | NO | | NULL | | | HISTORY | enum('YES','NO') | NO | | NULL | | | CONNECTION_TYPE | varchar(16) | YES | | NULL | | | THREAD_OS_ID | bigint(20) unsigned | YES | | NULL | | + 17 rows in set (0.00 sec) mysql> select name ,type ,thread_id,thread_os_id from threads; + | name | type | thread_id | thread_os_id | + | thread/sql/main | BACKGROUND | 1 | 2481 | | thread/sql/thread_timer_notifier | BACKGROUND | 2 | 2482 | | thread/innodb/io_read_thread | BACKGROUND | 3 | 2486 | | thread/innodb/io_read_thread | BACKGROUND | 4 | 2487 | | thread/innodb/io_read_thread | BACKGROUND | 5 | 2488 | | thread/innodb/io_write_thread | BACKGROUND | 6 | 2489 | | thread/innodb/io_write_thread | BACKGROUND | 7 | 2490 | | thread/innodb/io_write_thread | BACKGROUND | 8 | 2491 | | thread/innodb/io_write_thread | BACKGROUND | 9 | 2492 | | thread/innodb/page_cleaner_thread | BACKGROUND | 10 | 2493 | | thread/innodb/io_read_thread | BACKGROUND | 11 | 2485 | | thread/innodb/io_log_thread | BACKGROUND | 12 | 2484 | | thread/innodb/io_ibuf_thread | BACKGROUND | 13 | 2483 | | thread/innodb/srv_master_thread | BACKGROUND | 15 | 2501 | | thread/sql/background | BACKGROUND | 16 | 2502 | | thread/innodb/srv_purge_thread | BACKGROUND | 17 | 2502 | | thread/sql/background | BACKGROUND | 18 | 2503 | | thread/innodb/srv_monitor_thread | BACKGROUND | 19 | 2500 | | thread/innodb/srv_error_monitor_thread | BACKGROUND | 20 | 2499 | | thread/sql/background | BACKGROUND | 21 | 2504 | | thread/sql/background | BACKGROUND | 22 | 2505 | | thread/innodb/srv_lock_timeout_thread | BACKGROUND | 23 | 2498 | | thread/innodb/dict_stats_thread | BACKGROUND | 24 | 2507 | | thread/innodb/buf_dump_thread | BACKGROUND | 25 | 2506 | | thread/sql/signal_handler | BACKGROUND | 26 | 2510 | | thread/sql/compress_gtid_table | FOREGROUND | 27 | 2511 | | thread/sql/one_connection | FOREGROUND | 28 | 2514 | + 27 rows in set (0.00 sec) mysql> select name ,thread_id,thread_os_id,processlist_id from threads; + | name | thread_id | thread_os_id | processlist_id | + | thread/sql/main | 1 | 2481 | NULL | | thread/sql/thread_timer_notifier | 2 | 2482 | NULL | | thread/innodb/io_read_thread | 3 | 2486 | NULL | | thread/innodb/io_read_thread | 4 | 2487 | NULL | | thread/innodb/io_read_thread | 5 | 2488 | NULL | | thread/innodb/io_write_thread | 6 | 2489 | NULL | | thread/innodb/io_write_thread | 7 | 2490 | NULL | | thread/innodb/io_write_thread | 8 | 2491 | NULL | | thread/innodb/io_write_thread | 9 | 2492 | NULL | | thread/innodb/page_cleaner_thread | 10 | 2493 | NULL | | thread/innodb/io_read_thread | 11 | 2485 | NULL | | thread/innodb/io_log_thread | 12 | 2484 | NULL | | thread/innodb/io_ibuf_thread | 13 | 2483 | NULL | | thread/innodb/srv_master_thread | 15 | 2501 | NULL | | thread/sql/background | 16 | 2502 | NULL | | thread/innodb/srv_purge_thread | 17 | 2502 | NULL | | thread/sql/background | 18 | 2503 | NULL | | thread/innodb/srv_monitor_thread | 19 | 2500 | NULL | | thread/innodb/srv_error_monitor_thread | 20 | 2499 | NULL | | thread/sql/background | 21 | 2504 | NULL | | thread/sql/background | 22 | 2505 | NULL | | thread/innodb/srv_lock_timeout_thread | 23 | 2498 | NULL | | thread/innodb/dict_stats_thread | 24 | 2507 | NULL | | thread/innodb/buf_dump_thread | 25 | 2506 | NULL | | thread/sql/signal_handler | 26 | 2510 | NULL | | thread/sql/compress_gtid_table | 27 | 2511 | 1 | | thread/sql/one_connection | 28 | 2514 | 2 | + 27 rows in set (0.00 sec) mysql> show processlist ; + | Id | User | Host | db | Command | Time | State | Info | + | 2 | root | localhost | performance_schema | Query | 0 | starting | show processlist | + 1 row in set (0.00 sec)mysql> select connection_id(); + | connection_id() | + | 2 | + 1 row in set (0.00 sec)
通过threads表
中的信息,结合iotop -u mysql
的输出,就可以知道某个线程的io使用情况
MySQL 5.6 版本中没有thread_os_id
这个列。 作业一:如何将iotop中的Thread ID和MySQL5.6中的threads表中的信息对应起来。
3. 存储结构对应关系 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +-------------+-------------+-------------+ Database | 16K | 16K | 16K | +------+------+-------------+-------------+ | +------------------------------------------------------------------------+ | +------+ | +------+------v------+------+ Filesystem | 4K | 4K | 4K | 4K | +---+--+------+------+------+ | +------------------------------------------------------------------------+ | +--+ | v +------+------+ +------+ Disk | 512B | 512B | ... ... | 512B | +------+------+ +------+
SSD扇区的大小一般为4K或者8K。但是为了兼容HDD,SSD通过Flash Translation Layer (FTL)的方式转换成512B
4. O_DIRECT
fwrite / fsync
O_DIRECT
1 2 3 4 5 6 7 8 9 +-------------------+ +-------------------+ +-------------------+ | | fwrite | | fsync | | | Buffer Pool +---------------> Filesystem Cache +--------------> Disk | | | | | | | +--------+----------+ +-------------------+ +---------+---------+ | ^ | | | innodb_flush_method = O_DIRECT | +-----------------------------------------------------------------------+
> **`O_DIRECT`的设置参数是告诉系统`直接将数据写入磁盘`,跳过文件系统的缓存。等同于使用`裸设备`的效果**
四. sysbench 1. 安装 建议安装sysbenh-0.5
的版本1 2 3 4 5 6 7 8 9 10 11 12 13 14 shell> https://github.com/akopytov/sysbench.git shell> cd sysbench shell> ./autogen.sh shell> ./configure --with-mysql-includes=/usr/local /mysql56/include/ --with-mysql-libs=/usr/local /mysql56/lib/ shell> make -j 2 shell> make install shell> echo "export LD_LIBRARY_PATH=/usr/local/mysql56/lib/:$LD_LIBRARY_PATH " >> ~/.bashrc shell> source ~/.bashrc shell> sysbench --version sysbench 0.5
3. 测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 shell> sysbench --test =fileio \ --file-num=4 \ --file-block-size=8K \ --file-total-size=1G \ --file-test-mode=rndrd \ --file-extra-flags=direct \ --max-requests=0 \ --max-time=3600 \ --num-threads=4 \ prepare
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 shell> sysbench --test =fileio \ --file-num=4 \ --file-block-size=8K \ --file-total-size=1G \ --file-test-mode=rndrd \ --file-extra-flags=direct \ --max-requests=0 \ --max-time=30 \ --num-threads=4 \ --report-interval=3 \ run sysbench 0.5: multi-threaded system evaluation benchmark Running the test with following options: Number of threads: 4 Report intermediate results every 3 second(s) Random number generator seed is 0 and will be ignored Extra file open flags: 3 4 files, 256Mb each 1Gb total file size Block size 8Kb Number of IO requests: 0 Read/Write ratio for combined random IO test : 1.50 Periodic FSYNC enabled, calling fsync() each 100 requests. Calling fsync() at the end of test , Enabled. Using synchronous I/O mode Doing random read test Threads started! [ 3s] reads: 1.70 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 54.416ms (95%) [ 6s] reads: 1.78 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 55.469ms (95%) [ 9s] reads: 1.75 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 55.253ms (95%) [ 12s] reads: 1.66 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 52.120ms (95%) [ 15s] reads: 1.76 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 51.840ms (95%) [ 18s] reads: 1.79 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 50.933ms (95%) [ 21s] reads: 1.78 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 54.858ms (95%) [ 24s] reads: 1.88 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 50.857ms (95%) [ 27s] reads: 1.75 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 56.238ms (95%) [ 30s] reads: 1.61 MB/s writes: 0.00 MB/s fsyncs: 0.00/s response time: 64.097ms (95%) Operations performed: 6709 reads, 0 writes, 0 Other = 6709 Total Read 52.414Mb Written 0b Total transferred 52.414Mb (1.7462Mb/sec) 223.51 Requests/sec executed General statistics: total time: 30.0160s total number of events: 6709 total time taken by event execution: 120.0223s response time: min: 0.13ms avg: 17.89ms max: 254.62ms approx. 95 percentile: 54.97ms Threads fairness: events (avg/stddev): 1677.2500/28.16 execution time (avg/stddev): 30.0056/0.01
测试完成后执行cleanup
如果是真实的测试 max-time
设置成一周的时间 run
期间可以使用iotop
或者iostat
进行观察