1

我的應用程序連接到兩個故障切換集羣MySQL 5.6(實際上,Amazon Aurora)實例。主動節點始終是可寫入訪問的,而被動節點則以read_only模式運行(與典型的MySQL故障切換集羣不同,默認情況下所有從屬節點都可寫入訪問)。 Amazon RDS提供了一個符號DNS名稱,該名稱始終指向活動的MySQL節點的IP地址。從連接池到集羣中的只讀節點的連接

在故障切換過程中,以前的主設備以read_only模式重新啓動,而前一個被動節點變爲可寫訪問並被提升爲主設備。此外,DNS記錄已更改,以便羣集的DNS名稱現在指向新的主節點。

即使我完全禁用Java端的DNS緩存(通過sun.net.inetaddr.ttlnetworkaddress.cache.ttl),特定於操作系統的DNS緩存仍然有效,因此在數據庫故障切換後,我最終將我的DBCP池連接到讀取只有MySQL實例。這些連接是valid,即。即他們已經獲得之後故障轉移完成,但之前 DNS緩存過期。此外,這些連接都沒有設置標誌,所以我不能告訴我是否正在與只讀實例通話,直到我執行一些DML,這是當ER_OPTION_PREVENTS_STATEMENT所有的榮耀。即使我通過調用setReadOnly(false)並設置readOnlyPropagatesToServer標誌明確地建立了讀寫模式的連接,但這隻會導致驅動程序向服務器發送SET SESSION TRANSACTION READ WRITE,而不會導致拋出任何異常。

我想用盡可能少的應用程序邏輯來解決這個問題。如果有辦法將只讀實例的連接視爲無效/關閉連接(即,將其從池中逐出),則可以實現此目的。

我可以有一個validation querySHOW GLOBAL VARIABLES LIKE 'read_only'與一個額外的邏輯綁在一起嗎?是否有可能影響池的行爲w.r.連接基於驗證查詢返回的標量值?

+1

'select @@ read_only as col1;' – Drew

+0

@Drew是的,這與'SHOW GLOBAL VARIABLES LIKE'read_only''有相同的效果,但是如果'read_only'強制池驅逐連接,是'開'? – Bass

回答

2

下列驗證查詢可用於:

select case when @@read_only = 0 then 1 else (select table_name from information_schema.tables) end as `1` 

如果數據庫在只讀模式下運行,查詢將

ERROR 1242 (21000): Subquery returns more than 1 row 

失敗,因爲亞馬遜極光innodb_read_only但而不是read_only在簇中的讀取器端點上,驗證查詢可以被重寫爲

select case when @@read_only + @@innodb_read_only = 0 then 1 else (select table_name from information_schema.tables) end as `1` 

this啓發答案。

相關問題