在MySQL線上環境咱們通常只打開了binary log,slow log,有時咱們須要查看general log呢?由於該log記錄全部的請求,打開該日誌確定給磁盤形成很大壓力,IO能力有所降低,因此該日誌線上通常不打開的,這就到tcpdump閃亮登場了。html
tcpdump用法也不算複雜,輸出就比較複雜了,若是很是熟悉TCP/IP協議,那麼輸出對於你來講就是小kiss啦。咱們這裏只關心MySQL的Query,因此輸出仍是很是簡單,就是平常的查詢語句。mysql
1.安裝linux
通常系統都自帶了tcpdump命令,沒有該命令的採用以下方式安裝:sql
[root@yayun-mysql-server ~]# yum install tcpdump -y
2.簡單使用(shell結合perl過濾查詢)shell
[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=?
其實還有更簡單的方法,那就是使用tcpflowbash
安裝tcpflowtcp
[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