2012-09-11 9 views
3

我有一個在FreeBSD/Apache系統上運行的Perl腳本,它通過DBI對MySQL數據庫進行一些簡單的查詢。服務器相當活躍(每天有150k頁),每隔一段時間(一分鐘一次)都會導致進程掛起。我懷疑文件鎖定可能會阻止讀取,或者可能是SQL調用,但我一直無法弄清楚如何獲取關於掛起過程的信息。檢測Perl/MySQL中掛起的進程(FreeBSD)

根據實際mod_perl它聽起來像識別操作給我頭痛的方式是系統跟蹤,perl跟蹤或交互式調試器。我收集系統跟蹤在FreeBSD的ktrace,但是當我連接到頂部在吊的過程之一,經過進程只能輸出被殺害的是:

50904 perl5.8.9 PSIG SIGTERM SIG_DFL 

那是不是對我很有幫助。任何人都可以提出一個更有意義的方法嗎?我不是非常先進的Unix管理員,所以你的耐心,如果我聽起來很愚蠢是非常讚賞....:o)

+1

我會嘗試添加一些信號處理和日誌開始。如果可以的話,它肯定會有助於啓用mysql日誌記錄,以便查看在鎖定時間戳之前/期間所做的操作 - 這可能會提供一些進一步的見解。你碰巧在使用線程嗎?任何你可以發佈的日誌信息都可能幫助任何潛在的SO用戶來幫助你。 對於信號處理總是有posix模塊 - http://perldoc.perl.org/POSIX.html#POSIX%3a%3aSigAction – AndrewPK

+1

最好的情況是,如果有人可以識別錯誤,但否則你必須開始記錄你的出路。我對日誌進行了後處理,以便每個請求將它們提煉爲一行,僅包含具有所需開始和結束狀態的主要狀態更改的描述。然後,您應該能夠找到沒有所需結束狀態的行,並使用上次記錄的狀態作爲提示,指出應該進行更多日誌記錄。 – mzedeler

回答

0

Ktracing只給你係統調用,信號I/O和namei處理。並且它非常快速地生成一批數據。因此,找出麻煩點可能並不理想。

如果您可以看到腳本的標準輸出,請在您的代碼中將一些有策略的打印語句放在可疑故障點周圍。然後運行該程序應該顯示您發生掛起:

print "Before query X" 
$dbh->do($statement) 
print "After query X". 

如果看不到標準輸出,可以使用例如perl模塊或調用FreeBSD的logger(1)程序將調試信息寫入日誌文件。將其封裝到debug()函數中並使用該函數或打印語句可能是最容易的。

編輯:如果你不想要很多磁盤上的日誌,寫日誌信息到一個插座(系統日誌::支持與setlogsock()),並另寫劇本從插座和轉儲閱讀將調試文本發送到終端,並以接收數據的時間作爲前綴。一旦程序掛起,你可以看到它在做什麼。

+0

很棒的回答。問題是腳本在鎖定一次之前會運行一百萬次,所以這將是大量的數據記錄,並且我認爲會在服務器上增加一些負載。鑑於鎖定極其罕見的侷限性,您如何建議我跟蹤鎖定而不會造成過多的服務器負載和大量誤報? –

+0

使用套接字將調試信息寫入。查看更新的答案。 –

0

如果我理解正確,那麼在查詢MySQL時,您的Perl進程會掛起,而這本身仍在運行。 MySQL服務器具有嵌入式故障排除功能,log_slow_queries選件。把以下幾行你my.cnf使絕招:

[mysqld] 
log_slow_queries = /var/log/mysql/mysql-slow.log 
long_query_time = 10 

之後,重新啓動或重新載入MySQL守護進程。讓我們一會兒服務器運行收集統計和分析這是怎麼回事:

mysqldumpslow -s at /var/log/mysql/mysql-slow.log | less 

在一臺服務器礦山,上面記錄的(-s at訂單由平均查詢時間,BTW)是:

Count: 286 Time=101.26s (28960s) Lock=14.74s (4214s) Rows=0.0 (0), iwatcher[iwatcher]@localhost 
    INSERT INTO `wp_posts` (`post_author`,`post_date`,`post_date_gmt`,`post_content`,`post_content_filtered`,`post_title`,`post_excerpt`,`post_status`,`post_type`,`comment_status`,`ping_status`,`post_password`,`post_name`,`to_ping`,`pinged`,`post_modified`,`post_modified_gmt`,`post_parent`,`menu_order`,`guid`) VALUES ('S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S','S') 

FWIW,它是一個WordPress超過30K的職位。

+0

我不認爲它是MySQL,因爲沒有腳本的那部分發生鎖定。我最終將服務器移到了使用fastcgi的Ubuntu/Nginx框。我必須重寫皮膚腳本,但罕見的鎖定似乎仍然發生。我有一個cron腳本,用於檢查鎖定的進程,然後重新啓動FCGI包裝器,這是一個非常糟糕的解決方案,但確保該包裝盒保持99.99%的運行時間。我嘗試一行一行的腳本,但沒有跳出。我的同事建議我將整個事情轉移到PHP,這說起來容易做起來難。 –

+0

FCGI包裝已知很難調整;事實上,我經歷過許多突然的鎖定。另一方面,Nginx對PSGI非常好。例如,您可以嘗試使用PSGI封裝您的CGI,例如https://metacpan.org/module/CGI::Emulate::PSGI。 – creaktive

+0

感謝creaktive,我會看看該模塊.... –