現象:
程式啟動後正常執行,使用prstat -p 看到內存在逐步增加。使用tail -f 看到不停的有log輸出。突然在log列印一條sql被送往db server以後,程式似乎停下來了。沒有報錯,沒有core dump。
診斷:
程式pid=6208。要求mit做pfile,pstack,pflags。xuxu幫助我將現場儲存到/var/tmp下
-rw-r–r– 1 root other 1788 jul 18 02:31 /var/tmp/pfiles.6208
-rw-r–r– 1 root other 668 jul 18 02:31 /var/tmp/pflags.6208
-rw-r–r– 1 root other 759 jul 18 02:31 /var/tmp/prstat.6208
-rw-r–r– 1 root other 4222 jul 18 02:30 /var/tmp/pstack.6208
pd雖然沒有root許可權,但是prstat -p還是可以用的
bash-2.03$ cat prstat.6208
pid username size rss state pri nice time cpu process/lwpid
6208 user 633m 614m sleep 59 -20 0:00.00 0.0% scrubber/5
6208 user 633m 614m sleep 59 -20 0:00.00 0.0% scrubber/10
……(此處我省略了…)
可以發現:
記憶體size和駐留記憶體rss穩定在乙個固定的值上面,沒有變化–>程式沒有在進行記憶體分配和釋放程式狀態一直處於sleep,cpu=0.0%,程式似乎什麼事都不在幹程式並沒有退出,沒有類似seg fault– exit之類的資訊顯示–>程式正在正常執行。
bash-2.03$ cat pflags.6208
6208: …(此處省略)
/1: flags = pr_pcinval|pr_asleep [ accept(0x5,0xfd109a28,0xfd109a20,0x1) ]
/2: flags = pr_pcinval|pr_aslwp|pr_asleep [ signotifywait() ]
/3: flags = pr_pcinval|pr_asleep [ read(0xd,0x22738716,0x2010) ]
/5: flags = pr_pcinval|pr_asleep [ lwp_sema_wait(0xfd20be60) ]
/8: flags = pr_pcinval|pr_asleep [ lwp_cond_wait(0xfe1d34f0,0xfe1d3500,0xfe1ccd88) ]
/9: flags = pr_pcinval|pr_asleep [ lwp_cond_wait(0xfe1ccd30,0xfe1ccd18,0x0) ]
sigmask = 0xffbffeff,0x00001fff
/10: flags = pr_pcinval|pr_asleep [ door(0x0,0x0,0x0,0x0,0xfc60bd38,0x4) ]
所有執行緒處於sleep狀態,注意到read操作正在i/o等待。lwp號碼是3,於是檢視pstack找出對應的thread call stack:
—————– lwp# 3 / thread# 1 ——————–
fe29ecc0 read (d, 22738716, 2010)
…(具體的呼叫棧我就不在這裡貼出來了,但是這裡的call stack已經能夠幫助pd方便的定位程式源**了,可以用gc++filt進行unmangle便於閱讀), 於是基本肯定是在db read的時候發生i/o等待。這一點也和我們從log中看到的資訊符合。xuxu接著幫我確認了這一點。
在進行oracle db鏈結的時候,應用程式需要知道鏈結資訊,其中包括oracle db的vip name和port。於是我們檢視pfiles. 假設埠號是2000。資料庫伺服器的名字是arrowpigdb.vip.com
bash-2.03$ cat pfiles.6208 | grep 2000
peername: af_inet 11.11.11.11 port: 2000 (此處的ip和埠是我杜撰的,但是不影響理解)
peername: af_inet 11.12.12.12 port: 2000
bash-2.03$ /usr/sbin/nslookup 11.12.12.12
server: –>此處顯示dns伺服器的名字
address: –>此處顯示dns伺服器的ip
name: arrowpigdb.vip.com –>說明應用程式到db的鏈結已經正確建立,i/o等待發生在db server一側。由此可確定是sql執行速度太慢。
address: 11.12.12.12
解決:
該程式確實使用了一條新的sql,雖然我覺得sql的改動很小,只是改動了where:原來的where是:
last_modified between :start_time and :end_time order by last_modified
現在改為:
last_modified=:start_time and item_id>:last_id order by item_id
oracle可以方便的找到應用程式發往db的sql. 然後檢視執行計畫:
sql>explain plan for
select ……. 《此處我省略具體的sql>
explained.
sql>@?/rdbms/admin/utlxpls
plan_table_output
… 《此處我省略具體的執行計畫》
初步結果是在做db join的時候,有一張130gb的表,原來的訪問是使用table range scan,而新的sql卻使用table access full。於是我發了乙個db review ticket讓dba幫我看怎麼解決,是不是需要新增hint,是不是需要**改動。等這個ticket resolve以後,我爭取能夠理解dba的tuning技術,然後補一下關於這個sql tuning的文章。
C 如何判斷檔案處於開啟狀態
對於應用程式,有時候可能需要判斷某個檔案是否已經被開啟,也就是指是否被某個流連接著。這在對檔案的讀寫比較頻繁的程式中尤為重要,因為乙個檔案同一時刻只能有乙個流連線的。下面的 也許能有所幫助。csharp view plain copy print?public class filestatus in...
c 程式如何判斷自身已經混淆
乙個project是用的c 寫的。以前也想用c 但c 有乙個缺點,就是它執行時需要.net framework的支援。這將給我們軟體的部署增加困難。這次寫的乙個服務程式,很自然就選擇了c 了。因為不要考慮眾多使用者端安裝 net framework,只要給伺服器安裝 net 就行了。使用的時候發現還...
如何讓Qt 的程式等待一段時間1
qtime t t.start while t.elapsed 1000 不停地處理事件,以使得程式保持響應。qthread sleep 1 在while 1 死迴圈裡加上這個,cpu沒空去幹其他的事情,在多程序的情況下會影響其他程式的啟動 響應速度測試的乙個小例子 class widget pub...