我的應用程序連接到兩個故障切換集羣MySQL 5.6(實際上,Amazon Aurora)實例。主動節點始終是可寫入訪問的,而被動節點則以read_only
模式運行(與典型的MySQL故障切換集羣不同,默認情況下所有從屬節點都可寫入訪問)。 Amazon RDS提供了一個符號DNS名稱,該名稱始終指向活動的MySQL節點的IP地址。從連接池到集羣中的只讀節點的連接
在故障切換過程中,以前的主設備以read_only
模式重新啓動,而前一個被動節點變爲可寫訪問並被提升爲主設備。此外,DNS記錄已更改,以便羣集的DNS名稱現在指向新的主節點。
即使我完全禁用Java端的DNS緩存(通過sun.net.inetaddr.ttl
或networkaddress.cache.ttl
),特定於操作系統的DNS緩存仍然有效,因此在數據庫故障切換後,我最終將我的DBCP池連接到讀取只有MySQL實例。這些連接是valid
,即。即他們已經獲得之後故障轉移完成,但之前 DNS緩存過期。此外,這些連接都沒有設置標誌,所以我不能告訴我是否正在與只讀實例通話,直到我執行一些DML,這是當ER_OPTION_PREVENTS_STATEMENT
所有的榮耀。即使我通過調用setReadOnly(false)
並設置readOnlyPropagatesToServer
標誌明確地建立了讀寫模式的連接,但這隻會導致驅動程序向服務器發送SET SESSION TRANSACTION READ WRITE
,而不會導致拋出任何異常。
我想用盡可能少的應用程序邏輯來解決這個問題。如果有辦法將只讀實例的連接視爲無效/關閉連接(即,將其從池中逐出),則可以實現此目的。
我可以有一個validation query如SHOW GLOBAL VARIABLES LIKE 'read_only'
與一個額外的邏輯綁在一起嗎?是否有可能影響池的行爲w.r.連接基於驗證查詢返回的標量值?
'select @@ read_only as col1;' – Drew
@Drew是的,這與'SHOW GLOBAL VARIABLES LIKE'read_only''有相同的效果,但是如果'read_only'強制池驅逐連接,是'開'? – Bass