Tcpdump MySQL Query


在MySQL線上環境我們一般只打開了binary log,slow log,有時我們需要查看general log呢?因為該log記錄所有的請求,打開該日志肯定給磁盤造成很大壓力,IO能力有所下降,所以該日志線上一般不打開的,這就到tcpdump閃亮登場了。

tcpdump用法也不算復雜,輸出就比較復雜了,如果非常熟悉TCP/IP協議,那么輸出對於你來說就是小kiss啦。我們這里只關心MySQL的Query,所以輸出還是非常簡單,就是日常的查詢語句。

1.安裝

一般系統都自帶了tcpdump命令,沒有該命令的采用如下方式安裝:

[root@yayun-mysql-server ~]# yum install tcpdump -y

2.簡單使用(shell結合perl過濾查詢)

[root@yayun-mysql-server ~]# cat query.sh 
#!/bin/bash

tcpdump -i any -s 0 -l -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
    if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL)/i)
    {
        if (defined $q) { print "$q\n"; }
        $q=$_;
    } else {
        $_ =~ s/^[ \t]+//; $q.=" $_";
    }
}'
[root@yayun-mysql-server ~]# 

關於各個參數說明請閱讀文章最后給的鏈接。
執行上面腳本,在另外一個窗口執行查詢,我使用了sysbench進行壓力測試,最后抓取到的結果如下:

tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
 4{ @ H{ @ H` @ ?h 'f$ ?h ;f$ ?h Of$ ?h cf$ ?h wf$ ?h" f$ ?h# f% ?h# f% H| @ Lg @ ?h+ f% <X _ ?h/ f% ?h/ f% Ha @ #d +/ #d ?/ #d S/ #d g/ #d {/ Hh @ H} @ <e _ L| @ Hb @ ?h? f& ?hM f' ?hN f' ?hZ f( #d3 / H      @ Hi @ <x _ <x _ H~ @ Hc @ H} @ S 5       r ,) r @) r T) r h) r v) r! ) ?h~ f+ r+ ) N9 O f+#: f+#: #dM / Lj @ Hd @ #d_ / SHOW TABLE STATUS LIKE 'sbtest'
SELECT c from sbtest where id=?
SELECT c from sbtest where id between ? and ?
SELECT SUM(K) from sbtest where id between ? and ?
SELECT c from sbtest where id between ? and ? order by c
SELECT DISTINCT c from sbtest where id between ? and ? order by c
UPDATE sbtest set k=k+1 where id=?
UPDATE sbtest set c=? where id=?
DELETE from sbtest where id=?
INSERT INTO sbtest values(?,0,' ','aaaaaaaaaaffffffffffrrrrrrrrrreeeeeeeeeeyyyyyyyyyy')
SELECT c from sbtest where id=?
SELECT c from sbtest where id between ? and ?
SELECT SUM(K) from sbtest where id between ? and ?
SELECT c from sbtest where id between ? and ? order by c
SELECT DISTINCT c from sbtest where id between ? and ? order by c
UPDATE sbtest set k=k+1 where id=?
UPDATE sbtest set c=? where id=?
DELETE from sbtest where id=?
INSERT INTO sbtest values(?,0,' ','aaaaaaaaaaffffffffffrrrrrrrrrreeeeeeeeeeyyyyyyyyyy')
SELECT c from sbtest where id=?
SELECT c from sbtest where id between ? and ?
SELECT SUM(K) from sbtest where id between ? and ?
SELECT c from sbtest where id between ? and ? order by c
SELECT DISTINCT c from sbtest where id between ? and ? order by c
UPDATE sbtest set k=k+1 where id=?
UPDATE sbtest set c=? where id=?
DELETE from sbtest where id=?
INSERT INTO sbtest values(?,0,' ','aaaaaaaaaaffffffffffrrrrrrrrrreeeeeeeeeeyyyyyyyyyy')
SELECT c from sbtest where id=?
SELECT c from sbtest where id between ? and ?
SELECT SUM(K) from sbtest where id between ? and ?
SELECT c from sbtest where id between ? and ? order by c
SELECT DISTINCT c from sbtest where id between ? and ? order by c
UPDATE sbtest set k=k+1 where id=?
UPDATE sbtest set c=? where id=?
DELETE from sbtest where id=?

其實還有更簡單的方法,那就是使用tcpflow

安裝tcpflow

[root@yayun-mysql-server ~]# yum install tcpflow -y

抓取數據的命令如下:

[root@yayun-mysql-server ~]# tcpflow -c -p -i any dst port 3306 | grep -i -E "select|insert|update|delete|replace" | sed 's%\(.*\)\([.]\{4\}\)\(.*\)%\3%'  

輸出結果和tcpdump結果是一樣的。

tcpflow[9461]: listening on any
SELECT c from sbtest where id=?
SELECT c from sbtest where id between ? and ?
SELECT SUM(K) from sbtest where id between ? and ?
SELECT c from sbtest where id between ? and ? order by c
SELECT DISTINCT c from sbtest where id between ? and ? order by c
UPDATE sbtest set k=k+1 where id=?
UPDATE sbtest set c=? where id=?
DELETE from sbtest where id=?
INSERT INTO sbtest values(?,0,' ','aaaaaaaaaaffffffffffrrrrrrrrrreeeeeeeeeeyyyyyyyyyy')
SELECT c from sbtest where id=?
SELECT c from sbtest where id between ? and ?
SELECT SUM(K) from sbtest where id between ? and ?
SELECT c from sbtest where id between ? and ? order by c
SELECT DISTINCT c from sbtest where id between ? and ? order by c
UPDATE sbtest set k=k+1 where id=?
UPDATE sbtest set c=? where id=?
DELETE from sbtest where id=?
INSERT INTO sbtest values(?,0,' ','aaaaaaaaaaffffffffffrrrrrrrrrreeeeeeeeeeyyyyyyyyyy')
SELECT c from sbtest where id=?
SELECT c from sbtest where id between ? and ?
SELECT SUM(K) from sbtest where id between ? and ?
SELECT c from sbtest where id between ? and ? order by c
SELECT DISTINCT c from sbtest where id between ? and ? order by c

最后說說pt-query-digest,這工具包含在percona-toolkit,在分析慢查詢方面是非常的好使,具體的用法大家自己前往官網查閱。

我們通過tcpdump抓包以后,通過--type tcpdump選項來分析一下,簡單的用法如下:

[root@yayun-mysql-server ~]# tcpdump -s 65535 -x -nn -q -tttt -i any -c 1000 port 3306 > mysql.tcp.txt
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
1000 packets captured
3235 packets received by filter
2023 packets dropped by kernel
[root@yayun-mysql-server ~]# 

然后使用pt-query-digest工具來進行分析一下,用法也比較簡單

[root@yayun-mysql-server ~]# pt-query-digest --type tcpdump mysql.tcp.txt                             

# 340ms user time, 50ms system time, 24.38M rss, 205.10M vsz
# Current date: Thu Jun 26 03:44:15 2014
# Hostname: yayun-mysql-server
# Files: mysql.tcp.txt
# Overall: 20 total, 1 unique, 115.61 QPS, 0.02x concurrency _____________
# Time range: 2014-06-26 03:44:11.127883 to 03:44:11.300885
# Attribute          total     min     max     avg     95%  stddev  median
# ============     ======= ======= ======= ======= ======= ======= =======
# Exec time            3ms    51us   862us   171us   568us   191us    84us
# Rows affecte           0       0       0       0       0       0       0
# Query size           100       5       5       5       5       0       5
# Warning coun           0       0       0       0       0       0       0

# Profile
# Rank Query ID           Response time Calls R/Call V/M   Item
# ==== ================== ============= ===== ====== ===== =====
#    1 0x85FFF5AA78E5FF6A 0.0034 100.0%    20 0.0002  0.00 BEGIN

# Query 1: 115.61 QPS, 0.02x concurrency, ID 0x85FFF5AA78E5FF6A at byte 135761
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: 2014-06-26 03:44:11.127883 to 03:44:11.300885
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count        100      20
# Exec time    100     3ms    51us   862us   171us   568us   191us    84us
# Rows affecte   0       0       0       0       0       0       0       0
# Query size   100     100       5       5       5       5       0       5
# Warning coun   0       0       0       0       0       0       0       0
# String:
# Hosts        192.168.1.20
# Query_time distribution
#   1us
#  10us  ################################################################
# 100us  ####################################################
#   1ms
#  10ms
# 100ms
#    1s
#  10s+
BEGIN\G
[root@yayun-mysql-server ~]# 

如果系統歷史比較久,我們想知道哪些賬號在連接數據庫的話,可以使用下面的命令,非常簡單方便哦。

 tcpdump -s 65535 -x -nn -q -tttt -i any -c 1000  port 3306 | pt-query-digest --limit=100% --type tcpdump | perl -lne 'BEGIN{$/=""};1 while(/Hosts\s+((?:\d{1,3}\.){3}\d{1,3})[\s\S]+?Users\s+(\w+)(?{$h->{"$2\@$1"}++})/mg);END{print $_ for keys %$h}'

 

 參考資料:

http://www.megalinux.net/using-tcpdump-for-mysql-query-logging/

http://www.xfocus.net/articles/200105/172.html

http://www.mysqlperformanceblog.com/2008/11/07/poor-mans-query-logging/

http://www.percona.com/doc/percona-toolkit/2.2/pt-query-digest.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM