目錄
- 一、安裝介紹
- 1.1 軟體安裝
- 1.2 參數說明
- 二、使用示例
- 2.1 MySQL 一次 insert 刷幾次盤分析
- 2.1.1 sync、fsync與fdatasync的差別
- 2.1.2 write與pwrite的差別(read與pread)
- 2.2 sync_binlog和innodb_flush_log_at_trx_commit刷盤分析
- 三、pt-ioprofile限制
- 四、參考文檔
- 五、附錄
- 1. 測試結果圖表
一、安裝介紹
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資訊可檢視以下連結
- https://jira.percona.com/browse/PT-1631
## 修改腳本中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
- countCount of I/O operations
- sizesSizes of I/O operations
- timesI/O operation timing
--group-by
- 資料分組方式,預設用filename,支援all|filename|pid
- allSummarize into a single line of output
- filenameOne line of output per filename
- pidOne 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
測試結果彙總
| | fdatasync | fsync | pwrite64 | write | read | total |
1 | 3868 | 46 | 43 | 3946 | 3058 | ||
| | | | | | | 最安全也最耗性能 |
1 | 2 | 3815 | 62 | 3911 | 3861 | 3023 | |
| | | | | | | 最不安全也最不耗性能 |
1 | NULL | 3814 | 3814 | 3806 | 3757 | ||
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