MySQL IO分析之-pt-ioprofile

一、安裝介紹

pt-ioprofile工具是Percona-toolkit工具包中用來分析MySQL各個文件IO活動的小工具,pt-ioprofile工具需要用root用戶執行且依賴於lsof和strace命令,該工具的基本邏輯如下

  1. 使用lsofstrace採集數據
  2. 匯聚採集的結果,匯聚規則可以是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 */;

結果分析

  1. 對redolog使用的fsync方式刷盤,且redolog是持續刷盤的,所以可以看到在採集數據的幾秒內刷了多次盤
  2. 對binlog使用的是fdatasync方式刷盤,且binlog只在事務提交時刷盤,也就值觸發了一次刷盤操作
  3. 因爲是insert操作,所以涉及undolog的生成,對undo也觸發了一次fsync
  4. 對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。

四、參考文檔

五、附錄

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章