2010-07-01 14 views
0

我根據答案重寫了以下內容。如何找到哪些代碼正在消耗我的SQL Server連接池?

我有一個網站導致數據庫服務器上的高CPU問題到服務器變得不可用的地步。回收應用程序池可解決問題。根據服務器管理員http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en顯示,有一些線程活動大約一個小時。

與數據庫的交互非常簡單,並且在我們將Web表單路由添加到應用程序之前工作。

它們在整個應用程序中只包含類似這樣的代碼。 是的,這個代碼並不完美,但它不是這個代碼,這是我們添加路由之前的問題,沒有問題。

private string GetPublishedParagraphs() 
    { 
    string query, paragraphs = ""; 
    try 
    { 

     m_sql_connection = new SqlConnection(m_base_page.ConnectionString()); 
     query = "select * from PublishedParagraphs where IDDataContent_page='" + m_IDDataContent_page + "'"; 

     SqlDataAdapter da = new SqlDataAdapter(query, m_sql_connection); 
     DataSet ds = new DataSet(); 
     da.Fill(ds, "paragraph"); 

     if (ds.Tables["paragraph"].Rows.Count > 0) 
     paragraphs = (string)ds.Tables["paragraph"].Rows[0]["paragraphs"]; 

     ds.Dispose(); 
    da.Dispose(); 
    } 
    finally 
    { 
    m_sql_connection.Close(); 
    } 

    paragraphs = paragraphs.Replace("™", "™"); 

    return paragraphs; 
} 

連接字符串的樣子:

server_name; User ID=server_user; Password=server_password 

我們爲你精心檢查,要打開數據庫,每次調用()之後是關閉()。 我們測量有通過觀察他們,因爲我們在本地運行應用程序和連接數不增加通過沒有打開的連接:

SELECT SPID, 
     STATUS, 
     PROGRAM_NAME, 
     LOGINAME=RTRIM(LOGINAME), 
     HOSTNAME, 
     CMD 
FROM MASTER.DBO.SYSPROCESSES 
WHERE DB_NAME(DBID) = 'TEST' AND DBID != 0 

(但是,如果我們不這樣做的密切聯繫,有泄漏)

我們的應用程序與它工作時的區別在於通過web表單添加了asp.net路由。這也會調用數據庫,但在打開連接後再次關閉連接。

我們不確定還有什麼我們可以檢查的。 任何想法其他程序員?

ANSWER

我們通過查詢探查中發現的問題。這向我們展示了一個使用率很高的查詢。將查詢追溯回代碼顯示一遍又一遍地調用數據庫的無限循環。很難找到這個循環是由一個殭屍程序調用網頁上不再存在的頁面啓動的。

+0

真的是UYJ788hh2NN您的密碼到數據庫? – 2010-07-01 01:27:38

+0

不,它是一個虛擬的,只是想知道連接字符串本身是否有問題 – Petras 2010-07-01 01:50:37

回答

1
  • 在你顯示的代碼中,ds和da .Dispose放在finally塊中。更好的是,使用確保對象處理的使用(){}結構

  • 構建您自己的字符串作爲查詢的模式不僅僅是一個漏洞百出的安全漏洞,它也非常低效。改用存儲過程和參數。

  • 對進程的查詢過於嚴格。如果您有資源問題導致連接被拒絕,它不會被限制爲單個數據庫。關於我要限制的唯一的事情就是當前的命令 - > spid!= @@ spid

  • REALLY需要一些錯誤消息和上下文 - 它們在哪裏被看到?告訴我們更多,我們可以幫助!

祝你好運!


  • 首先,偉大的附加信息!感謝您的跟進。

  • 我會建議如果您確信您發佈的代碼與您從問題中刪除它的問題無關。但是,這些問題不僅僅是「不完美」的問題。正確處置內存密集型對象 - 初始開發人員認爲足夠密集以包含dispose()方法 - 與數據庫交互的那些對象 - 在數據庫存在不明原因問題的同時,這不是一個小問題,反正我認爲。

  • 我做了一些Google搜索,發現this。雖然我不會說這是問題,但它確實讓我思考。當「活動大約一個小時的線程」,是在db服務器上還是在Web服務器上測得的?我對這個工具不熟悉,但是你能夠從這個工具發佈日誌嗎?

  • 在網絡服務器上,您能夠監視路由代碼的操作嗎?路由代碼是以寫入/設置的方式防止無限循環 - 請參閱問題和答案here text

  • 在我的回答的早期版本中,我告訴過你,只查看特定數據庫的@連接對於你的任務來說太嚴格了。對您的問題的澄清並不表明您已更正此查詢。我建議:

 

    SELECT 
     is_being_blocked = sp.blocked 
     , sp.cpu 
     , DB_NAME (dbid) 
     , sp.status 
     , LOGINAME=RTRIM(sp.LOGINAME) 
     , sp.HOSTNAME 
     , sp.Hostprocess 
     , sp.CMD 
    FROM SYSPROCESSES sp 
    WHERE spid != @@SPID 
    ORDER BY 
     sp.blocked ASC 
     , sp.cpu DESC 
 
  • 日誌 - 什麼是在SQL Server日誌中的時間跨度說前10分鐘和10分鐘就重新啓動Web應用程序後?

  • 你有沒有試過,這個問題是否可以在開發中重複使用?

  • 請告訴我們下面的語句在應用程序方面是指 - 錯誤信息或其他:「服務器不可用」

  • 我強烈建議你啓動SQL Server的痕跡使用Profiler。根據你在這個問題中說的話,這就是我將跟蹤保存到表(在另一個sql服務器上)或保存到文件(在另一臺機器上不是sql服務器框)的內容。這一痕跡是爲了找出嚴重阻礙生產的問題。這不是你想要定期運行的東西。

我會捕獲這些事件

* Errors and Warnings - all of them 
* Security Audit 
** Audit Login 
** Audit Logout 
* Sessions 
** Existing Sessions 
* TSQL 
** SQL: Stmt Starting 
** SQL: Stmt Completed 
** Prepare SQL 
** Exec Prepared SQL 

我不會使用預設值以外的任何過濾器。

0

你是什麼意思「用完應用程序池?」你的意思是連接池?

如果您的數據庫似乎正在過度勞累,也可能是因爲用戶對您的m_IDDataContent_page變量進行了自由統治。此數據訪問代碼易受sql注入攻擊。

1

您是否嘗試過在SQL Server Management Studio中運行「sp_who2」查詢以查看有多少個活動數據庫連接,因爲代碼看起來不錯。

您可能想要將m_sql_connection變量的範圍從類範圍更改爲成員範圍。也許這可能是你的問題?