如何判斷程式處於I O等待

2021-05-24 01:40:58 字數 3341 閱讀 7420

現象:

程式啟動後正常執行,使用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...