[20140212]linux下使用tcpdump抓取sql語句

lfree發表於2014-02-13

[20140212]linu下使用tcpdump抓取sql語句.txt

我們生產系統問題多多,經常要跟蹤使用者執行的sql語句,當出現問題時要跟蹤比較麻煩,我需要一個快捷的方式"看到"使用者執行的sql語
句,想到了tcpdump抓包軟體。

我測試建立shell指令碼如下:

#! /bin/bash
/usr/sbin/tcpdump -l -i eth0 -s 16384 -A -nn src host $1 and dst port 1521

--說明:
-- -l     Make stdout line buffered.  Useful if you want to see the data while capturing it.  E.g.,
          ''tcpdump  -l  |  tee dat'' or ''tcpdump  -l   > dat  &  tail  -f  dat''.
--這樣可以立即看到包。不然要等待快取,可能漏掉一些sql語句。
-- -i     指網路介面。
-- -s     抓包長度,這個設定多少我還真不知道,我亂寫為16384
-- -A     Print each packet (minus its link level header) in ASCII.  Handy for capturing web pages.

--- 執行很簡單,引數使用ip地址就ok了。

Tcpdumpsql ip_address

很明顯抓取的東西有一些亂。雖然sql語句也在裡面,但是顯示太亂了。想到了一些過濾命令grep等等。但是如果sql語句太長,這樣也不
是很好。我開始google看看是否有人寫一些相似的命令,輸入tcpdump oracle

他使用tcpdump抓取oracle錯誤。在其網站檢索發現:

這個正是我需要的。

按照以上指令碼修改如下:

# cat /usr/local/bin/Tcpdumpsql
#! /bin/bash
/usr/sbin/tcpdump -l -i eth0 -s 16384 -A -nn src host $1 and dst port 1521 |  sed  -u -e  "s/^\.*//;s/\.*$//" | \
awk '{if (tolower($0) ~ "select" || tolower($0) ~ "update" ||  tolower($0) ~ "delete") {p=1;print} \
else if(p == 1 && $0 !~ "^[0-9][0-9]:") {print} else if ($0 ~ "^[0-9][0-9]:") {p=0}}'

--前面的. 實際上前面含有^M。修改如下ok了。

#! /bin/bash
/usr/sbin/tcpdump  -l -i eth0 -s 16384 -A -nn src host $1 and dst port 1521 2>/dev/null | sed -u -e  "s/^M/!/g;s/^E\.\..\{1,100\}//;s/\.*$//;s/^\.*//" | \
awk '{if (tolower($0) ~ "select" || tolower($0) ~ "update" ||  tolower($0) ~ "delete" || tolower($0) ~ "insert" ) {p=1;print} \
else if(p == 1 && $0 !~ "^[0-9][0-9]:") {print} else if ($0 ~ "^[0-9][0-9]:") {p=0}}'

--^M 輸入要ctrl+v ctrl+m.

順便測試alter session set cursor_sharing=force ;轉換成繫結在那裡發生:

alter session set cursor_sharing=force ;
select * from dept where deptno= 30;

擷取sql如下:
#select * from dept where deptno= 30

--保持原樣,可見轉換在伺服器端完成。

前面的#實際上sql語句的長度指示器。

select dump('#') from dual ;
DUMP('#')
-------------------
Typ=96 Len=1: 35

select length('select * from dept where deptno= 30') from dual ;
LENGTH('SELECT*FROMDEPTWHEREDEPTNO=30')
---------------------------------------
                                     35
--sql語句長度35,正好合適。

如果很長FF+sql語句+FF+sql語句+剩下長度+sql語句,這樣擷取的可能有不需要的字元。不過僅僅拿來看個大概,基本沒有問題。還有一些前面可能出現\n,這樣轉換可能存在一些問題,
總體滿足自己的需要。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-1080698/,如需轉載,請註明出處,否則將追究法律責任。

相關文章