天天看點

MySQL IO分析之-pt-ioprofile

目錄

  • ​​一、安裝介紹​​
  • ​​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指令,該工具的基本邏輯如下
  1. 使用​

    ​lsof​

    ​​和​

    ​strace​

    ​采集資料
  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資訊可檢視以下連結
  • ​​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 */;      
MySQL IO分析之-pt-ioprofile
結果分析
  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方式
MySQL IO分析之-pt-ioprofile
  • 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,該函數的作用是用來重新定位檔案讀寫的位移。
MySQL IO分析之-pt-ioprofile
  • 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 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​

最不安全也最不耗性能
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

MySQL IO分析之-pt-ioprofile

sync_binlog=1 && innodb_flush_log_at_trx_commit=1

MySQL IO分析之-pt-ioprofile

sync_binlog=1 && innodb_flush_log_at_trx_commit=2

MySQL IO分析之-pt-ioprofile

sync_binlog=0 && innodb_flush_log_at_trx_commit=0

MySQL IO分析之-pt-ioprofile

sync_binlog=0 && innodb_flush_log_at_trx_commit=1

MySQL IO分析之-pt-ioprofile

sync_binlog=0 && innodb_flush_log_at_trx_commit=2

MySQL IO分析之-pt-ioprofile