我想知道為什麼當 Amazon Aurora MySQL 相容版資料庫叢集容錯移轉時,會收到唯讀錯誤。
簡短描述
當 Aurora MySQL 相容資料庫叢集遇到多可用區容錯移轉時,叢集端點會自動更新。舊寫入器重新啟動並設定為唯讀模式,然後 Aurora 將現有複本提升為寫入器。端點反映了這項變更,並指向新的寫入器和讀取器角色。
當您使用讀者角色透過現有節點執行下列其中一項作業時,可能會收到唯讀錯誤訊息:
- 資料定義語言 (DDL) 作業
- 資料操作語言 (DML) 作業
- 資料控制語言 (DCL) 作業
解決方法
確定角色是否為唯讀
若要檢查角色是否為唯讀,請使用 innodb_read_only 變數。
輸出範例:
mysql> show variables where variable_name='innodb_read_only';+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_read_only | ON |
+------------------+-------+
1 row in set (0.01 sec)
使用集群寫入器端點
Aurora MySQL 叢集中的資料庫執行個體的角色可以改變。最佳做法是使用叢集寫入器端點,確保永遠指向最新的寫入器。如果您使用資料庫執行個體端點或直接 IP 位址,那麼您可能不知道是否發生了容錯移轉。當您重新連線到相同主機時,您會收到唯讀錯誤,並且無法執行 DDL 或 DML 變更。
不要過度快取 DNS
如果您沒有使用智慧型驅動程式,則在容錯移轉事件發生後,您會依賴 DNS 記錄更新和傳播。Aurora MySQL DNS 區域使用 5 秒的短存留時間 (TTL)。您的網路和用戶端組態不得增加 TTL。DNS 快取發生在架構的多個層級,例如作業系統 (OS)、網路層或應用程式容器。如果未預期的 DNS 快取超過 5 秒,那麼您可能會在容錯移轉後重新連線到舊的編寫器。
Java 虛擬機器 (JVM) 可以過度快取 DNS。當 JVM 將主機名稱解析為 IP 地址時,它會在一段指定的時間內快取 IP 地址。在某些組態中,JVM 預設 TTL 僅在 JVM 重新啟動時才重新整理 DNS 項目,並可能在容錯移轉後導致唯讀錯誤。若要解決此問題,請手動設定一個較小的 TTL,以便 DNS 項目定期重新整理。
使用 AWS Advanced JDBC 驅動器
Aurora MySQL DB 叢集端點自動傳播 DNS 記錄更新。當資料庫上發生事件時,您可能會遇到 DNS 記錄更新延遲。當發生這種情況時,應用程式會處理該事件。
AWS Advanced JDBC (Java 資料庫連線) Wrapper 驅動器會透過 INFORMATION_SCHEMA.REPLICA_HOST_STATUS 中繼資料表,使用資料庫叢集的拓撲。由於該資料表近乎即時,AWS Advanced JDBC Wrapper 驅動器會將連線路由到適當的角色。它還可在現有複本之間實現負載平衡。使用 Java 中的 Proxy 模式來實作 AWS Advanced JDBC Wrapper。您必須新增原生 Aurora MySQL 驅動器作為相依性。如需詳細資訊,請參閱 Baeldung 網站上的 Java 中的 Proxy 模式。您可以在 GitHub 網站上下載 AWS Advanced JDBC Wrapper。
如需詳細資訊,請參閱升級 Amazon RDS Multi-AZ 資料庫叢集時,使用 Advanced JDBC Wrapper 驅動器達到一秒或更短的停機時間。
**注意:**過多的 DNS 快取可能會影響 AWS Advanced JDBC Wrapper 驅動器。如需詳細資訊,請參閱提高 Amazon Aurora 上的應用程式可用性。
測試您連線的執行個體
如果您未使用智慧驅動器,請在建立新連線後測試執行個體。若要測試您是否已連線到寫入器執行個體,請使用 @@innodb_read_only 變數。如果您收到的值為 0,則表示您已連線到寫入器。
輸出範例:
mysql> select @@innodb_read_only;+--------------------+
| @@innodb_read_only |
+--------------------+
| 0 |
+--------------------+
1 row in set (0.00 sec)
相關資訊
Amazon Aurora MySQL 資料庫管理員手冊
Amazon Aurora 端點連線