我有一個mod_perl2.0.4/Apache2.2網絡應用程序運行在CentOS 6.4與PostgreSQL 9.0。SET SESSION AUTHORIZATION安全設計多用戶mod-perl2連接緩存
直到最近,我還有this setup:Apache :: DBI和DBI-> connect_cached用於所有連接,即使在我唯一的用戶開發區域,它也開始給予FATAL: sorry, too many clients already
。
爲了調試這個,我已經刪除了所有對Apache :: DBI的引用,升級到最新的DBI,並用普通的DBI-> connect替換了所有出現的connect_cached。在我看來,現在有點少的連接,然後離開<IDLE>
。但是,我意識到我沒有在我的所有語句句柄上調用disconnect(),因爲它聽起來像在Apache :: DBI下,它沒有任何區別。
我的連接當前連接所有用戶爲同一用戶,然後通過SET SESSION AUTHORIZATION降低他們的權限。我這樣做是因爲其他一些使用數據庫的應用程序允許使用密碼登錄,它可以將憑證直接傳遞到數據庫,但是這個特定的Web應用程序使用榮譽系統登錄屏幕,只需點擊您的名字即可登錄。所以這是未來的安全準備,但目前是方便的。另外,數據庫觸發歷史記錄等依賴會話用戶正確設置以跟蹤誰做了什麼。
由於我擔心數據庫句柄會被錯誤的會話用戶重複使用,因此我將{ private_user_login => $login_role_name, PrintError => 0, RaiseError => 1, AutoCommit => 1}
傳遞給connect_cached以區分用戶的每個連接。但是由於我總是在連接之後立即設置會話授權,所以我認爲所有的private_user_login
哈希值都是這樣的:對於給定的Apache進程,至少可以創建儘可能多的數據庫連接,並保留空閒,因爲有用戶,如果最終每個用戶都會隨機使用一個給定的Apache進程。同時,由於我沒有斷開任何手柄,它們最終會耗盡。
我的問題是,取出private_user_login
是否安全,以使所有連接句柄看起來相同,減少打開的連接數量,還是可以重新使用連接句柄在一個腳本的中間(在設置會話用戶之後)由不同的用戶創建競爭條件?此外,雖然Apache :: DBI的文檔說我不需要刪除disconnect()
調用,我應該在每個腳本的末尾仍然有這樣的調用,以便Apache :: DBI可以決定是否斷開連接?
換句話說,沒有我的私有連接變量,當下一個Apache :: DBI-> connect()重用現有連接時,SET SESSION AUTHORIZATION的效果會持續嗎?如果是這樣,有可能連接被另一個請求重新使用,而一個請求當前正在執行,但目前沒有使用數據庫句柄?
謝謝,我考慮過這個,但我也讀過另一個SO線程,PgBouncer更多的是一個權宜之計。我試圖找到設計問題的根源,因爲我想我一定誤解了一些東西,以便首先解決這個問題。另外我更喜歡一個解決方案,它修復了我的代碼,而不是另一個應用程序依賴項。 – Kev
雖然,這是否會解決Apache :: DBI文檔中描述的限制,「它將數據庫連接保持在每個進程的基礎上」?也就是說,PgBouncer會這樣做,以便通過兩個不同的Apache進程連接到數據庫的*相同用戶*最終將使用由PgBouncer管理的相同數據庫連接? (在這種情況下,我會考慮PgBouncer的初始設計而不是權宜之計,這是否意味着PgBouncer僅與PostgreSQL核心分離,因爲這適用於Web服務器環境,但不適用於桌面環境? – Kev
@Kev不,它贏得了'噸,但基本上什麼都不會。如果你需要的話,你可能需要重新考慮你的應用程序,因爲幾乎沒有任何東西可以在你想要的地方做到。 –