天天看點

DBA 抓包神器 tshark 測評

作者:愛可生

想窺探神秘的網絡世界的奧秘,tshark 助你一臂之力!

作者:趙黎明

愛可生 MySQL DBA 團隊成員,熟悉 Oracle、MySQL 等資料庫,擅長資料庫性能問題診斷、事務與鎖問題的分析等,負責處理客戶 MySQL 及我司自研 DMP 平台日常運維中的問題,對開源資料庫相關技術非常感興趣。

本文來源:原創投稿

愛可生開源社群出品,原創内容未經授權不得随意使用,轉載請聯系小編并注明來源。

常用抓包工具

tshark、tcpdump 和 Wireshark 都是網絡抓包工具,它們可以在網絡上捕獲和分析資料包。

tcpdump

一個開源的,基于指令行的網絡抓包工具。它可以捕獲和分析網絡資料包,運作在幾乎所有的 Unix 和 Linux 系統上;可以抓取實時網絡通信中的資料包,然後通過過濾器及其他參數,對資料包進行解析和處理。

tshark

Wireshark 的指令行版本,也是一個開源的網絡分析工具。它可以在指令行下捕獲和分析網絡流量資料,并使用 Wireshark 的過濾器來提取所需的資料,還支援與各種腳本語言(如 Python 和 Perl)結合使用,以自動化分析過程。

Wireshark

是一個流行的網絡協定分析器,支援從線上網絡或本地檔案中捕獲資料包,并提供了圖形化使用者界面來展示資料包内容;可以解析并顯示各種網絡協定,并提供了強大的分析工具以及過濾器;與 tshark 和 tcpdump 相比,Wireshark 的優勢在于它提供了友好的 GUI 界面,使使用者更輕松地進行網絡協定的分析和調試。

小結

以上這些工具都可以直接捕獲和分析網絡資料包,但它們在使用方式和功能上略有不同;通常,我們會先用 tcpdump 或 tshark 在目标伺服器上抓包生成 pcap 檔案,再将其拿到裝有 Wireshark 的主機上進行分析,本文将會分享 tshark 和 Wireshark 的一些使用技巧。

三次握手和四次揮手

TCP 協定中的三次握手和四次揮手是 TCP 連接配接建立和關閉的過程。

三次握手

  1. 用戶端向伺服器發送 SYN 封包(請求建立連接配接)
  2. 伺服器收到 SYN 封包後,回複 SYN+ACK 封包(同意建立連接配接)
  3. 用戶端收到 SYN+ACK 封包後,再回複 ACK 封包(确認連接配接建立)
DBA 抓包神器 tshark 測評

四次揮手

  1. 用戶端向伺服器發送 FIN 封包(請求斷開連接配接)
  2. 伺服器收到 FIN 封包後,回複 ACK 封包(确認收到請求)
  3. 當伺服器确認資料已經全部發送完畢後,它會向用戶端發送 FIN 封包(關閉連接配接)
  4. 用戶端收到 FIN 封包後,回複 ACK 封包(表示确認收到關閉請求),至此,整個 TCP 連接配接就被徹底關閉了
DBA 抓包神器 tshark 測評

三次握手用于建立連接配接,是雙方協商建立 TCP 連接配接的過程;四次揮手用于斷開連接配接,是雙方結束 TCP 連接配接的過程;不過,有時候四次揮手也會變成三次(如果沒有資料發送,2 個包會合并傳輸)。

DBA 抓包神器 tshark 測評

三次握手和四次揮手的過程

我們可以通過 tshark 抓包來觀察 TCP 連接配接、斷開的具體過程。

-- 在服務端執行 tshark 指令進行抓包
dmp2 (master) ~# tshark -f 'tcp port 3332 and host 10.186.61.83'
Running as user "root" and group "root". This could be dangerous.
Capturing on 'eth0'
==> 等待捕獲 TCP 包直到有内容輸出

# 此處省略了 -i,預設會選擇第一個非 loopback 的網絡接口(可簡寫為 lo),效果與指定 -i eth0 相同
# -f,指定捕獲過濾器的表達式,可指定需要捕獲的内容,如:協定、端口、主機IP等

-- 通過 MySQL 用戶端遠端連接配接到 MySQL 執行個體,等待片刻後再退出
{master} ~# m3332 -s(此處配置了 alias,可省略具體的連接配接串)
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql> exit

-- 觀察螢幕輸出

1、三次握手
從左到右的字段依次代表序号、時間戳(納秒)、源端 IP、目标端 IP、協定、包的長度(位元組)、具體資訊(包括源/目标端口号或裝置名、标志位等内容)
  1 0.000000000 10.186.61.83 -> 10.186.60.68 TCP 74 38858 > mcs-mailsvr [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=2369606050 TSecr=0 WS=128
  2 0.000018368 10.186.60.68 -> 10.186.61.83 TCP 74 mcs-mailsvr > 38858 [SYN, ACK] Seq=0 Ack=1 Win=28960 Len=0 MSS=1460 SACK_PERM=1 TSval=2369617045 TSecr=2369606050 WS=128
  3 0.000233161 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=2369606050 TSecr=2369617045
  4 0.000592420 10.186.60.68 -> 10.186.61.83 TCP 148 mcs-mailsvr > 38858 [PSH, ACK] Seq=1 Ack=1 Win=29056 Len=82 TSval=2369617045 TSecr=2369606050
  5 0.000827920 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=1 Ack=83 Win=29312 Len=0 TSval=2369606051 TSecr=2369617045
  6 0.000833512 10.186.61.83 -> 10.186.60.68 TCP 102 38858 > mcs-mailsvr [PSH, ACK] Seq=1 Ack=83 Win=29312 Len=36 TSval=2369606051 TSecr=2369617045
  7 0.000837263 10.186.60.68 -> 10.186.61.83 TCP 66 mcs-mailsvr > 38858 [ACK] Seq=83 Ack=37 Win=29056 Len=0 TSval=2369617045 TSecr=2369606051
  8 0.001997998 10.186.61.83 -> 10.186.60.68 TCP 264 38858 > mcs-mailsvr [PSH, ACK] Seq=37 Ack=83 Win=29312 Len=198 TSval=2369606052 TSecr=2369617045
  9 0.002021916 10.186.60.68 -> 10.186.61.83 TCP 66 mcs-mailsvr > 38858 [ACK] Seq=83 Ack=235 Win=30080 Len=0 TSval=2369617047 TSecr=2369606052
 10 0.006977223 10.186.60.68 -> 10.186.61.83 TCP 2088 mcs-mailsvr > 38858 [PSH, ACK] Seq=83 Ack=235 Win=30080 Len=2022 TSval=2369617052 TSecr=2369606052
 11 0.007227340 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=235 Ack=2105 Win=33280 Len=0 TSval=2369606057 TSecr=2369617052
 12 0.008426447 10.186.61.83 -> 10.186.60.68 TCP 171 38858 > mcs-mailsvr [PSH, ACK] Seq=235 Ack=2105 Win=33280 Len=105 TSval=2369606058 TSecr=2369617052
 13 0.008812324 10.186.60.68 -> 10.186.61.83 TCP 308 mcs-mailsvr > 38858 [PSH, ACK] Seq=2105 Ack=340 Win=30080 Len=242 TSval=2369617053 TSecr=2369606058
 14 0.009099712 10.186.61.83 -> 10.186.60.68 TCP 291 38858 > mcs-mailsvr [PSH, ACK] Seq=340 Ack=2347 Win=36224 Len=225 TSval=2369606059 TSecr=2369617053
 15 0.009189644 10.186.60.68 -> 10.186.61.83 TCP 106 mcs-mailsvr > 38858 [PSH, ACK] Seq=2347 Ack=565 Win=31104 Len=40 TSval=2369617054 TSecr=2369606059
 16 0.009443936 10.186.61.83 -> 10.186.60.68 TCP 132 38858 > mcs-mailsvr [PSH, ACK] Seq=565 Ack=2387 Win=36224 Len=66 TSval=2369606059 TSecr=2369617054
 17 0.009656405 10.186.60.68 -> 10.186.61.83 TCP 187 mcs-mailsvr > 38858 [PSH, ACK] Seq=2387 Ack=631 Win=31104 Len=121 TSval=2369617054 TSecr=2369606059
 18 0.049641532 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=631 Ack=2508 Win=36224 Len=0 TSval=2369606100 TSecr=2369617054

# 序号 1-3 的包,即 TCP 三次握手的過程
# 1)1 10.186.61.83 -> 10.186.60.68 TCP 74 38858 > mcs-mailsvr [SYN] Seq=0
# 2)2 10.186.60.68 -> 10.186.61.83 TCP 74 mcs-mailsvr > 38858 [SYN, ACK] Seq=0 Ack=1
# 3)3 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=1 Ack=1 

2、四次揮手(在用戶端執行 exit 指令後才會輸出)
 19 86.744173501 10.186.61.83 -> 10.186.60.68 TCP 100 38858 > mcs-mailsvr [PSH, ACK] Seq=631 Ack=2508 Win=36224 Len=34 TSval=2369692794 TSecr=2369617054
 20 86.744194551 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [FIN, ACK] Seq=665 Ack=2508 Win=36224 Len=0 TSval=2369692794 TSecr=2369617054
 21 86.744389417 10.186.60.68 -> 10.186.61.83 TCP 66 mcs-mailsvr > 38858 [FIN, ACK] Seq=2508 Ack=666 Win=31104 Len=0 TSval=2369703789 TSecr=2369692794
 22 86.744632203 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=666 Ack=2509 Win=36224 Len=0 TSval=2369692795 TSecr=2369703789

# 序号 20-22 的包,為四次揮手的過程,這裡由于伺服器并沒有資料要傳輸給用戶端,是以将 FIN 和 ACK 合并在一個 TCP 包中了,即所謂的四次揮手變成了三次
# 1)20 19 86.744173501 10.186.61.83 -> 10.186.60.68 TCP 100 38858 > mcs-mailsvr [PSH, ACK] Seq=631 Ack=2508
# 2)21 10.186.60.68 -> 10.186.61.83 TCP 66 mcs-mailsvr > 38858 [FIN, ACK] Seq=2508 Ack=666
# 3)22 10.186.61.83 -> 10.186.60.68 TCP 66 38858 > mcs-mailsvr [ACK] Seq=666 Ack=2509           

TCP 包标志位的說明

TCP(傳輸控制協定)標頭部有 6 個标志位(Flag),分别為 URG、ACK、PSH、RST、SYN、FIN,它們的十六進制值分别為:0x20、0x10、0x08、0x04、0x02、0x01,其中每個标志位的意義如下:

  • URG 标志:緊急指針是否有效
  • ACK 标志:确認号是否有效
  • PSH 标志:Push操作,盡可能快地将資料交給應用層
  • RST 标志:重置連接配接
  • SYN 标志:發起一個新的連接配接
  • FIN 标志:釋放連接配接

tshark常見用法示例

1. tshark 以自定義字段來展示資訊

-- 服務端執行抓包
dmp2 (master) ~# tshark -i eth0 -d tcp.port==3332,mysql -f "host 10.186.61.83 and tcp port 3332" -T fields -e frame.time -e ip.host -e tcp.flags
Running as user "root" and group "root". This could be dangerous.
Capturing on 'eth0'

# -T fields,可以指定需要輸出的字段,需配合 -e 一起使用,此處将分别列印擷取包的時間、主機 IP 及 TCP 的标志位,這些字段會按照 -e 的順序進行排列展示
# -e,支援多種協定下的字段展示,具體用法查詢路徑:Wireshark -> 分析 -> 顯示過濾器表達式

-- 通過 MySQL 用戶端連接配接執行個體,執行一個查詢,再退出(共有 3 部分:連接配接、通信、斷連)
{master} ~# m3332 -s
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql> select @@version;
@@version
5.7.36-log
mysql> exit

-- 觀察螢幕輸出
1、三次握手
"Jun  6, 2023 14:41:42.839863403 CST"   10.186.61.83,10.186.60.68       0x00000002
"Jun  6, 2023 14:41:42.839904347 CST"   10.186.60.68,10.186.61.83       0x00000012
"Jun  6, 2023 14:41:42.840263352 CST"   10.186.61.83,10.186.60.68       0x00000010
"Jun  6, 2023 14:41:42.840666158 CST"   10.186.60.68,10.186.61.83       0x00000018
"Jun  6, 2023 14:41:42.841604106 CST"   10.186.61.83,10.186.60.68       0x00000010
"Jun  6, 2023 14:41:42.841612112 CST"   10.186.61.83,10.186.60.68       0x00000018
"Jun  6, 2023 14:41:42.841616568 CST"   10.186.60.68,10.186.61.83       0x00000010
"Jun  6, 2023 14:41:42.842524996 CST"   10.186.61.83,10.186.60.68       0x00000018
"Jun  6, 2023 14:41:42.842550796 CST"   10.186.60.68,10.186.61.83       0x00000010
"Jun  6, 2023 14:41:42.848566815 CST"   10.186.60.68,10.186.61.83       0x00000018
"Jun  6, 2023 14:41:42.848826004 CST"   10.186.61.83,10.186.60.68       0x00000010
"Jun  6, 2023 14:41:42.850258537 CST"   10.186.61.83,10.186.60.68       0x00000018
"Jun  6, 2023 14:41:42.850881377 CST"   10.186.60.68,10.186.61.83       0x00000018
"Jun  6, 2023 14:41:42.851278991 CST"   10.186.61.83,10.186.60.68       0x00000018
"Jun  6, 2023 14:41:42.851395808 CST"   10.186.60.68,10.186.61.83       0x00000018
"Jun  6, 2023 14:41:42.851667278 CST"   10.186.61.83,10.186.60.68       0x00000018
"Jun  6, 2023 14:41:42.851926804 CST"   10.186.60.68,10.186.61.83       0x00000018
"Jun  6, 2023 14:41:42.892409030 CST"   10.186.61.83,10.186.60.68       0x00000010

# 前三個包分别為:0x02 [SYN] 、0x12 [SYN, ACK] 、0x10 [ACK],即三次握手的過程
# 後面的幾個包:0x18 [PSH, ACK]、0x10 [ACK],是資料傳輸的過程

2、執行一個查詢
"Jun  6, 2023 14:42:19.967273148 CST"   10.186.61.83,10.186.60.68       0x00000018
"Jun  6, 2023 14:42:19.967553321 CST"   10.186.60.68,10.186.61.83       0x00000018
"Jun  6, 2023 14:42:19.967835719 CST"   10.186.61.83,10.186.60.68       0x00000010

# 當 TCP 連接配接完成後,在資料傳輸過程中擷取的包,其标志位為 0x18 [PSH, ACK] 或 0x10 [ACK]

3、四次揮手
"Jun  6, 2023 14:43:06.157240404 CST"   10.186.61.83,10.186.60.68       0x00000018
"Jun  6, 2023 14:43:06.157833986 CST"   10.186.61.83,10.186.60.68       0x00000011
"Jun  6, 2023 14:43:06.166359966 CST"   10.186.61.83,10.186.60.68       0x00000011
"Jun  6, 2023 14:43:06.166378115 CST"   10.186.60.68,10.186.61.83       0x00000010
"Jun  6, 2023 14:43:06.166971169 CST"   10.186.60.68,10.186.61.83       0x00000011
"Jun  6, 2023 14:43:06.167317550 CST"   10.186.61.83,10.186.60.68       0x00000010

# 看最後 4 個包,0x11 [FIN,ACK]、0x10 [ACK]、0x11 [FIN,ACK]、0x10 [ACK],這是标準的四次揮手過程           

2. tshark 抓取 MySQL 中執行的 SQL

-- 在伺服器上執行抓包
dmp2 (master) ~# tshark -f 'tcp port 3332' -Y "mysql.query" -d tcp.port==3332,mysql -T fields -e frame.time -e ip.src -e ip.dst -e mysql.query
Running as user "root" and group "root". This could be dangerous.
Capturing on 'eth0'

# -Y,指定顯示過濾器表達式,在單次分析中可以代替 -R 選項,此處表示僅顯示 mysql.query 相關的包
# -d,用于指定該抓包會話的協定詳細解析器子產品,可以執行 tshark -d help 來檢視可用的協定(執行雖然會報錯,但會顯示所有支援的協定),此處表示将 3332 端口上的 TCP 包以 MySQL 協定進行解析
# -T fields -e mysql.query,即可擷取符合 MySQL 協定的 SQL 語句
# -e ip.src -e ip.dst 的寫法,也可以用 -e ip.host 來替換

-- 先停止從庫複制後再啟動
[email protected] [(none)]> stop slave;
Query OK, 0 rows affected (0.06 sec)

[email protected] [(none)]> start slave;
Query OK, 0 rows affected (0.05 sec)

-- 觀察螢幕輸出
"Jun  6, 2023 16:11:38.831359581 CST"   10.186.60.74    10.186.60.68    SELECT UNIX_TIMESTAMP()
"Jun  6, 2023 16:11:38.832278722 CST"   10.186.60.74    10.186.60.68    SELECT @@GLOBAL.SERVER_ID
"Jun  6, 2023 16:11:38.832613595 CST"   10.186.60.74    10.186.60.68    SET @master_heartbeat_period= 1000000000
"Jun  6, 2023 16:11:38.832861743 CST"   10.186.60.74    10.186.60.68    SET @master_binlog_checksum= @@global.binlog_checksum
"Jun  6, 2023 16:11:38.833078690 CST"   10.186.60.74    10.186.60.68    SELECT @master_binlog_checksum
"Jun  6, 2023 16:11:38.833278049 CST"   10.186.60.74    10.186.60.68    SELECT @@GLOBAL.GTID_MODE
"Jun  6, 2023 16:11:38.833489342 CST"   10.186.60.74    10.186.60.68    SELECT @@GLOBAL.SERVER_UUID
"Jun  6, 2023 16:11:38.833769721 CST"   10.186.60.74    10.186.60.68    SET @slave_uuid= '90161133-88b1-11ed-bbcc-02000aba3c4a'

# 通過指定 MySQL 協定解析子產品,此處捕獲到了 MySQL 從執行個體在啟動複制時會執行的 SQL 語句
# 如已用 -d 選項指定了協定、端口等資訊時,可省略 -f(抓包過濾器表達式),除非還有其他的過濾需求,但不建議省略 -Y(顯示過濾器表達式),否則會輸出非常多的資訊,以下兩種寫法是等效的:
tshark -f 'tcp port 3332' -Y "mysql.query" -d tcp.port==3332,mysql -T fields -e frame.time -e ip.host -e mysql.query
tshark -Y "mysql.query" -d tcp.port==3332,mysql -T fields -e frame.time -e ip.host -e mysql.query

-- 擷取類型為 Query 的 SQL
dmp2 (master) ~# tshark -i lo -d tcp.port==3332,mysql -Y "mysql.command==3" -T fields -e ip.host -e mysql.query -e frame.time -c 10
Running as user "root" and group "root". This could be dangerous.
Capturing on 'Loopback'
127.0.0.1,127.0.0.1     START TRANSACTION       "Jun  7, 2023 17:17:29.194080437 CST"
127.0.0.1,127.0.0.1     insert ignore into universe.u_delay(source,real_timestamp,logic_timestamp) values ('ustats', now(), 0) "Jun  7, 2023 17:17:29.194306733 CST"
127.0.0.1,127.0.0.1     update universe.u_delay set real_timestamp=now(), logic_timestamp = logic_timestamp + 1 where source = 'ustats'        "Jun  7, 2023 17:17:29.194647464 CST"
127.0.0.1,127.0.0.1     COMMIT  "Jun  7, 2023 17:17:29.194953692 CST"
4 packets captured

# mysql.command=3,表示執行的 SQL 類型為 Query,共支援 30 多種預設值
# 對于熟悉 DMP 的小夥伴,一看便知這是由平台納管的一個執行個體,目前正在做時間戳的寫入(判斷主從延時的依據)

--  擷取與 show 相關的 SQL
dmp2 (master) ~# tshark -i lo -d tcp.port==3332,mysql -Y 'mysql.query contains "show"' -T fields -e ip.host -e mysql.query -e frame.time -c 10
Running as user "root" and group "root". This could be dangerous.
Capturing on 'Loopback'
127.0.0.1,127.0.0.1     show slave status       "Jun  7, 2023 17:37:44.672060318 CST"
127.0.0.1,127.0.0.1     show global status      "Jun  7, 2023 17:37:44.672808866 CST"
127.0.0.1,127.0.0.1     show global variables   "Jun  7, 2023 17:37:44.672845236 CST"
127.0.0.1,127.0.0.1     show global variables where Variable_name = 'innodb_flush_log_at_trx_commit' or Variable_name = 'sync_binlog'  "Jun  7, 2023 17:37:44.673036197 CST"
4 packets captured

dmp2 (master) ~# tshark -i lo -d tcp.port==3332,mysql -Y 'mysql.query matches "^show"' -T fields -e ip.host -e mysql.query -e frame.time -c 10
Running as user "root" and group "root". This could be dangerous.
Capturing on 'Loopback'
127.0.0.1,127.0.0.1     show global status      "Jun  7, 2023 17:56:02.671895630 CST"
127.0.0.1,127.0.0.1     show slave status       "Jun  7, 2023 17:56:02.671944388 CST"
127.0.0.1,127.0.0.1     show global variables   "Jun  7, 2023 17:56:02.671998965 CST"
127.0.0.1,127.0.0.1     show master status      "Jun  7, 2023 17:56:02.672673795 CST"
4 packets captured

# contains 使用字元串進行比對,隻要在資料包中存在指定的字元串,就會比對成功,不論該字元串出現在查詢的任何位置
# matches 支援使用正規表達式進行比對,比對符合指定規則的資料包,如:^show
# 用 contains/maches 進行比對查找時,關鍵詞需用雙引号包圍,此時外層建議使用單引号,因為 maches 進行正則比對時,外層使用雙引号會報錯,contains 則不限制
# 以上比對方式類似模糊查詢,但會區分大小寫,如果指定 Show 或 SHOW 為關鍵詞,可能擷取不到 SQL           

3. tshark 抓取 OB 中執行 SQL

與之前的方法類似,隻需調整 IP 位址和端口号即可。

-- 抓取 5 個 mysql.query 協定的包
[root@10-186-65-73 ~]# tshark -i lo -Y "mysql.query" -d tcp.port==2881,mysql -T fields -e frame.time -e ip.host -e mysql.query -c 5
Running as user "root" and group "root". This could be dangerous.
Capturing on 'Loopback'
"Jun  7, 2023 15:40:12.886615893 CST"   127.0.0.1,127.0.0.1     select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ __all_tenant.tenant_id, tenant_name, mem_used, access_count, hit_count from v$plan_cache_stat join __all_tenant on v$plan_cache_stat.tenant_id = __all_tenant.tenant_id
"Jun  7, 2023 15:40:12.889500546 CST"   127.0.0.1,127.0.0.1     select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ tenant_name, tenant_id, case when event_id = 10000 then 'INTERNAL' when event_id = 13000 then 'SYNC_RPC' when event_id = 14003 then 'ROW_LOCK_WAIT' when (event_id >= 10001 and event_id <= 11006) or (event_id >= 11008 and event_id <= 11011) then 'IO' when event like 'latch:%' then 'LATCH' else 'OTHER' END event_group, sum(total_waits) as total_waits, sum(time_waited_micro / 1000000) as time_waited from v$system_event join __all_tenant on v$system_event.con_id = __all_tenant.tenant_id where v$system_event.wait_class <> 'IDLE' and (con_id > 1000 or con_id = 1) group by tenant_name, event_group
2 packets captured

# 執行抓包指令的伺服器是 OBServer 叢集内的一個節點,2881 是 OB 的對外服務的端口号
# -c,指定抓取 5 個包,實際上隻抓到了 2 個符合過濾條件的包
# 從擷取的 SQL 語句來看,猜測是由 ocp_monagent 監控元件發起的資訊收集相關的 SQL

-- 抓包時過濾包含 “__all_” 視圖的 SQL
[root@10-186-65-73 ~]# tshark -i lo -Y 'mysql.query contains "__all_"' -d tcp.port==2881,mysql -T fields -e frame.time -e ip.host -e mysql.query -c 5
Running as user "root" and group "root". This could be dangerous.
Capturing on 'Loopback'
"Jun  7, 2023 18:14:38.895171334 CST"   127.0.0.1,127.0.0.1     select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ tenant_name, tenant_id, stat_id, value from v$sysstat, __all_tenant where stat_id IN (10000, 10001, 10002, 10003, 10004, 10005, 10006, 140002, 140003, 140005, 140006, 40030, 60019, 60020, 60024, 80040, 80041, 130000, 130001, 130002, 130004, 20000, 20001, 20002, 30000, 30001, 30002, 30005, 30006, 30007, 30008, 30009, 30010, 30011, 30012, 30013, 40000, 40001, 40002, 40003, 40004, 40005, 40006, 40007, 40008, 40009, 40010, 40011, 40012, 40018, 40019, 50000, 50001, 50002, 50004, 50005, 50008, 50009, 50010, 50011, 50037, 50038, 60000, 60001, 60002, 60003, 60004, 60005, 60019, 60020, 60021, 60022, 60023, 60024, 80057, 120000, 120001, 120009, 120008) and (con_id > 1000 or con_id = 1) and __all_tenant.tenant_id = v$sysstat.con_id and class < 1000
"Jun  7, 2023 18:14:38.896653822 CST"   127.0.0.1,127.0.0.1     select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ tenant_id, tenant_name, sum(total_waits) as total_waits, sum(time_waited_micro) / 1000000 as time_waited from v$system_event join __all_tenant on v$system_event.con_id = __all_tenant.tenant_id where v$system_event.wait_class <> 'IDLE' group by tenant_name
2 packets captured

[root@10-186-65-73 ~]# tshark -i lo -Y 'mysql.query contains "__all_"' -d tcp.port==2881,mysql -T fields -e frame.time -e ip.host -e mysql.query > /tmp/monit_ob.txt
Running as user "root" and group "root". This could be dangerous.
Capturing on 'Loopback'
124 ^C
You have mail in /var/spool/mail/root
[root@10-186-65-73 ~]# cat /tmp/monit_ob.txt |grep -i select|wc -l

# 可用此方法來擷取一些常用的 “__all_” 視圖相關的監控 SQL
# 将捕獲的 SQL 重定向到文本檔案,再用 awk 處理一下就能擷取完整的 SQL

[root@10-186-65-73 ~]# awk -F " "  '{for (i=7;i<=NF;i++)printf("%s ", $i);print ""}' /tmp/monit_ob.txt|cat -n|head -5
     1  select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ zone, name, value, time_to_usec(now()) as current from __all_zone
     2  select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ __all_tenant.tenant_id, tenant_name, cache_name, cache_size from __all_virtual_kvcache_info, __all_tenant where __all_tenant.tenant_id = __all_virtual_kvcache_info.tenant_id and svr_ip = '10.186.65.73' and svr_port = 2882
     3  select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ case when cnt is null then 0 else cnt end as cnt, tenant_name, tenant_id from (select __all_tenant.tenant_name, __all_tenant.tenant_id, cnt from __all_tenant left join (select count(1) as cnt, tenant as tenant_name from __all_virtual_processlist where svr_ip = '10.186.65.73' and svr_port = 2882 group by tenant) t1 on __all_tenant.tenant_name = t1.tenant_name) t2
     4  select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ case when cnt is null then 0 else cnt end as cnt, tenant_name, tenant_id from (select __all_tenant.tenant_name, __all_tenant.tenant_id, cnt from __all_tenant left join (select count(`state`='ACTIVE' OR NULL) as cnt, tenant as tenant_name from __all_virtual_processlist where svr_ip = '10.186.65.73' and svr_port = 2882 group by tenant) t1 on __all_tenant.tenant_name = t1.tenant_name) t2
     5  select /*+ MONITOR_AGENT READ_CONSISTENCY(WEAK) */ __all_tenant.tenant_id, tenant_name, mem_used, access_count, hit_count from v$plan_cache_stat join __all_tenant on v$plan_cache_stat.tenant_id = __all_tenant.tenant_id            

4. tshark 抓包後用 Wireshark 解析

tshark 也可以像 tcpdump 一樣,先在伺服器上抓包,再拿到 Wireshark 的圖形視窗中做進一步分析。

-- 抓取 50 個包并生成 pcap 檔案
dmp2 (master) ~# tshark -d tcp.port==3332,mysql -f 'tcp port 3332 and host 10.186.61.83' -c 50 -w /tmp/61_83.pcap
Running as user "root" and group "root". This could be dangerous.
Capturing on 'eth0'

# 注意,-w 指定的檔案無需提前建立,但抓包會話必須對該目錄有寫入權限,否則會報權限不足的錯誤。           

以下截圖為三次握手和四次揮手的過程。

DBA 抓包神器 tshark 測評
DBA 抓包神器 tshark 測評

同樣地,也可以在 Wireshark 中将 mysql.query 字段展示出來:Wireshark -> 編輯 -> 首選項 -> 外觀 -> 列 。

DBA 抓包神器 tshark 測評

以下顯示過濾器表達式中的内容表示:将包中 TCP 端口為 3332,源端 IP 位址為 10.186.60.74,協定類型為 MySQL 的内容過濾并展示,效果如圖:

DBA 抓包神器 tshark 測評

結語

tshark 作為 Wireshark 的指令行工具,與我們比較熟悉的 tcpdump 相比,有其不少優點:

1. 更多的過濾條件

具有比 tcpdump 更多的過濾條件,可以更加精确地過濾所需的資料包,tshark 支援 Wireshark 過濾器文法的全部特性,并提供了更進階的功能。

2. 更加靈活的輸出格式

可以以不同的檔案格式和标準輸出列印輸出捕獲資料,而 tcpdump 的輸出格式非常有限。

3. 更好的可讀性和易用性

輸出會更加易于閱讀,因為它會對分組進行解析并顯示其中包含的各種資料,比如協定、參數和錯誤資訊等。這些資訊對資料包分析非常有幫助。

4. 更加輕量級

相比于 tcpdump,占用的系統資源較少,并且不需要将所有資料存儲在記憶體中,進而能夠處理更大的資料流。

5. 更多的網絡協定

支援更多的網絡協定,包括 IPv6、IS-IS、IPX 等,而 tcpdump 支援的協定種類相對較少。

綜上,在一些較為複雜的資料包分析和網絡問題診斷場景中,更推薦使用 tshark,而對于隻需快速捕捉網絡流量的簡單應用場景,tcpdump 可能會更适合一些。

繼續閱讀