2012-05-20 20 views
1

當壓力測試mod_perl數據庫連接消失時,我遇到了一個問題。我懷疑進程正在共享數據庫連接,導致該問題。使用mod_perl創建新的數據庫句柄

但我按照Apache :: DBI的所有說明,並不能解決這個問題。

我在子進程中進行連接,而不是在startup.pl中進行連接。但是當我檢查DBI-> connnect中每個子節點返回的$ dbh時,每個httpd進程的地址都是相同的。 首先,如果這是工作正常,併爲每個進程重新連接,DBI->連接返回的地址應該是不同的每個子進程?我假設如此,但據我所知,DBI中的核心C代碼(dbih_setup_handle)正在管理這個並且返回相同的地址。所以也許我不明白重新連接孩子意味着什麼。

我是否正確重新連接,如果$ dbh手柄是相同的?

+0

Cross發佈在http://www.perlmonks.com/?node_id=971450 – lschult2

回答

0

聽起來您正在啓動配置中的<perl>...</perl>部分或啓動時加載的模塊中建立數據庫連接,並保留它,直到分支進程嘗試使用它。

不幸的是,你不能逃避這一點。你需要以某種方式確保新的進程獲得新的連接。

我對這個問題的解決方案是獲取dbh的一個核心功能,該功能跟蹤當連接建立時$$(當前進程ID)是什麼。如果移交連接時,該功能發現$$發生了變化,它會處理任何現有連接的,但不關閉他們,並創建一個新:

my $_dbh; 
my $pid; 

sub dbh { 
     if($pid != $$) { 
       $_dbh = DBI->connect(...); 
       $pid = $$; 
     } 
     return $_dbh; 
} 

是想利用該數據庫將任意代碼首先調用dbh()來獲得一個數據庫句柄,並讓它在必要時創建一個新句柄,或者如果可以使用,則移交先前建立的連接。

+0

Michael,我沒有在startup.pl中建立任何連接以避免此問題。所有的連接都由孩子建立。但是當我檢查每個孩子的$ dbh的地址時,地址是相同的。但由於這些地址是相對於孩子的虛擬地址,因此可能會或可能不會意味着連接正在被共享。這是我想弄明白的。我如何確定連接不被共享? – lschult2

+3

如果分叉的子服務器處理的所有行爲都與其打開數據庫句柄的行爲相同,則它們將具有相同的地址,但這些地址位於單獨的進程內存空間中,因此這不是問題。 –

+0

所以這就回答了這個問題。即使$ dbh具有相同的地址,我也正確地做到了這一點。 ab壓力測試證實這並不是失敗。 (我不確定如何選擇Michael的評論作爲「答案」) – lschult2