

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 對 MySQL 僅供讀取複本問題進行故障診斷
<a name="USER_ReadRepl.Troubleshooting"></a>

使用 MySQL DB 時，僅供讀取複本偶爾會出現複寫錯誤，或僅供讀取複本和來源資料庫執行個體間出現資料不一致的情況 (或兩者同時發生)。若您在僅供讀取複本或來源資料庫執行個體失敗的期間，沒有清空部分二進位日誌 (binlog) 事件或 InnoDB 重做日誌，就會出現上述問題。在這種情況下，手動刪除並重新建立僅供讀取複本。如果要降低此情況發生的機率，則可設定以下參數值：`sync_binlog=1` 和 `innodb_flush_log_at_trx_commit=1`。但這些設定可能會降低效能，所以請先測試這些設定所帶來的影響，再於生產環境中實作變更內容。

**警告**  
在與來源資料庫執行個體相關聯的參數群組中，建議保留以下參數值：`sync_binlog=1` 和 `innodb_flush_log_at_trx_commit=1`。這些參數是動態參數。如果您不想使用這些設定，建議在對來源資料庫執行個體執行任何可能導致重新啟動的操作之前，暫時設定這些值。這些操作包括但不限於重新啟動、透過容錯移轉重新啟動、升級資料庫版本，以及變更資料庫執行個體類或其儲存體。這些建議同樣適用於為來源資料庫執行個體建立新的僅供讀取複本時。  
若未遵循此指南的說明操作，會增加僅供讀取複本出現複寫錯誤，或僅供讀取複本和來源資料庫執行個體間出現資料不一致的情況 (或兩者同時發生) 的風險。

MySQL 採用非同步複寫技術，因此，來源資料庫執行個體的 `BinLogDiskUsage` 和僅供讀取複本上的 `ReplicaLag` 預料會偶爾增加。例如，來源資料庫執行個體可同時出現大量寫入操作。相對而言，僅供讀取複本的寫入操作則使用單一輸入/輸出執行緒序列化，這可能導致來源執行個體和僅供讀取複本之間的延遲。如需唯讀複本的詳細資訊，請參閱 MySQL 文件中的[複寫實作詳細資訊](https://dev.mysql.com/doc/refman/8.0/en/replication-implementation-details.html)。

您可執行下列動作，減少來源資料庫執行個體的更新與僅供讀取複本的後續更新間的延遲：
+ 將僅供讀取複本的儲存體大小和資料庫執行個體類別大小，設定為等同於來源資料庫執行個體。
+ 確保來源資料庫執行個體和僅供讀取複本所使用之資料庫參數群組中的參數設定相容。如需詳細資訊和範例，請參閱本節稍後討論的 `max_allowed_packet` 參數。

Amazon RDS 會監控複寫您的僅供讀取複本的狀態，並在複寫因任何原因停止時，將僅供讀取複本執行個體上的 `Replication State` (複寫狀態) 欄位更新為 `Error` (錯誤)。一個可能的範例為，僅供讀取複本上執行的 DML 查詢，與來源資料庫執行個體的更新相衝突。

您可以檢視 `Replication Error` 欄位，藉此檢閱 MySQL 引擎擲出的相關聯錯誤詳細資訊。也會產生指出僅供讀取複本之狀態的事件，包括 [RDS-EVENT-0045](USER_Events.Messages.md#RDS-EVENT-0045)、[RDS-EVENT-0046](USER_Events.Messages.md#RDS-EVENT-0046) 和 [RDS-EVENT-0047](USER_Events.Messages.md#RDS-EVENT-0047)。如需事件和訂閱事件的詳細資訊，請參閱[使用 Amazon RDS 事件通知](USER_Events.md)。如果傳回 MySQL 錯誤訊息，請在 [MySQL 錯誤訊息文件](https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html)中檢閱錯誤號碼。

其中一個常見問題就是僅供讀取複本的 `max_allowed_packet` 參數值小於來源資料庫執行個體的 `max_allowed_packet` 參數值，因而導致複寫錯誤。`max_allowed_packet` 參數是您可以在資料庫參數群組中設定的自訂參數。您可以使用 `max_allowed_packet` 以指定可以在資料庫上執行的 DML 程式碼的大小上限。在部分案例中，與僅供讀取複本建立關聯之資料庫參數群組中的 `max_allowed_packet` 值，會小於與來源資料庫執行個體建立關聯之資料庫參數群組中的 `max_allowed_packet` 值。在這些情況下，複寫程序可能會擲回錯誤 `Packet bigger than 'max_allowed_packet' bytes` 並停止複寫。若要修正錯誤，可讓來源資料庫執行個體和僅供讀取複本使用具有相同 `max_allowed_packet` 參數值的資料庫參數群組。

可能造成複寫錯誤的其他常見情況包括下列：
+ 寫入僅供讀取複本上的資料表。在某些情況下，您可能會在僅供讀取複本上建立與來源資料庫執行個體索引不同的索引。如果您這樣做，請將 `read_only` 參數設定為 `0` 以建立索引。當寫入僅供讀取複本上的資料表時，若僅供讀取複本與來源資料庫執行個體變得不相容，則複寫可能會中斷。在僅供讀取複本上執行維護作業後，建議您將 `read_only` 參數設回 `1`。
+  使用非交易儲存引擎 (例如 MyISAM)。僅供讀取複本需要交易儲存引擎。複寫功能僅支援 MySQL 上的 InnoDB 儲存引擎。
+  使用不安全的非確定性查詢 (例如 `SYSDATE()`)。如需詳細資訊，請參閱[二進位日誌中安全和不安全陳述式的判定](https://dev.mysql.com/doc/refman/8.0/en/replication-rbr-safe-unsafe.html)。

若您認為能夠安全略過錯誤，請遵循[略過 RDS for MySQL 目前的複寫錯誤](Appendix.MySQL.CommonDBATasks.SkipError.md)中所述的步驟。否則，您可以先刪除僅供讀取複本。您可以使用的相同資料庫執行個體識別符建立執行個體，使得端點可與您的舊僅供讀取複本端點保持相同。如果複寫錯誤已修復，`Replication State` (複寫狀態) 會變更為 *replicating (複寫中)*。