本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Amazon Aurora MySQL 的最佳實務
此主題包含有關使用資料或將資料遷移至 Amazon Aurora MySQL 資料庫叢集的最佳實務和選項的資訊。本主題中的資訊摘要說明並重申您可以在 管理 Amazon Aurora 資料庫叢集 中找到的部分指導方針和程序。
判斷您連接的資料庫執行個體
若要判斷連線所連接的是 Aurora MySQL 資料庫叢集中的哪個資料庫執行個體,請檢查 innodb_read_only
全域變數,如以下範例所示。
SHOW GLOBAL VARIABLES LIKE 'innodb_read_only';
如果您連線到讀取器資料庫執行個體,則 innodb_read_only
變數設定為 ON
。如果您連線至寫入器資料庫執行個體 (例如已佈建叢集中的主要執行個體),則此設定為 OFF
。
如果要將邏輯新增至您的應用程式碼,以平衡工作負載或確保寫入操作使用的是正確的連接,則此方法很實用。
Aurora MySQL 效能和擴展的最佳實務
您可以應用以下最佳實務,改善 Aurora MySQL 叢集的效能和可擴展性。
主題
使用 T 執行個體類別進行開發和測試
對於不支援需時較長的高工作負載應用程式,使用 db.t2
、db.t3
或 db.t4g
資料庫執行個體類別的 Amazon Aurora MySQL 執行個體是完美之選。T 執行個體旨在提供適度的基準效能和容量,可視您的工作負載需要大幅提升效能。它們適用非經常或持續使用整個 CPU,但偶爾需要高載的工作負載。建議您在開發、測試伺服器或其他非生產伺服器時,僅使用 T 資料庫執行個體類別。如需 T 執行個體類別的詳細資訊,請參閱爆量效能執行個體。
如果您的 Aurora 叢集大於 40 TB,請勿使用 T 執行個體類別。當您的資料庫有大量資料時,管理結構描述物件的記憶體額外負荷可能會超過 T 執行個體的容量。
請不要在 Amazon Aurora MySQL T 執行個體上啟用 MySQL Performance Schema (MySQL 效能結構描述)。如果已啟用 Performance Schema (效能結構描述),執行個體可能會用盡記憶體。
提示
若您的資料庫有時處於閒置狀態,但有時工作負載相當大,則可使用 Aurora Serverless v2 作為 T 執行個體的替代方案。利用 Aurora Serverless v2,您可定義容量範圍,Aurora 會根據目前的工作負載自動擴展或縮小資料庫。如需用量詳細資料,請參閱 使用 Aurora Serverless v2。若需可與 Aurora Serverless v2 搭配使用的資料庫引擎版本,請參閱 要求和限制 Aurora Serverless v2。
當您在 Aurora MySQL 資料庫叢集中,使用 T 執行個體作為資料庫執行個體時,我們建議下列作法:
-
在您的資料庫叢集中,所有執行個體請皆使用相同的資料庫執行個體類別。例如:如果您的寫入器執行個體使用
db.t2.medium
,則我們也建議讀取器執行個體使用db.t2.medium
。 -
請不要調整任何與記憶體相關的組態設定,例如
innodb_buffer_pool_size
。Aurora 可針對 T 執行個體上的記憶體緩衝區使用一組高度調整的預設值。Aurora 需要這些特殊的預設值,才能在記憶體受限的執行個體上執行。如果您在 T 實例上更改任何與內存相關的設置,則即使您的更改旨在增加緩衝區大小,也更有可能遇到 out-of-memory 條件。 -
監控您的 CPU 點數餘額 (
CPUCreditBalance
) 以確保它處於可永續使用的層級。也就是說,CPU 點數的累積速率與使用時速率相同。某個執行個體用盡 CPU 點數時,您會看到可用 CPU 立即下降,以及看到執行個體的讀寫延遲增加。此情況會造成執行個體整體效能嚴重降低。
如果您的 CPU 點數餘額未處於可永續使用的層級,建議您修改資料庫執行個體,以使用其中一個支援的 R 資料庫執行個體類別 (擴展運算)。
如需監控指標的詳細資訊,請參閱在 Amazon RDS 主控台中檢視指標。
-
監控寫入器執行個體與讀取器執行個體之間的複本延遲 (
AuroraReplicaLag
)。如果讀取器執行個體先於寫入器執行個體耗盡 CPU 點數,則產生的延遲可能會導致讀取器執行個體頻繁重新啟動。當應用程式分散在讀取器執行個體之間的讀取操作負載繁重,而同時寫入器執行個體有少量寫入操作時,此結果很常見。
如果您看到複本延遲持續增加,請確定資料庫叢集中讀取器執行個體的 CPU 點數餘額尚未用盡。
如果您的 CPU 點數餘額未處於可永續使用的層級,建議您修改資料庫執行個體,以使用其中一個支援的 R 資料庫執行個體類別 (擴展運算)。
-
針對已啟用二進位日誌的資料庫叢集,將每個交易的插入數保持在 100 萬個以下。
如果資料庫叢集的資料庫叢集參數群組的
binlog_format
參數設定為以外的值OFF
,則如果資料庫叢集接收到要插入超過 100 萬個資料列的交易,您的資料庫叢集可能會遇到 out-of-memory條件。您可以監控可釋放記憶體 (FreeableMemory
) 指標,以判斷資料庫叢集是否用盡可用的記憶體。然後可以檢查寫入操作 (VolumeWriteIOPS
) 指標,以查看寫入器執行個體接收的寫入器操作負載是否繁重。若是這種情況,建議更新您的應用程式,將一個交易中的插入數限制在 100 萬個以下。或者,您可以修改執行個體,以使用其中一個支援的 R 資料庫執行個體類別 (擴展運算)。
使用非同步索引鍵預先提取,將 Amazon Aurora MySQL 索引聯結查詢最佳化
Aurora MySQL 可以使用非同步索引鍵預先提取 (AKP) 功能來改善聯結索引間資料表之查詢的效能。在 JOIN 查詢要求使用批次索引鍵存取 (BKA) 聯結演算法和多範圍讀取 (MRR) 最佳化功能的情況下,透過預期執行查詢所需的資料列,此功能可藉此改善效能。如需 BKA 和 MRR 的詳細資訊,請參閱 MySQL 文件中的封鎖巢狀迴圈和批次索引鍵存取聯結
若要利用 AKP 功能,查詢必須同時使用 BKA 和 MRR。一般來說,當查詢的 JOIN 子句使用次要索引,但也需要來自主要索引的一些資料欄時,會發生這類查詢。例如,當 JOIN 子句代表小型外部資料表與大型內部資料表間索引值的對等聯結,並且較大資料表上的索引具有高度選擇性時,您可以使用 AKP。AKP 可與 BKA 和 MRR 共同合作,以在 JOIN 子句的評估期間執行次要至主要索引查詢。AKP 會識別在 JOIN 子句的評估期間執行查詢所需的資料列。然後使用背景執行緒,在執行查詢之前,將包含那些資料列的頁面非同步載入至記憶體。
AKP 適用於 Aurora MySQL 第 2.10 版以上及第 3 版。如需 Aurora MySQL 版本的詳細資訊,請參閱 Amazon Aurora MySQL 的資料庫引擎更新。
啟用非同步索引鍵預先提取
您可以透過將 MySQL 伺服器變數 aurora_use_key_prefetch
設定為 on
來啟用 AKP 功能。依預設,此值是設為 on
。不過,在您也啟用 BKA 聯結演算法並停用成本型 MRR 功能之前,無法啟用 AKP。若要這麼做,您必須設定 MySQL 伺服器變數 optimizer_switch
的下列值:
-
將
batched_key_access
設定為on
。此值可控制 BKA 聯結演算法的使用。依預設,此值是設為off
。 將
mrr_cost_based
設定為off
。此值可控制成本型 MRR 功能的使用。依預設,此值是設為on
。
目前,您只能在工作階段層級設定這些值。下列範例說明如何透過執行 SET 陳述式來設定這些值,來為目前的工作階段啟用 AKP。
mysql>
set @@session.aurora_use_key_prefetch=on;mysql>
set @@session.optimizer_switch='batched_key_access=on,mrr_cost_based=off';
相同地,您可以使用 SET 陳述式來停用 AKP 和 BKA 聯結演算法,以及為目前的工作階段重新啟用成本型 MRR 功能,如以下範例所示。
mysql>
set @@session.aurora_use_key_prefetch=off;mysql>
set @@session.optimizer_switch='batched_key_access=off,mrr_cost_based=on';
如需 batched_key_access 和 mrr_cost_based 最佳化器切換參數的詳細資訊,請參閱 MySQL 文件中的可切換的最佳化
非同步索引鍵預先提取的最佳化查詢
您可以確認查詢是否可利用 AKP 功能。若要這麼做,請使用 EXPLAIN
陳述式在執行查詢之前描繪查詢。EXPLAIN
陳述式提供要針對指定查詢使用之執行計劃的相關資訊。
在 EXPLAIN
陳述式的輸出中,Extra
資料欄說明執行計劃隨附的其他資訊。如果 AKP 功能適用於查詢中使用的資料表,此資料欄會包括以下其中一個值:
Using Key Prefetching
Using join buffer (Batched Key Access with Key Prefetching)
下列範例示範使用 EXPLAIN
來檢視可利用 AKP 之查詢的執行計劃。
mysql>
explain select sql_no_cache->
ps_partkey,->
sum(ps_supplycost * ps_availqty) as value->
from->
partsupp,->
supplier,->
nation->
where->
ps_suppkey = s_suppkey->
and s_nationkey = n_nationkey->
and n_name = 'ETHIOPIA'->
group by->
ps_partkey having->
sum(ps_supplycost * ps_availqty) > (->
select->
sum(ps_supplycost * ps_availqty) * 0.0000003333->
from->
partsupp,->
supplier,->
nation->
where->
ps_suppkey = s_suppkey->
and s_nationkey = n_nationkey->
and n_name = 'ETHIOPIA'->
)->
order by->
value desc;+----+-------------+----------+------+-----------------------+---------------+---------+----------------------------------+------+----------+-------------------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------+-----------------------+---------------+---------+----------------------------------+------+----------+-------------------------------------------------------------+ | 1 | PRIMARY | nation | ALL | PRIMARY | NULL | NULL | NULL | 25 | 100.00 | Using where; Using temporary; Using filesort | | 1 | PRIMARY | supplier | ref | PRIMARY,i_s_nationkey | i_s_nationkey | 5 | dbt3_scale_10.nation.n_nationkey | 2057 | 100.00 | Using index | | 1 | PRIMARY | partsupp | ref | i_ps_suppkey | i_ps_suppkey | 4 | dbt3_scale_10.supplier.s_suppkey | 42 | 100.00 | Using join buffer (Batched Key Access with Key Prefetching) | | 2 | SUBQUERY | nation | ALL | PRIMARY | NULL | NULL | NULL | 25 | 100.00 | Using where | | 2 | SUBQUERY | supplier | ref | PRIMARY,i_s_nationkey | i_s_nationkey | 5 | dbt3_scale_10.nation.n_nationkey | 2057 | 100.00 | Using index | | 2 | SUBQUERY | partsupp | ref | i_ps_suppkey | i_ps_suppkey | 4 | dbt3_scale_10.supplier.s_suppkey | 42 | 100.00 | Using join buffer (Batched Key Access with Key Prefetching) | +----+-------------+----------+------+-----------------------+---------------+---------+----------------------------------+------+----------+-------------------------------------------------------------+ 6 rows in set, 1 warning (0.00 sec)
如需 EXPLAIN
輸出格式的詳細資訊,請參閱 MySQL 文件中的延伸 EXPLAIN 輸出格式
使用雜湊聯結,將大型 Aurora MySQL 聯結查詢最佳化
需要使用對等聯結來聯結大量資料時,雜湊聯結可以改善查詢效能。您可以為 Aurora MySQL 啟用雜湊聯結。
雜湊聯結資料欄可以是任何複雜的表達式。在雜湊聯結資料欄中,您可以利用下列方式來比較各個資料類型:
-
您可以比較各類別的精確數值資料類型項目,例如
int
、bigint
、numeric
和bit
。 -
您可以比較各類別的近似數值資料類型項目,例如
float
和double
。 -
您可以比較各字串類型的項目,以得知字串類型是否有相同的字元集和定序。
-
您可以比較項目的日期和時間戳記資料類型,以得知類型是否相同。
注意
您無法在不同類別中比較資料類型。
下列限制適用 Aurora MySQL 的雜湊聯結:
-
Aurora MySQL 第 2 版不支援左右外部連接,但第 3 版支援。
-
不支援半聯結 (例如子查詢),除非先將子查詢具體化。
-
不支援多資料表更新或刪除。
注意
支援單一資料表更新或刪除。
-
BLOB 和空間資料類型資料欄不可為雜湊聯結中的聯結資料欄。
啟用雜湊聯結
若要啟用雜湊聯結:
-
Aurora MySQL 第 2 版 — 將資料庫參數或資料庫叢集參數
aurora_disable_hash_join
設為0
。若關閉aurora_disable_hash_join
,optimizer_switch
的值將為hash_join=on
。 -
Aurora MySQL 第 3 版 — 將 MySQL 伺服器參數
optimizer_switch
設為block_nested_loop=on
。
雜湊聯結在 Aurora MySQL 第 3 版中會預設開啟,在 Aurora MySQL 第 2 版則預設關閉。下列範例說明如何為 Aurora MySQL 第 3 版啟用雜湊聯結。您可以發出陳述式 select @@optimizer_switch
,以查看哪些其他設定存在於 SET
參數字串中。更新 optimizer_switch
參數中的某個設定不會清除或修改其他設定。
mysql>
SET optimizer_switch='block_nested_loop=on';
注意
對於 Aurora MySQL 第 3 版,雜湊聯結支援適用於所有次要版本,預設為開啟。
對於 Aurora MySQL 第 2 版,雜湊聯結支援適用於所有次要版本。在 Aurora MySQL 第 2 版中,雜湊聯結功能一律由 aurora_disable_hash_join
值控制。
利用此設定,最佳化器會根據成本、查詢特質和資源可用性選擇使用雜湊聯結。如果成本估算不正確,您可以強制最佳化器選擇某個雜湊聯結。您可以透過將 MySQL 伺服器變數 hash_join_cost_based
設定為 off
來執行此動作。下列範例說明如何強制最佳化器選擇雜湊聯結。
mysql>
SET optimizer_switch='hash_join_cost_based=off';
注意
此設定會覆寫成本類型最佳化工具的決策。雖然該設定對於測試和開發非常有用,但建議您不要在生產環境中使用它。
最佳化雜湊聯結的查詢
若要了解查詢是否可利用雜湊聯結,請先使用 EXPLAIN
陳述式來描繪查詢。EXPLAIN
陳述式提供要針對指定查詢使用之執行計劃的相關資訊。
在 EXPLAIN
陳述式的輸出中,Extra
資料欄說明執行計劃隨附的其他資訊。如果雜湊聯結適用於查詢中所用的資料表,此資料欄會包括類似以下的值:
Using where; Using join buffer (Hash Join Outer table
table1_name
)Using where; Using join buffer (Hash Join Inner table
table2_name
)
下列範例示範使用 EXPLAIN 來檢視雜湊聯結查詢的執行計劃。
mysql>
explain SELECT sql_no_cache * FROM hj_small, hj_big, hj_big2->
WHERE hj_small.col1 = hj_big.col1 and hj_big.col1=hj_big2.col1 ORDER BY 1;+----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------------------+ | 1 | SIMPLE | hj_small | ALL | NULL | NULL | NULL | NULL | 6 | Using temporary; Using filesort | | 1 | SIMPLE | hj_big | ALL | NULL | NULL | NULL | NULL | 10 | Using where; Using join buffer (Hash Join Outer table hj_big) | | 1 | SIMPLE | hj_big2 | ALL | NULL | NULL | NULL | NULL | 15 | Using where; Using join buffer (Hash Join Inner table hj_big2) | +----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------------------+ 3 rows in set (0.04 sec)
在輸出中,Hash Join Inner table
是用來建置雜湊資料表的資料表,而 Hash Join Outer table
是用來探測雜湊資料表的資料表。
如需延伸 EXPLAIN
輸出格式的詳細資訊,請參閱 MySQL 產品文件中的延伸 EXPLAIN 輸出格式
在 Aurora MySQL 2.08 及更高版本中,您可以使用 SQL 提示來影響查詢是否使用雜湊聯結,以及要使用哪些資料表來建置和聯結探測端。如需詳細資訊,請參閱 Aurora MySQL 提示。
使用 Amazon Aurora 為 MySQL 資料庫擴展讀取
您可以使用 Amazon Aurora 搭配 MySQL 資料庫執行個體來利用 Amazon Aurora 的讀取擴展功能,並為 MySQL 資料庫執行個體擴展讀取工作負載。若要使用 Aurora 來讀取擴展 MySQL 資料庫執行個體,請建立 Aurora MySQL 資料庫叢集,並讓它成為您 MySQL DB 執行個體的讀取複本。然後連線至 Aurora MySQL 叢集以處理讀取查詢。該來源資料庫可以是 RDS for MySQL 資料庫執行個體,也可以是在 Amazon RDS 外部執行的 MySQL 資料庫。如需詳細資訊,請參閱 使用 Amazon Aurora 為 MySQL 資料庫擴展讀取。
最佳化時間戳記操作
當系統變數 time_zone
的值設為 SYSTEM
時,每個需要時區計算的 MySQL 函數呼叫都會進行系統程式庫呼叫。當您執行以高並行方式傳回或變更這類 TIMESTAMP
值的 SQL 陳述式時,可能會遇到延遲、鎖定爭用和 CPU 使用率增加的情況。如需詳細資訊,請參閱 MySQL 文件中的 time_zone
若要避免此行為,建議您將 time_zone
資料庫叢集參數的值變更為 UTC
。如需詳細資訊,請參閱 修改資料庫叢集參數群組中的參數。
儘管 time_zone
參數是動態的 (不需要重新啟動資料庫伺服器),但新值僅用於新連線。若要確保所有連線都更新為使用新的 time_zone
值,建議您在更新資料庫叢集參數之後回收應用程式連線。
Aurora MySQL 高可用性的最佳實務
您可以應用以下最佳實務,改善 Aurora MySQL 叢集的可用性。
主題
使用 Amazon Aurora 搭配 MySQL 資料庫進行災難復原
您可以使用 Amazon Aurora 搭配 MySQL 資料庫執行個體來建立用於災難復原的離站備份。若要使用 Aurora 進行 MySQL 資料庫執行個體的災難復原,請建立 Amazon Aurora 資料庫叢集,並讓它成為 MySQL 資料庫執行個體的讀取複本。這可套用至 RDS for MySQL 資料庫執行個體,或在 Amazon RDS 外部執行的 MySQL 資料庫。
重要
設定 MySQL 資料庫執行個體與 Amazon Aurora MySQL 資料庫叢集之間的複寫時,您應該監控此複寫以確保其維持正常運作,並在必要時加以修復。
如需如何建立 Amazon Aurora MySQL 資料庫叢集,並讓它成為 MySQL 資料庫執行個體讀取複本的指示,請遵循使用 Amazon Aurora 為 MySQL 資料庫擴展讀取中的程序。
如需災難復原模型的詳細資訊,請參閱 How to choose the best disaster recovery option for your Amazon Aurora MySQL cluster
從 MySQL 遷移至 Amazon Aurora MySQL 時減少停機時間
從支援線上應用程式的 MySQL 資料庫將資料匯入至 Amazon Aurora MySQL 資料庫叢集時,您可能希望能減少遷移時服務中斷的時間。為此,您可以使用《Amazon Relational Database Service 使用者指南》中減少將資料匯入 MySQL 或 MariaDB 資料庫執行個體時的停機時間所記載的程序。如果您使用的是超大型資料庫,這個程序特別有用。您可以使用此程序來透過降低經過網路傳輸至 AWS的資料量,藉此減少匯入的成本。
此程序列出將資料庫資料的複本傳輸至 Amazon EC2 執行個體,並將資料匯入新的 RDS for MySQL 資料庫執行個體的步驟。因為 Amazon Aurora 與 MySQL 相容,您可以改為對目標 Amazon RDS MySQL 資料庫執行個體使用 Amazon Aurora 資料庫叢集。
避免 Aurora MySQL 資料庫執行個體效能變慢、自動重新啟動和容錯移轉
如果您正在執行繁重的工作負載或工作負載超出資料庫執行個體配置的資源,則可能會在執行應用程式和 Aurora 資料庫時耗盡資源。若要取得資料庫執行個體的指標,例如 CPU 使用率、記憶體使用量和使用的資料庫連線數目,您可以參考 Amazon 提供的指標 CloudWatch、Performance Insights 和增強型監控。如需如何監控資料庫執行個體的詳細資訊,請參閱 在 Amazon Aurora 叢集中監控指標。
如果您的工作負載耗盡了您正在使用的資源,您的資料庫執行個體可能會變慢、重新啟動,甚至容錯移轉到其他資料庫執行個體。若要避免這種情況,請監控資源使用率、檢查資料庫執行個體上執行的工作負載,並在必要時進行最佳化。如果最佳化無法改善執行個體指標並減緩資源耗盡,請考慮在達到其限制之前縱向擴展資料庫執行個體。如需可用資料庫執行個體類別及其規格的詳細資訊,請參閱 Aurora 資料庫執行個體類別。
針對 Aurora MySQL 的建議
以下功能可在與 MySQL 相容的 Aurora MySQL 中使用。但是,這些功能在 Aurora 環境中存在效能、可擴展性、穩定性或相容性的問題。因此,建議您在使用這些功能時遵循某些指導方針。例如,建議您不要將特定功能用於生產 Aurora 部署。
主題
在 Aurora MySQL 中使用多執行緒複寫
使用多執行緒二進位日誌複寫,SQL 執行緒會從轉送日誌讀取事件,並將它們排入佇列,以供 SQL 工作者執行緒套用。SQL 工作者執行緒是由協調器執行緒管理。可能的話,會平行套用二進位日誌事件。
Aurora MySQL 第 3 版和 Aurora MySQL 2.12.1 及更新版本中支援多執行緒複寫。
對於低於 3.04 的 Aurora MySQL 版本,當 Aurora MySQL 資料庫叢集用作二進位記錄複寫的僅供讀取複本時,依預設會使用單執行緒複寫。
早期版本的 Aurora MySQL 版本 2 繼承了有關從 MySQL 社區版多線程複製的幾個問題。對於這些版本,我們建議您不要在生產環境中使用多執行緒複寫。
如果您確實使用多執行緒複寫,建議您徹底測試它。
如需在 Amazon Aurora 中使用複寫的詳細資訊,請參閱以 Amazon Aurora 進行複寫。如需 Aurora MySQL 中多執行緒複寫的詳細資訊,請參閱多執行緒二進位記錄複寫。
使用本地 MySQL AWS Lambda 函數調用函數
建議您使用原生 MySQL 函數 lambda_sync
和 lambda_async
,以叫用 Lambda 函數。
如果您使用已棄用的 mysql.lambda_async
程序,建議在預存程序中包裝對 mysql.lambda_async
程序的呼叫。您可以從不同的來源 (例如觸發程式或用戶端程式碼) 呼叫此預存程序。此方法有助於避免阻抗不符問題,並讓您的資料庫程式設計人員能夠輕鬆呼叫 Lambda 函數。
如需從 Amazon Aurora 叫用 Lambda 函數的詳細資訊,請參閱從 Amazon Aurora MySQL 資料庫叢集叫用 Lambda 函式。
避免搭配 Amazon Aurora MySQL 使用 XA 交易
建議您不要使用 eXtended Architecture (XA) 交易搭配 Aurora MySQL,因為如果 XA 處於 PREPARED
狀態,它們可能造成過長的復原時間。如果您必須使用 XA 交易搭配 Aurora MySQL,請遵循這些最佳實務:
-
請勿讓 XA 交易保持開啟在
PREPARED
狀態。 -
盡可能讓 XA 交易越小越好。
如需使用 XA 交易搭配 MySQL 的詳細資訊,請參閱 MySQL 文件中的 XA 交易
DML 陳述式期間保持外部索引鍵的開啟狀態
在將 foreign_key_checks
變數設為 0
(關閉) 時,強烈建議您不要執行任何資料定義語言 (DDL) 陳述式。
如果您需要插入或更新需要暫時違反外部索引鍵的資料列,請遵循這些步驟:
-
將
foreign_key_checks
設定為0
。 -
進行您的資料處理語言 (DML) 變更。
-
確定您完成的變更未違反任何外部索引鍵限制。
-
將
foreign_key_checks
設為1
(開啟)。
此外,遵循用於外部索引鍵限制的這些其他最佳實務:
-
確定您的用戶端應用程式未隨著
foreign_key_checks
變數將0
變數設為init_connect
。 -
如果從邏輯備份 (例如
mysqldump
) 的還原失敗或未完成,在相同工作階段中開始任何其他操作之前,請確定將foreign_key_checks
設為1
。邏輯備份會在開始時將foreign_key_checks
設為0
。
設定日誌緩衝區的排清頻率
在 MySQL Community Edition 中,若要使交易可以耐久,InnoDB 日誌緩衝區必須排清到耐久儲存。您可以使用 innodb_flush_log_at_trx_commit
參數來設定日誌緩衝區排清到磁碟的頻率。
當您將 innodb_flush_log_at_trx_commit
參數設為預設值 1 時,日誌緩衝區會在每次交易認可時進行排清。此設定有助於保持資料庫 ACID
變更innodb_flush_log_at_trx_commit
為非預設值有助於減少資料操作語言 (DML) 延遲,但會犧牲記錄記錄的耐久性。一旦缺乏耐久性,就會使資料庫 ACID 不合規。建議您的資料庫必須是 ACID 合規,以避免在伺服器重新啟動時發生資料遺失的風險。如需此參數的詳細資訊,請參閱 MySQL 文件中的 innodb_flush_log_at_trx_commit
在 Aurora MySQL 中,重做日誌處理會卸載至儲存層,因此資料庫執行個體上不會排清至日誌檔。發出寫入時,重做日誌會從寫入器資料庫執行個體直接傳送至 Aurora 叢集磁碟區。唯一跨網路的寫入是重做日誌記錄。始終不會從資料庫層寫入任何頁面。
依預設,每個執行緒認可交易都會等待 Aurora 叢集磁碟區的確認。此確認指出已寫入此記錄和所有先前的重做日誌記錄,都已寫入並達到仲裁
Aurora MySQL 不會如 MySQL Community Edition 一樣將日誌排清到資料檔案。不過,在將重做日誌記錄寫入至 Aurora 叢集磁碟區時,您可以使用 innodb_flush_log_at_trx_commit
參數來放鬆耐久性限制。
對於 Aurora MySQL 版本 2:
-
innodb_flush_log_at_trx_commit
= 0 或 2 — 資料庫不會等待重做日誌記錄寫入 Aurora 叢集磁碟區的確認。 -
innodb_flush_log_at_trx_commit
= 1 — 資料庫會等待確認重做日誌記錄已寫入 Aurora 叢集磁碟區。
對於 Aurora MySQL 版本 3:
-
innodb_flush_log_at_trx_commit
= 0 — 資料庫不會等待重做日誌記錄寫入 Aurora 叢集磁碟區的確認。 -
innodb_flush_log_at_trx_commit
= 1 或 2 — 資料庫會等待確認重做日誌記錄已寫入 Aurora 叢集磁碟區。
因此,若要在 Aurora MySQL 第 3 版中取得與 Aurora MySQL 版本 2 中設定為 0 或 2 的相同非預設行為,請將參數設定為 0。
雖然這些設定可以降低用戶端的 DML 延遲,但在發生容錯移轉或重新啟動時,也可能導致資料遺失。因此,建議您將 innodb_flush_log_at_trx_commit
參數持續設定為預設值 1。
雖然 MySQL Community Edition 和 Aurora MySQL 都可能發生資料遺失,但由於其架構不同,每個資料庫的行為都會有所不同。這些架構差異可能會導致不同程度的資料遺失。若要確保您的資料庫是 ACID 合規,請將 innodb_flush_log_at_trx_commit
一律設定為 1。
注意
在 Aurora MySQL 版本 3 中,您必須先將值變更innodb_flush_log_at_trx_commit
為 1 以外的值,才能變更innodb_trx_commit_allow_data_loss
為 1。通過這樣做,您承認數據丟失的風險。
減少和疑難排解 Aurora MySQL 的死結情況
在相同資料頁面上並行修改記錄時,執行在唯一次要索引或外部索引鍵上經常遇到限制條件違規之工作負載的使用者,可能會遇到更多的死結情況和鎖定等待逾時。這些死結情況和逾時皆源自 MySQL Community Edition 錯誤修正
此修正包含在 MySQL Community Edition 5.7.26 及更新版本中,並已向後移植至 Aurora MySQL 2.10.3 及更新版本。強制序列化必須有此修正,方法是在 InnoDB 資料表的記錄變更上,針對這些資料處理語言 (DML) 類型執行額外鎖定。此問題是調查先前 MySQL Community Edition 錯誤修正
該項修正變更了 InnoDB 儲存引擎中,元組 (資料列) 更新的部分回復內部處理。在外部索引鍵或唯一次要索引產生限制條件違規的操作會導致部分回復。這包括但不限於並行 INSERT...ON DUPLICATE KEY UPDATE
、REPLACE
INTO,
和 INSERT IGNORE
陳述式 (upserts)。
在此情況下,部分回復並非應用程式層級交易的回復,而是發生限制條件違規時,對叢集索引的內部 InnoDB 回復變更。例如,在 upsert 操作期間找到重複索引鍵值。
在正常的插入操作中,InnoDB 會自動為每個索引建立叢集
減少 InnoDB 死結情況
您可以採取下列方法來減少資料庫執行個體的死結情況發生頻率。MySQL 文件
-
為了減少死結情況發生,請在進行一系列相關變更後立即遞交交易。您可以將大型交易 (遞交之間的多列更新) 拆解為較小交易來執行此動作。若您要批次插入行,請盡量減少批次插入的大小,尤其是使用上述提及的 upsert 操作時。
若要減少部分回復的次數,您可以嘗試下列方法:
-
一次插入一行,而非進行批次插入操作。如此便能減少可能發生衝突之交易的鎖定時間。
-
請不要使用
REPLACE INTO
,而是將 SQL 陳述式以多陳述式交易重新寫入,如下所示:BEGIN; DELETE
conflicting rows
; INSERTnew rows
; COMMIT; -
請不要使用
INSERT...ON DUPLICATE KEY UPDATE
,而是將 SQL 陳述式以多陳述式交易重新寫入,如下所示:BEGIN; SELECT
rows that conflict on secondary indexes
; UPDATEconflicting rows
; INSERTnew rows
; COMMIT;
-
-
避免長時間執行且可能導致鎖定的作用中或閒置交易。其中包括互動式 MySQL 用戶端工作階段,這些工作階段可能會在未遞交的交易中長時間開啟。最佳化交易大小或批次大小時,影響會因並行、重複項目數量和資料表結構等因素而有所不同。任何變更都應根據您的工作負載來執行和測試。
-
在部分情況下,當兩筆交易嘗試以不同順序存取相同的資料集時,不論資料集是否位於同一個資料表,皆可能發生死結情況。為了防止這種情況,您可以修改交易以相同順序存取資料,進而序列化該存取。例如,建立待完成的交易佇列。當多個交易並行發生時,此方法便能協助避免死結情況。
-
將謹慎選擇的索引新增到資料表中,可改善選取性並減少存取資料列的需求,從而減少死結情況。
-
若發生間隙鎖定
,您可以將工作階段或交易的交易隔離層級修改為 READ COMMITTED
,以避免發生間隙鎖定。如需詳細了解 InnoDB 隔離層級和其行為,請參閱 MySQL 文件的交易隔離層級。
注意
雖然您可以採取預防措施來減少死結情況,但死結情況是可預期的資料庫行為,仍然可能發生。應用程式應具有必要的邏輯來處理死結情況。例如,在應用程式中執行重試和停止邏輯。最理想的是解決問題根本原因,但是若確實發生死結情況,應用程式仍可以選擇等待並重試。
監控 InnoDB 死結情況
應用程式交易嘗試以導致循環等待的方式取得資料表層級和資料列層級鎖定時,MySQL 中可能發生死結
-
SHOW ENGINE
陳述式 –SHOW ENGINE INNODB STATUS \G
陳述式包含自上次重啟以來,資料庫最近遇到的死結詳細資訊。 -
MySQL 錯誤日誌 – 若您頻繁遇到死結,而
SHOW ENGINE
陳述式的輸出不敷使用,您可以開啟 innodb_print_all_deadlocks資料庫叢集參數。 開啟此參數時,InnoDB 使用者交易中所有死結的相關資訊皆會記錄在 Aurora MySQL 錯誤日誌
。 -
Amazon CloudWatch 指標 — 我們也建議您使用指標主動監控死 CloudWatch 結
Deadlocks
。如需詳細資訊,請參閱 Amazon Aurora 的執行個體層級指標。 -
Amazon CloudWatch 日誌 — 使用 CloudWatch 日誌,您可以檢視指標、分析日誌資料以及建立即時警示。如需詳細資訊,請參閱使用 Amazon 監控 Amazon Aurora MySQL 中的錯誤 CloudWatch 和使用 Amazon SNS 傳送通知
。 使用 CloudWatch 記錄開
innodb_print_all_deadlocks
啟時,您可以設定警示,以便在死結數超過指定臨界值時通知您。若要定義閾值,建議您觀察平時情況,根據您的正常工作負載來定義該值。 -
績效詳情 — 當您使用績效詳情時,您可以監控
innodb_deadlocks
和innodb_lock_wait_timeout
指標。如需這些指標的詳細資訊,請參閱 Aurora MySQL 的非原生計數器。