技術分享 | 如何使用 bcc 工具觀測 MySQL 延遲

  • 2020 年 3 月 26 日
  • 筆記

作者:劉安

愛可生測試團隊成員,主要負責 TXLE 開源項目相關測試任務,擅長 Python 自動化測試開發,最近醉心於 Linux 性能分析優化的相關知識。

本文來源:原創投稿

*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。


最近在極客時間上學習《Linux 性能優化實戰》,接觸到了基於 eBPF 的 BCC 軟件包。今天來分享一下 bcc 軟件包中用來觀測 MySQL 的幾個工具。

1. 什麼是 BPF 和 eBPF

  • BPF = Berkeley Packet Filter https://en.wikipedia.org/wiki/BerkeleyPacketFilter
  • BPF 是類 Unix 系統上數據鏈路層的一種原始接口,提供原始鏈路層封包的收發
  • BPF 支持過濾數據包——用戶態的進程可以提供一個過濾程序來聲明它想收到哪些數據包
  • 從 3.18 版本開始,Linux 內核提供了一種擴展的 BPF 虛擬機,被稱為「extended BPF「,簡稱為 eBPF。它能夠被用於非網絡相關的功能,比如附在不同的 tracepoints 上,從而獲取當前內核運行的許多信息

實際上 tcpdump 使用的 libpcap 就是基於 BPF 的。而接下來我們要介紹的基於 eBPF 的 bcc 軟件包可以簡單的理解為過濾內核運行信息的 "tcpdump"。

以下是一張 BPF 的工作流程圖:

2. 什麼是 bcc

  • Bcc 的開源項目:https://github.com/iovisor/bcc
  • eBPF 虛擬機使用的是類似於彙編語言的指令,對於程序編寫來說直接使用難度非常大。bcc 提供了一個名為 bcc 的 python 庫,簡化了 eBPF 應用的開發過程
  • Bcc 收集了大量現成的 eBPF 程序可以直接拿來使用,可以通過以下工具分佈圖感受一下

3. 安裝 bcc

# Ubuntu    sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD    echo "deb https://repo.iovisor.org/apt/$(lsb_release -cs) $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/iovisor.list    sudo apt-get update    sudo apt-get install bcc-tools libbcc-examples linux-headers-$(uname -r)    export PATH=$PATH:/usr/share/bcc/tools      # CentOS    yum install bcc-tools    export PATH=$PATH:/usr/share/bcc/tools   

以 CentOS 7.7 的系統為例,安裝後的工具集如下:

[root@liuan tools]# ls    argdist       btrfsslower   dbslower             ext4dist     gethostlatency  killsnoop       nfsslower    perlflow     pythonflow   rubystat     solisten    tclobjnew   tcpstates  vfsstat    bashreadline  cachestat     dbstat               ext4slower   hardirqs        lib             nodegc       perlstat     pythongc     runqlat      sslsniff    tclstat     tcpsubnet  wakeuptime    biolatency    cachetop      dcsnoop              filelife     javacalls       llcstat         nodestat     phpcalls     pythonstat   runqlen      stackcount  tcpaccept   tcptop     xfsdist    biosnoop      capable       dcstat               fileslower   javaflow        mdflush         offcputime   phpflow      reset-trace  runqslower   statsnoop   tcpconnect  tcptracer  xfsslower    biotop        cobjnew       deadlock_detector    filetop      javagc          memleak         offwaketime  phpstat      rubycalls    shmsnoop     syncsnoop   tcpconnlat  tplist    bitesize      cpudist       deadlock_detector.c  funccount    javaobjnew      mountsnoop      oomkill      pidpersec    rubyflow     slabratetop  syscount    tcpdrop     trace    bpflist       cpuunclaimed  doc                  funclatency  javastat        mysqld_qslower  opensnoop    profile      rubygc       sofdsnoop    tclcalls    tcplife     ttysnoop    btrfsdist     criticalstat  execsnoop            funcslower   javathreads     nfsdist         perlcalls    pythoncalls  rubyobjnew   softirqs     tclflow     tcpretrans  vfscount   

4. 使用 bcc 工具觀測 MySQL:

1)dbstat

功能:將 MySQL/PostgreSQL 的查詢延遲匯總為直方圖

語法:

dbstat [-h] [-v] [-p [PID [PID ...]]] [-m THRESHOLD] [-u] [-i INTERVAL]                  {mysql,postgres}

選項:

{mysql,postgres}                           # 觀測哪種數據庫    -h, --help                                 # 顯示幫助然後退出    -v, --verbose                              # 顯示BPF程序    -p [PID [PID ...]], --pid [PID [PID ...]]  # 要觀測的進程號,空格分隔    -m THRESHOLD, --threshold THRESHOLD        # 只統計查詢延遲比此閾值高的    -u, --microseconds                         # 以微秒為時間單位來顯示延遲(默認單位:毫秒)    -i INTERVAL, --interval INTERVAL           # 打印摘要的時間間隔(單位:秒)   

示例:

# 使用 sysbench 在被觀測數據庫上執行 select    [root@liuan tools]# dbstat mysql -p `pidof mysqld` -u    Tracing database queries for pids 3350 slower than 0 ms...    ^C[14:42:26]         query latency (us)  : count     distribution             0 -> 1          : 0        |                                        |             2 -> 3          : 0        |                                        |             4 -> 7          : 0        |                                        |             8 -> 15         : 0        |                                        |            16 -> 31         : 0        |                                        |            32 -> 63         : 0        |                                        |            64 -> 127        : 0        |                                        |           128 -> 255        : 0        |                                        |           256 -> 511        : 0        |                                        |           512 -> 1023       : 491612   |****************************************|          1024 -> 2047       : 46152    |****                                    |          2048 -> 4095       : 261      |                                        |          4096 -> 8191       : 1        |                                        |          8192 -> 16383      : 3        |                                        |

2)dbslower

功能:跟蹤 MySQL/PostgreSQL 的查詢時間高於閾值

語法:

dbslower [-h] [-v] [-p [PID [PID ...]]] [-x PATH] [-m THRESHOLD]                     {mysql,postgres}

參數:

 {mysql,postgres}                           # 觀測哪種數據庫     -h, --help                                 # 顯示幫助然後退出     -v, --verbose                              # 顯示BPF程序     -p [PID [PID ...]], --pid [PID [PID ...]]  # 要觀測的進程號,空格分隔     -m THRESHOLD, --threshold THRESHOLD        # 只統計查詢延遲比此閾值高的     -x PATH, --exe PATH                        # 數據庫二進制文件的位置

示例:

 # 使用sysbench在被觀測數據庫上執行update_index     [root@liuan tools]# dbslower mysql -p `pidof mysqld` -m 2     Tracing database queries for pids 3350 slower than 2 ms...     TIME(s)        PID          MS QUERY     1.765087       3350      2.996 UPDATE sbtest1 SET k=k+1 WHERE id=963     3.187147       3350      2.069 UPDATE sbtest1 SET k=k+1 WHERE id=628     5.945987       3350      2.171 UPDATE sbtest1 SET k=k+1 WHERE id=325     7.771761       3350      3.853 UPDATE sbtest1 SET k=k+1 WHERE id=595   

5. 使用限制

  • bcc 基於 eBPF 開發(需要 Linux 3.15 及更高版本)。bcc 使用的大部分內容都需要 Linux 4.1 及更高版本。
  • "bcc.usdt.USDTException: failed to enable probe 'query__start'; a possible cause can be that the probe requires a pid to enable" 需要 MySQL 具備 Dtrace tracepoint。 dbslower man page:https://github.com/iovisor/bcc/blob/master/man/man8/mysqld_qslower.8#L17-L18