一、安裝介紹
pt-ioprofile工具是Percona-toolkit工具包中用來分析MySQL各個文件IO活動的小工具,pt-ioprofile工具需要用root用戶執行且依賴於lsof和strace命令,該工具的基本邏輯如下
- 使用
lsof
和strace
採集數據- 匯聚採集的結果,匯聚規則可以是sum或avg
1.1 軟件安裝
## 先安裝依賴包
shell> yum install lsof strace -y
## 下載並安裝percona-toolkit
shell> wget https://www.percona.com/downloads/percona-toolkit/3.1.0/binary/redhat/7/x86_64/percona-toolkit-3.1.0-2.el7.x86_64.rpm
shell> yum install -y percona-toolkit-3.1.0-2.el7.x86_64.rpm
shell> pt-ioprofile --version
因strace在CentOS6和CentOS7上輸出的頭信息格式變化,導致該工具在CentOS7下目前存在BUG需要修改腳本,詳細BUG信息可查看以下鏈接
## 修改腳本中574行對strace的匹配語法
shell> vim /usr/bin/pt-ioprofile +573
## 修改前
573 /^COMMAND/ { mode = "lsof"; }
574 /^Process/ { mode = "strace"; }
## 修改後
573 /^COMMAND/ { mode = "lsof"; }
574 /^(strace: )?Process/ { mode = "strace"; }
1.2 參數說明
--aggregate
- 數據匯聚方式,默認爲sum,支持sum|avg兩種
--cell
- 統計方式,默認爲times(時間消耗),支持times|count|sizes
- count Count of I/O operations
- sizes Sizes of I/O operations
- times I/O operation timing
--group-by
- 數據分組方式,默認用filename,支持all|filename|pid
- all Summarize into a single line of output
- filename One line of output per filename
- pid One line of output per process ID
--profile-pid
- MySQL數據庫的pid
--profile-process
- MySQL數據庫的進程名稱,通過進程名稱解析pid
--run-time
- 數據採集運行時間,默認爲30秒
--save-samples
- 將採集的數據保存到文件中
二、使用示例
2.1 MySQL 一次 insert 刷幾次盤分析
## 確認當前MySQL的參數配置
mysql> select @@log_bin,@@sync_binlog,@@innodb_flush_log_at_trx_commit;
+-----------+---------------+----------------------------------+
| @@log_bin | @@sync_binlog | @@innodb_flush_log_at_trx_commit |
+-----------+---------------+----------------------------------+
| 1 | 1 | 1 |
+-----------+---------------+----------------------------------+
## 開啓pt-ioprofile監控IO
shell> pt-ioprofile --profile-pid=$(pidof mysqld) --cell=count --run-time=5
## 插入一條數據
mysql> insert into t1(uname) values('zhenxing') /* yuzhenxing */;
結果分析
- 對redolog使用的fsync方式刷盤,且redolog是持續刷盤的,所以可以看到在採集數據的幾秒內刷了多次盤
- 對binlog使用的是fdatasync方式刷盤,且binlog只在事務提交時刷盤,也就值觸發了一次刷盤操作
- 因爲是insert操作,所以涉及undolog的生成,對undo也觸發了一次fsync
- 對t1.ibd的數據做修改最終也觸發了一次fsync
2.1.1 sync、fsync與fdatasync的區別
通過下圖我們可以知道binlog採用的是fdatasync方式刷盤,而redo採用的是fsync方式,這兩種方式有什麼區別呢,以及圖中未出現的sync方式
- sync
- sync函數只是將所有修改過的塊緩衝區排入寫隊列,然後就返回,它並不等待實際寫磁盤操作結束。
- fsync
- fsync函數只對由文件描述符filedes指定的單一文件起作用,並且等待寫磁盤操作結束,然後返回。
- fsync可用於數據庫這樣的應用程序,因爲數據庫需要確保將修改過的塊立即寫到磁盤上
- fdatasync
- fdatasync函數類似於fsync,但它隻影響文件的數據部分。而除數據外,fsync還會同步更新文件的屬性。
2.1.2 write與pwrite的區別(read與pread)
通過下圖我們可以知道,對於redolog採用的是pwrite方式寫,而對於binlog用的write方式寫,那這2種方式有什麼區別了,相似還有read與pread
在解釋他們區別前我們需要了解另一個函數lseek,該函數的作用是用來重新定位文件讀寫的位移。
- read/write
- 從磁盤讀取數據或將buf中數據寫入磁盤
- pwrite
- 從緩衝區
buf
到偏移量offset
的文件描述符fd
讀取/寫入計數字節,但文件偏移量未更改。 - 由於lseek和read調用之間,內核可能會臨時掛起進程,所以pread/pwrite是把lseek和read/write的調用作爲一個原子性操作
- 從緩衝區
2.2 sync_binlog和innodb_flush_log_at_trx_commit刷盤分析
通過對比sync_binlog和innodb_flush_log_at_trx_commit在不同配置下的刷盤對比
## 壓測語句
sysbench /usr/local/share/sysbench/oltp_read_write.lua --db-ps-mode=disable --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=sysbench --mysql-password=sysbench --mysql-db=sbtest --tables=1 --table-size=10000000 --report-interval=1 --time=600 --threads=4 run
## 根據不同場景調整sync_binlog和innodb_flush_log_at_trx_commit值
set global sync_binlog=1;
set global innodb_flush_log_at_trx_commit=1;
select @@log_bin,@@sync_binlog,@@innodb_flush_log_at_trx_commit;
## IO監控命令
pt-ioprofile --profile-pid=$(pidof mysqld) --cell=count --group-by=filename --run-time=20
測試結果彙總
sync_binlog |
innodb_xxx_commit |
fdatasync | fsync | pwrite64 | write | read | total |
---|---|---|---|---|---|---|---|
1 | 0 | 3868 | 46 | 43 | 3946 | 3058 | |
1 |
1 |
3666 |
3687 |
3687 |
3677 |
2945 |
最安全也最耗性能 |
1 | 2 | 3815 | 62 | 3911 | 3861 | 3023 | |
0 |
0 |
NULL |
41 |
38 |
4215 |
3825 |
最不安全也最不耗性能 |
0 | 1 | NULL | 3814 | 3814 | 3806 | 3757 | |
0 | 2 | NULL | 68 | 4032 | 3978 | 3827 |
測試結果分析
- 在sync_binlog和innodb_flush_log_at_trx_commit都設置爲0時刷盤頻率最低,對IO影響最小
- 在sync_binlog和innodb_flush_log_at_trx_commit都設置爲1是刷盤頻率最高,每個事務都需要刷盤操作,性能影響最大
- 在sync_binlog設置爲0時,並不會觸發fdatasync操作
- 測試也可以側面說明當磁盤IO壓力較大時,將sync_binlog和innodb_flush_log_at_trx_commit設置爲0確實可以明顯提升數據庫性能
三、pt-ioprofile限制
pt-ioprofile會凍結服務器,並可能使進程崩潰,或在分離後使其性能下降,或使其處於睡眠狀態,pt-ioprofile是一種侵入性工具,不應在生產服務器上使用pt-ioprofile。
四、參考文檔
- https://www.percona.com/doc/percona-toolkit/LATEST/pt-ioprofile.html
- https://jira.percona.com/browse/PT-1631
- https://github.com/percona/percona-toolkit/blob/3.0.12/bin/pt-ioprofile#L574
五、附錄
1. 測試結果圖表
sync_binlog=1 && innodb_flush_log_at_trx_commit=0
sync_binlog=1 && innodb_flush_log_at_trx_commit=1
sync_binlog=1 && innodb_flush_log_at_trx_commit=2
sync_binlog=0 && innodb_flush_log_at_trx_commit=0
sync_binlog=0 && innodb_flush_log_at_trx_commit=1
sync_binlog=0 && innodb_flush_log_at_trx_commit=2