

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

# 對 Amazon Aurora MySQL 資料庫效能進行故障診斷
<a name="aurora-mysql-troubleshooting"></a>

本主題著重於一些常見的 Aurora MySQL 資料庫效能問題，以及如何故障診斷或收集資訊以快速修復這些問題。我們將資料庫效能分為兩個類別：
+ 伺服器效能 – 整個資料庫伺服器執行速度較慢。
+ 查詢效能 – 執行一或多個查詢需要更長的時間。

## AWS 監控選項
<a name="aurora-mysql-troubleshooting.monitoring"></a>

我們建議您使用下列 AWS 監控選項來協助進行故障診斷：
+ Amazon CloudWatch - Amazon CloudWatch 會即時監控您的 AWS 資源，以及您在 AWS 上執行的應用程式。您可以使用 CloudWatch 收集和追蹤指標，這些是您可以為您的資源和應用程式測量的變數。如需詳細資訊，請參閱[什麼是 Amazon CloudWatch？](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html)

  您可以在 AWS 管理主控台 上檢視資料庫執行個體的所有系統指標和處理程序資訊。您可以設定 Aurora MySQL 資料庫叢集將一般、緩慢、稽核和錯誤日誌資料發佈至 Amazon CloudWatch Logs 中的日誌群組。這可讓您檢視趨勢、在主機受到影響時維護日誌，以及建立「正常」效能的基準，以輕鬆識別異常或變更。如需更多詳細資訊，請參閱 [將 Amazon Aurora MySQL 日誌發佈至 Amazon CloudWatch Logs](AuroraMySQL.Integrating.CloudWatch.md)。
+ 增強型監控 – 若要啟用 Aurora MySQL 資料庫的其他 Amazon CloudWatch 指標，請開啟增強型監控。當您建立或修改 Aurora 資料庫叢集時，請選取**啟用增強型監控**。這可讓 Aurora 將效能指標發佈至 CloudWatch。一些可用的關鍵指標包括 CPU 用量、資料庫連線、儲存空間用量和查詢延遲。這些指標可協助判斷效能瓶頸。

  針對資料庫執行個體傳輸的資訊量與針對「增強型監控」定義的精密度成正比。較短的監控時間間隔會導致較頻繁的作業系統指標報告，並增加您的監控成本。若要管理成本，請針對 AWS 帳戶 中的不同執行個體設定不同的精細程度。建立執行個體時的預設精細程度為 60 秒。如需更多詳細資訊，請參閱 [增強型監控的成本](USER_Monitoring.OS.md#USER_Monitoring.OS.cost)。
+ 績效詳情 – 您可以檢視所有資料庫呼叫指標。這包括資料庫鎖定、等待和已處理的列數，所有這些都可以用於故障診斷。當您建立或修改 Aurora 資料庫叢集時，請選取**開啟績效詳情**。根據預設，績效詳情具有 7 天的資料保留期，但可以自訂以分析長期的績效趨勢。對於超過 7 天的保留期，您需要升級至付費方案。如需詳細資訊，請參閱[績效詳情定價](https://aws.amazon.com/rds/performance-insights/pricing/)。您可以分別設定每個 Aurora 資料庫執行個體的資料保留期間。如需更多詳細資訊，請參閱 [在 Amazon Aurora 上使用績效詳情監控資料庫負載](USER_PerfInsights.md)。

## Aurora MySQL 資料庫效能問題的最常見原因
<a name="aurora-mysql-troubleshooting-common"></a>

您可以使用下列步驟來故障診斷 Aurora MySQL 資料庫中的效能問題。我們會以調查的邏輯順序列出這些步驟，但它們不是線性的。一個探索可能會跨步驟跳躍，允許一系列的調查路徑。

1. [工作負載](aurora-mysql-troubleshooting-workload.md) – 了解您的資料庫工作負載。

1. [記錄](aurora-mysql-troubleshooting-logging.md) – 檢閱所有資料庫日誌。

1. [資料庫連線 ](mysql-troubleshooting-dbconn.md) – 請確定您的應用程式與資料庫之間的連線是可靠的。

1. [查詢效能](aurora-mysql-troubleshooting-query.md) – 檢查您的查詢執行計劃，以查看它們是否已變更。程式碼變更可能會導致計劃變更。

# 針對 Aurora MySQL 資料庫的工作負載問題進行故障診斷
<a name="aurora-mysql-troubleshooting-workload"></a>

資料庫工作負載可以檢視為讀取和寫入。了解「正常」資料庫工作負載後，您可以調校查詢和資料庫伺服器，以滿足其變更的需求。效能可以變更的原因有很多種，因此第一步是了解變更的內容。
+ 是否有主要或次要版本升級？

  主要版本升級包括引擎程式碼的變更，特別是在可變更查詢執行計畫的最佳化工具中。升級資料庫版本時，特別是主要版本，分析資料庫工作負載並進行相應調校非常重要。調校可能涉及最佳化和重寫查詢，或根據測試結果新增和更新參數設定。了解造成影響的原因，可讓您開始專注於該特定區域。

  如需詳細資訊，請參閱 MySQL 文件中的 [MySQL 8.0 中的新功能](https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html)和[伺服器和狀態變數，以及 MySQL 8.0 中新增、棄用或移除的選項](https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html)，以及 [比較 Aurora MySQL 第 2 版和 Aurora MySQL 第 3 版](AuroraMySQL.Compare-v2-v3.md)。
+ 正在處理的資料是否增加 (列計數)？
+ 是否有更多同時執行的查詢？
+ 是否有結構描述或資料庫變更？
+ 是否有程式碼瑕疵或修正？

**Contents**
+ [

## 執行個體主機指標
](#ams-workload-instance)
  + [

### CPU 用量
](#ams-workload-cpu)
  + [

### 記憶體用量
](#ams-workload-instance-memory)
  + [

### 網路輸送量
](#ams-workload-network)
+ [

## 資料庫指標
](#ams-workload-db)
+ [

# 針對 Aurora MySQL 資料庫的記憶體用量問題進行故障診斷
](ams-workload-memory.md)
  + [

## 範例 1：持續高記憶體用量
](ams-workload-memory.md#ams-workload-memory.example1)
  + [

## 範例 2：暫時性記憶體峰值
](ams-workload-memory.md#ams-workload-memory.example2)
  + [

## 範例 3：可釋放的記憶體持續下降，且不會回收
](ams-workload-memory.md#ams-workload-memory.example3)
+ [

# 故障診斷 Aurora MySQL 資料庫記憶體不足的問題
](AuroraMySQLOOM.md)

## 執行個體主機指標
<a name="ams-workload-instance"></a>

監控執行個體主機指標，例如 CPU、記憶體和網路活動，以協助了解工作負載是否已變更。了解工作負載變更有兩個主要概念：
+ 使用率 – 裝置的使用率，例如 CPU 或磁碟。它可以是以時間為基礎或以容量為基礎。
  + 時間型 – 資源在特定觀察期間忙碌的時間量。
  + 容量型 – 系統或元件可交付的輸送量，以容量的百分比表示。
+ 飽和度 – 資源需要的工作量超過其可處理的程度。當容量型用量達到 100% 時，便無法處理額外工作，且必須排入佇列。

### CPU 用量
<a name="ams-workload-cpu"></a>

您可以使用下列工具來識別 CPU 用量和飽和度：
+ CloudWatch 提供 `CPUUtilization` 指標。如果達到 100%，則執行個體會飽和。不過，CloudWatch 指標的平均值為 1 分鐘，且缺乏精細程度。

  如需 CloudWatch 指標的相關資訊，請參閱 [Amazon Aurora 的執行個體層級指標](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)。
+ 增強型監控提供作業系統 `top` 命令傳回的指標。它會顯示負載平均值和下列 CPU 狀態，精細程度為 1 秒：
  + `Idle (%)` = 閒置時間
  + `IRQ (%)` = 軟體中斷
  + `Nice (%)` = 具有[良好狀態](https://en.wikipedia.org/wiki/Nice_(Unix))優先順序之程序的良好時間。
  + `Steal (%)` = 服務其他租用戶所花費的時間 (虛擬化相關)
  + `System (%)` = 系統時間
  + `User (%)` = 使用者時間
  + `Wait (%)` = I/O 等待

  如需增強式監控指標的詳細資訊，請參閱 [Aurora​ 的作業系統指標](USER_Monitoring-Available-OS-Metrics.md#USER_Monitoring-Available-OS-Metrics-RDS)。

### 記憶體用量
<a name="ams-workload-instance-memory"></a>

如果系統處於記憶體壓力下，且資源消耗達到飽和，您應該會觀察高度的頁面掃描、分頁、交換和記憶體不足錯誤。

您可以使用下列工具來識別記憶體用量和飽和度：

CloudWatch 提供 `FreeableMemory` 指標，顯示透過清除一些作業系統快取和目前的可用記憶體，可以回收多少記憶體。

如需 CloudWatch 指標的相關資訊，請參閱 [Amazon Aurora 的執行個體層級指標](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)。

增強型監控提供下列指標，可協助您識別記憶體用量問題：
+ `Buffers (KB)` – 在寫入至儲存裝置之前，用於緩衝 I/O 請求的記憶體數量，以 KB 為單位。
+ `Cached (KB)` – 用來快取檔案系統 I/O 的記憶體數量。
+ `Free (KB)` – 未指派的記憶體數量，以 KB 為單位。
+ `Swap` – 快取、免費和總計。

例如，如果您看到資料庫執行個體使用 `Swap` 記憶體，則工作負載的記憶體總量會大於執行個體目前可用的記憶體總量。我們建議您增加資料庫執行個體的大小，或調校工作負載以使用較少的記憶體。

如需增強式監控指標的詳細資訊，請參閱 [Aurora​ 的作業系統指標](USER_Monitoring-Available-OS-Metrics.md#USER_Monitoring-Available-OS-Metrics-RDS)。

如需使用效能結構描述和 `sys` 結構描述來判斷哪些連線和元件正在使用記憶體的詳細資訊，請參閱 [針對 Aurora MySQL 資料庫的記憶體用量問題進行故障診斷](ams-workload-memory.md)。

### 網路輸送量
<a name="ams-workload-network"></a>

CloudWatch 為總網路輸送量提供下列指標，所有指標均為 1 分鐘內平均值：
+ `NetworkReceiveThroughput` – Aurora 資料庫叢集中的各個執行個體從用戶端接收到的網路輸送量。
+ `NetworkTransmitThroughput` – Aurora 資料庫叢集中的各個執行個體傳送至用戶端的網路輸送量。
+ `NetworkThroughput` – Aurora 資料庫叢集中的各個執行個體從用戶端接收及傳送至用戶端的網路輸送量。
+ `StorageNetworkReceiveThroughput` – 資料庫叢集中的各個執行個體從 Aurora 儲存子系統接收到的網路輸送量。
+ `StorageNetworkTransmitThroughput` – Aurora 資料庫叢集中的各個執行個體傳送至 Aurora 儲存子系統的網路輸送量。
+ `StorageNetworkThroughput` – Aurora 資料庫叢集中的各個執行個體從 Aurora 儲存子系統接收和向其傳入的網路輸送量。

如需 CloudWatch 指標的相關資訊，請參閱 [Amazon Aurora 的執行個體層級指標](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)。

增強型監控提供 `network` 的已接收 (**RX**) 和已傳輸 (**TX**) 圖形，精細程度高達 1 秒。

如需增強式監控指標的詳細資訊，請參閱 [Aurora​ 的作業系統指標](USER_Monitoring-Available-OS-Metrics.md#USER_Monitoring-Available-OS-Metrics-RDS)。

## 資料庫指標
<a name="ams-workload-db"></a>

檢查下列 CloudWatch 指標以確認是否有工作負載變更：
+ `BlockedTransactions` – 被封鎖的資料庫中的平均每秒交易數量。
+ `BufferCacheHitRatio` – 由緩衝區快取提供服務的請求的百分比。
+ `CommitThroughput` – 遞交操作的每秒平均數量。
+ `DatabaseConnections` – 連線至資料庫執行個體的用戶端網路連線數。
+ `Deadlocks` – 資料庫中平均每秒的死鎖數量。
+ `DMLThroughput` – 平均每秒插入、更新及刪除的數量。
+ `ResultSetCacheHitRatio` – 由查詢快取提供服務的請求的百分比。
+ `RollbackSegmentHistoryListLength` – 記錄具有刪除標記記錄之已遞交交易的復原日誌。
+ `RowLockTime` – 針對 InnoDB 資料表取得資料列鎖定所花費的時間總計。
+ `SelectThroughput` – 平均每秒選取查詢的數量。

如需 CloudWatch 指標的相關資訊，請參閱 [Amazon Aurora 的執行個體層級指標](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)。

檢查工作負載時，請考慮下列問題：

1. 資料庫執行個體類別最近是否有變更，例如將執行個體大小從 8xlarge 減少為 4xlarge，或從 db.r5 變更為 db.r6？ 

1. 您可以建立複製並重現問題，還是僅在該單一執行個體上發生？

1. 是否有伺服器資源耗盡、高 CPU 或記憶體耗盡？ 如果是，這可能表示需要額外的硬體。

1. 一個或多個查詢需要更長的時間嗎？

1. 變更是否由升級造成，尤其是主要版本升級？ 如果是，請比較升級前和升級後指標。

1. 讀取器資料庫執行個體的數量是否有變更？

1. 您是否已啟用一般、稽核或二進位記錄？ 如需更多詳細資訊，請參閱 [記錄 Aurora MySQL 資料庫](aurora-mysql-troubleshooting-logging.md)。

1. 您是否啟用、停用或變更二進位記錄 (binlog) 複寫的使用？

1. 是否有任何長時間執行的交易具有大量資料列鎖定？ 檢查 InnoDB 歷史記錄清單長度 (HLL) 是否有長時間執行交易的指示。

   如需詳細資訊，請參閱 [InnoDB 歷史記錄清單長度顯著增加](proactive-insights.history-list.md) 和部落格文章[為什麼我的 SELECT 查詢在 Amazon Aurora MySQL 資料庫叢集上緩慢執行？](https://repost.aws/knowledge-center/aurora-mysql-slow-select-query)。

   1. 如果大型 HLL 是由寫入交易造成，表示 `UNDO` 日誌正在累積 (未定期清理)。在大型寫入交易中，此累積可能會快速成長。在 MySQL 中，`UNDO` 存放在 [SYSTEM 資料表空間](https://dev.mysql.com/doc/refman/5.7/en/innodb-system-tablespace.html)中。`SYSTEM` 資料表空間無法縮減。`UNDO` 日誌可能會導致 `SYSTEM` 資料表空間成長到數個 GB 甚至 TB。清除後，透過建立資料的邏輯備份 (傾印) 釋放配置的空間，然後將傾印匯入新的資料庫執行個體。

   1. 如果大型 HLL 是由讀取交易 (長時間執行的查詢) 所造成，可能表示查詢使用大量的暫時空間。重新啟動以釋放暫時空間。檢查 Performance Insights 資料庫指標是否有 `Temp` 區段中的任何變更，例如 `created_tmp_tables`。如需更多詳細資訊，請參閱 [在 Amazon Aurora 上使用績效詳情監控資料庫負載](USER_PerfInsights.md)。

1. 您可以將長時間執行的交易分割成修改較少資料列的較小交易嗎？

1. 封鎖的交易是否有任何變更或死結增加？ 用來檢查 `Locks` 區段中狀態變數的任何變更的 Performance Insights 資料庫指標，例如 `innodb_row_lock_time`、` innodb_row_lock_waits` 和 ` innodb_dead_locks`。使用 1 分鐘或 5 分鐘的間隔。

1. 是否有增加的等待事件？ 使用 1 分鐘或 5 分鐘的間隔檢查 Performance Insights 等待事件和等待類型。分析最久等待事件，並查看它們是否與工作負載變更或資料庫爭用相關聯。例如，`buf_pool mutex` 表示緩衝集區爭用。如需更多詳細資訊，請參閱 [使用等待事件調校 Aurora MySQL](AuroraMySQL.Managing.Tuning.wait-events.md)。

# 針對 Aurora MySQL 資料庫的記憶體用量問題進行故障診斷
<a name="ams-workload-memory"></a>

雖然 CloudWatch、增強型監控和 Performance Insights 在作業系統層級提供記憶體用量的良好概觀，例如資料庫程序使用的記憶體用量，但它們不允許您細分引擎內可能導致此記憶體用量的連線或元件。

若要對此進行故障診斷，您可以使用效能結構描述和 `sys` 結構描述。在 Aurora MySQL 第 3 版中，啟用效能結構描述時，預設會啟用記憶體檢測。在 Aurora MySQL 第 2 版中，預設只會啟用效能結構描述記憶體用量的記憶體檢測。如需效能結構描述中可用資料表的相關資訊，以追蹤記憶體用量並啟用效能結構描述記憶體檢測，請參閱 MySQL 文件中的[記憶體摘要資料表](https://dev.mysql.com/doc/refman/8.3/en/performance-schema-memory-summary-tables.html)。如需使用效能結構描述搭配 Performance Insights 的詳細資訊，請參閱 [Aurora MySQL 上 Performance Insights 的效能結構描述概觀](USER_PerfInsights.EnableMySQL.md)。

雖然效能結構描述中提供了詳細資訊來追蹤目前的記憶體用量，但 MySQL [sys 結構描述](https://dev.mysql.com/doc/refman/8.0/en/sys-schema.html)具有效能結構描述資料表的檢視，可讓您快速找出記憶體的使用位置。

在 `sys` 結構描述中，下列檢視可用於依連線、元件和查詢來追蹤記憶體用量。


| 檢視 | 描述 | 
| --- | --- | 
|  [memory\$1by\$1host\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-host-by-current-bytes.html)  |  提供主機引擎記憶體用量的相關資訊。這有助於識別哪些應用程式伺服器或用戶端主機正在耗用記憶體。  | 
|  [memory\$1by\$1thread\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-thread-by-current-bytes.html)  |  依執行緒 ID 提供引擎記憶體用量的相關資訊。MySQL 中的執行緒 ID 可以是用戶端連線或背景執行緒。您可以使用 [sys.processlist](https://dev.mysql.com/doc/refman/8.0/en/sys-processlist.html) 檢視或 [performance\$1schema.threads](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-threads-table.html) 資料表，將執行 ID 映射至 MySQL 連線 ID。  | 
|  [memory\$1by\$1user\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-user-by-current-bytes.html)  |  依使用者提供引擎記憶體用量的相關資訊。這有助於識別哪些使用者帳戶或用戶端正在耗用記憶體。  | 
|  [memory\$1global\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-global-by-current-bytes.html)  |  依引擎元件提供引擎記憶體用量的相關資訊。這有助於依引擎緩衝區或元件全域識別記憶體用量。例如，您可能會看到 InnoDB 緩衝集區的 `memory/innodb/buf_buf_pool` 事件，或預備陳述式的 `memory/sql/Prepared_statement::main_mem_root` 事件。  | 
|  [memory\$1global\$1total](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-global-total.html)  |  提供資料庫引擎中總追蹤記憶體用量的概觀。  | 

在 Aurora MySQL 3.05 版及更高版本中，您也可以在[效能結構描述陳述式摘要表格中](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html)，依陳述式摘要追蹤記憶體用量上限。陳述式摘要資料表包含標準化陳述式摘要及其執行的彙總統計資料。`MAX_TOTAL_MEMORY` 欄可協助您識別自上次重設統計資料後，或資料庫執行個體重新啟動後，查詢摘要所使用的記憶體上限。這有助於識別可能耗用大量記憶體的特定查詢。

**注意**  
效能結構描述和 `sys` 結構描述會顯示伺服器上目前的記憶體使用量，以及每個連線和引擎元件所耗用記憶體的高水位標記。由於效能結構描述會保留在記憶體中，因此資料庫執行個體重新啟動時會重設資訊。若要隨時間維護歷程記錄，建議您在效能結構描述之外設定此資料的擷取和儲存。

**Topics**
+ [

## 範例 1：持續高記憶體用量
](#ams-workload-memory.example1)
+ [

## 範例 2：暫時性記憶體峰值
](#ams-workload-memory.example2)
+ [

## 範例 3：可釋放的記憶體持續下降，且不會回收
](#ams-workload-memory.example3)

## 範例 1：持續高記憶體用量
<a name="ams-workload-memory.example1"></a>

在 CloudWatch 中全域查看 `FreeableMemory`，我們可以看到記憶體用量在 2024-03-26 02:59 UTC 大幅增加。

![\[FreeableMemory 圖表顯示高記憶體用量。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/AuroraUserGuide/images/ams-freeable-memory.png)


這不會告訴我們整體情況。若要判斷哪個元件使用最多記憶體，您可以登入資料庫並查看 `sys.memory_global_by_current_bytes`。此資料表包含 MySQL 追蹤的記憶體事件清單，以及每個事件的記憶體配置資訊。每個記憶體追蹤事件都以 `memory/%` 開頭，後面接著與事件相關聯之引擎元件/功能的其他資訊。

例如，`memory/performance_schema/%` 適用於與效能結構描述相關的記憶體事件，而 `memory/innodb/%` 適用於 InnoDB，以此類推。如需關於事件命名慣例的詳細資訊，請參閱 MySQL 文件中的[效能結構描述檢測命名慣例](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-instrument-naming.html)。

從下列查詢中，我們可以根據 `current_alloc` 找出可能的問題點，但我們也可以看到許多 `memory/performance_schema/%` 事件。

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                                                  | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root                                |        512817 | 4.91 GiB      | 10.04 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
| memory/performance_schema/prepared_statements_instances                     |           252 | 488.25 MiB    | 1.94 MiB          |        252 | 488.25 MiB | 1.94 MiB       |
| memory/innodb/hash0hash                                                     |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/performance_schema/events_errors_summary_by_thread_by_error          |          1028 | 52.27 MiB     | 52.06 KiB         |       1028 | 52.27 MiB  | 52.06 KiB      |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name |             4 | 47.25 MiB     | 11.81 MiB         |          4 | 47.25 MiB  | 11.81 MiB      |
| memory/performance_schema/events_statements_summary_by_digest               |             1 | 40.28 MiB     | 40.28 MiB         |          1 | 40.28 MiB  | 40.28 MiB      |
| memory/performance_schema/memory_summary_by_thread_by_event_name            |             4 | 31.64 MiB     | 7.91 MiB          |          4 | 31.64 MiB  | 7.91 MiB       |
| memory/innodb/memory                                                        |         15227 | 27.44 MiB     | 1.85 KiB          |      20619 | 33.33 MiB  | 1.66 KiB       |
| memory/sql/String::value                                                    |         74411 | 21.85 MiB     |  307 bytes        |      76867 | 25.54 MiB  |  348 bytes     |
| memory/sql/TABLE                                                            |          8381 | 21.03 MiB     | 2.57 KiB          |       8381 | 21.03 MiB  | 2.57 KiB       |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.02 sec)
```

我們先前提到效能結構描述存放在記憶體中，這表示它也會在 `performance_schema` 記憶體檢測中受到追蹤。

**注意**  
如果您發現效能結構描述正在使用大量記憶體，並且想要限制其記憶體用量，您可以根據您的需求調整資料庫參數。如需詳細資訊，請參閱 MySQL 文件中的[效能結構描述記憶體配置模型](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-memory-model.html)。

為了方便閱讀，您可以重新執行相同的查詢，但排除效能結構描述事件。輸出會顯示下列內容：
+ 主要記憶體取用者為 `memory/sql/Prepared_statement::main_mem_root`。
+ `current_alloc` 欄會通知我們，MySQL 目前已配置 4.91 GiB 給此事件。
+ `high_alloc column` 告訴我們 4.91 GiB 是自上次重設統計資料後或伺服器重新啟動後 `current_alloc` 的高水位標記。這表示 `memory/sql/Prepared_statement::main_mem_root` 處於其最高值。

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name NOT LIKE 'memory/performance_schema/%' LIMIT 10;

+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                    | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root  |        512817 | 4.91 GiB      | 10.04 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
| memory/innodb/hash0hash                       |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/innodb/memory                          |         17096 | 31.68 MiB     | 1.90 KiB          |      22498 | 37.60 MiB  | 1.71 KiB       |
| memory/sql/String::value                      |        122277 | 27.94 MiB     |  239 bytes        |     124699 | 29.47 MiB  |  247 bytes     |
| memory/sql/TABLE                              |          9927 | 24.67 MiB     | 2.55 KiB          |       9929 | 24.68 MiB  | 2.55 KiB       |
| memory/innodb/lock0lock                       |          8888 | 19.71 MiB     | 2.27 KiB          |       8888 | 19.71 MiB  | 2.27 KiB       |
| memory/sql/Prepared_statement::infrastructure |        257623 | 16.24 MiB     |   66 bytes        |     257631 | 16.24 MiB  |   66 bytes     |
| memory/mysys/KEY_CACHE                        |             3 | 16.00 MiB     | 5.33 MiB          |          3 | 16.00 MiB  | 5.33 MiB       |
| memory/innodb/sync0arr                        |             3 | 7.03 MiB      | 2.34 MiB          |          3 | 7.03 MiB   | 2.34 MiB       |
| memory/sql/THD::main_mem_root                 |           815 | 6.56 MiB      | 8.24 KiB          |        849 | 7.19 MiB   | 8.67 KiB       |
+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.06 sec)
```

從事件的名稱，我們可以指出此記憶體正用於預備陳述式。如果您想要查看哪些連線使用此記憶體，您可以檢查 [memory\$1by\$1thread\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-thread-by-current-bytes.html)。

在下列範例中，每個連線配置了大約 7 MiB，高水位標記約為 6.29 MiB (`current_max_alloc`)。這很合理，因為範例使用 `sysbench` 搭配 80 個資料表和 800 個連線以及預備陳述式。如果您想要在此案例中減少記憶體使用量，您可以最佳化應用程式對預備陳述式的使用量，以減少記憶體使用量。

```
mysql> SELECT * FROM sys.memory_by_thread_by_current_bytes;

+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
| thread_id | user                                      | current_count_used | current_allocated | current_avg_alloc | current_max_alloc | total_allocated |
+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
|        46 | rdsadmin@localhost                        |                405 | 8.47 MiB          | 21.42 KiB         | 8.00 MiB          | 155.86 MiB      |
|        61 | reinvent@10.0.4.4                         |               1749 | 6.72 MiB          | 3.93 KiB          | 6.29 MiB          | 14.24 MiB       |
|       101 | reinvent@10.0.4.4                         |               1845 | 6.71 MiB          | 3.72 KiB          | 6.29 MiB          | 14.50 MiB       |
|        55 | reinvent@10.0.4.4                         |               1674 | 6.68 MiB          | 4.09 KiB          | 6.29 MiB          | 14.13 MiB       |
|        57 | reinvent@10.0.4.4                         |               1416 | 6.66 MiB          | 4.82 KiB          | 6.29 MiB          | 13.52 MiB       |
|       112 | reinvent@10.0.4.4                         |               1759 | 6.66 MiB          | 3.88 KiB          | 6.29 MiB          | 14.17 MiB       |
|        66 | reinvent@10.0.4.4                         |               1428 | 6.64 MiB          | 4.76 KiB          | 6.29 MiB          | 13.47 MiB       |
|        75 | reinvent@10.0.4.4                         |               1389 | 6.62 MiB          | 4.88 KiB          | 6.29 MiB          | 13.40 MiB       |
|       116 | reinvent@10.0.4.4                         |               1333 | 6.61 MiB          | 5.08 KiB          | 6.29 MiB          | 13.21 MiB       |
|        90 | reinvent@10.0.4.4                         |               1448 | 6.59 MiB          | 4.66 KiB          | 6.29 MiB          | 13.58 MiB       |
|        98 | reinvent@10.0.4.4                         |               1440 | 6.57 MiB          | 4.67 KiB          | 6.29 MiB          | 13.52 MiB       |
|        94 | reinvent@10.0.4.4                         |               1433 | 6.57 MiB          | 4.69 KiB          | 6.29 MiB          | 13.49 MiB       |
|        62 | reinvent@10.0.4.4                         |               1323 | 6.55 MiB          | 5.07 KiB          | 6.29 MiB          | 13.48 MiB       |
|        87 | reinvent@10.0.4.4                         |               1323 | 6.55 MiB          | 5.07 KiB          | 6.29 MiB          | 13.25 MiB       |
|        99 | reinvent@10.0.4.4                         |               1346 | 6.54 MiB          | 4.98 KiB          | 6.29 MiB          | 13.24 MiB       |
|       105 | reinvent@10.0.4.4                         |               1347 | 6.54 MiB          | 4.97 KiB          | 6.29 MiB          | 13.34 MiB       |
|        73 | reinvent@10.0.4.4                         |               1335 | 6.54 MiB          | 5.02 KiB          | 6.29 MiB          | 13.23 MiB       |
|        54 | reinvent@10.0.4.4                         |               1510 | 6.53 MiB          | 4.43 KiB          | 6.29 MiB          | 13.49 MiB       |
.                                                                                                                                                          .
.                                                                                                                                                          .
.                                                                                                                                                          .
|       812 | reinvent@10.0.4.4                         |               1259 | 6.38 MiB          | 5.19 KiB          | 6.29 MiB          | 13.05 MiB       |
|       214 | reinvent@10.0.4.4                         |               1279 | 6.38 MiB          | 5.10 KiB          | 6.29 MiB          | 12.90 MiB       |
|       325 | reinvent@10.0.4.4                         |               1254 | 6.38 MiB          | 5.21 KiB          | 6.29 MiB          | 12.99 MiB       |
|       705 | reinvent@10.0.4.4                         |               1273 | 6.37 MiB          | 5.13 KiB          | 6.29 MiB          | 13.03 MiB       |
|       530 | reinvent@10.0.4.4                         |               1268 | 6.37 MiB          | 5.15 KiB          | 6.29 MiB          | 12.92 MiB       |
|       307 | reinvent@10.0.4.4                         |               1263 | 6.37 MiB          | 5.17 KiB          | 6.29 MiB          | 12.87 MiB       |
|       738 | reinvent@10.0.4.4                         |               1260 | 6.37 MiB          | 5.18 KiB          | 6.29 MiB          | 13.00 MiB       |
|       819 | reinvent@10.0.4.4                         |               1252 | 6.37 MiB          | 5.21 KiB          | 6.29 MiB          | 13.01 MiB       |
|        31 | innodb/srv_purge_thread                   |              17810 | 3.14 MiB          |  184 bytes        | 2.40 MiB          | 205.69 MiB      |
|        38 | rdsadmin@localhost                        |                599 | 1.76 MiB          | 3.01 KiB          | 1.00 MiB          | 25.58 MiB       |
|         1 | sql/main                                  |               3756 | 1.32 MiB          |  367 bytes        | 355.78 KiB        | 6.19 MiB        |
|       854 | rdsadmin@localhost                        |                 46 | 1.08 MiB          | 23.98 KiB         | 1.00 MiB          | 5.10 MiB        |
|        30 | innodb/clone_gtid_thread                  |               1596 | 573.14 KiB        |  367 bytes        | 254.91 KiB        | 970.69 KiB      |
|        40 | rdsadmin@localhost                        |                235 | 245.19 KiB        | 1.04 KiB          | 128.88 KiB        | 808.64 KiB      |
|       853 | rdsadmin@localhost                        |                 96 | 94.63 KiB         | 1009 bytes        | 29.73 KiB         | 422.45 KiB      |
|        36 | rdsadmin@localhost                        |                 33 | 36.29 KiB         | 1.10 KiB          | 16.08 KiB         | 74.15 MiB       |
|        33 | sql/event_scheduler                       |                  3 | 16.27 KiB         | 5.42 KiB          | 16.04 KiB         | 16.27 KiB       |
|        35 | sql/compress_gtid_table                   |                  8 | 14.20 KiB         | 1.77 KiB          | 8.05 KiB          | 18.62 KiB       |
|        25 | innodb/fts_optimize_thread                |                 12 | 1.86 KiB          |  158 bytes        |  648 bytes        | 1.98 KiB        |
|        23 | innodb/srv_master_thread                  |                 11 | 1.23 KiB          |  114 bytes        |  361 bytes        | 24.40 KiB       |
|        24 | innodb/dict_stats_thread                  |                 11 | 1.23 KiB          |  114 bytes        |  361 bytes        | 1.35 KiB        |
|         5 | innodb/io_read_thread                     |                  1 |  144 bytes        |  144 bytes        |  144 bytes        |  144 bytes      |
|         6 | innodb/io_read_thread                     |                  1 |  144 bytes        |  144 bytes        |  144 bytes        |  144 bytes      |
|         2 | sql/aws_oscar_log_level_monitor           |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         4 | innodb/io_ibuf_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         7 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         8 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         9 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        10 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        11 | innodb/srv_lra_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        12 | innodb/srv_akp_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        18 | innodb/srv_lock_timeout_thread            |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |  248 bytes      |
|        19 | innodb/srv_error_monitor_thread           |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        20 | innodb/srv_monitor_thread                 |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        21 | innodb/buf_resize_thread                  |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        22 | innodb/btr_search_sys_toggle_thread       |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        32 | innodb/dict_persist_metadata_table_thread |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        34 | sql/signal_handler                        |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
831 rows in set (2.48 sec)
```

如前所述，此處的執行緒 ID (`thd_id`) 值可以參考伺服器背景執行緒或資料庫連線。如果您想要將執行緒 ID 值映射至資料庫連線 ID，您可以使用 `performance_schema.threads` 資料表或 `sys.processlist` 檢視，其中 `conn_id` 是連線 ID。

```
mysql> SELECT thd_id,conn_id,user,db,command,state,time,last_wait FROM sys.processlist WHERE user='reinvent@10.0.4.4';

+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
| thd_id | conn_id | user              | db       | command | state          | time | last_wait                                       |
+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
|    590 |     562 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    578 |     550 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    579 |     551 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    580 |     552 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    581 |     553 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    582 |     554 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    583 |     555 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    584 |     556 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    585 |     557 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    586 |     558 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    587 |     559 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
.                                                                                                                                     .
.                                                                                                                                     .
.                                                                                                                                     .
|    323 |     295 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    324 |     296 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    325 |     297 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    326 |     298 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    438 |     410 | reinvent@10.0.4.4 | sysbench | Execute | System lock    |    0 | wait/lock/table/sql/handler                     |
|    280 |     252 | reinvent@10.0.4.4 | sysbench | Sleep   | starting       |    0 | wait/io/socket/sql/client_connection            |
|     98 |      70 | reinvent@10.0.4.4 | sysbench | Query   | freeing items  |    0 | NULL                                            |
+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
804 rows in set (5.51 sec)
```

現在，我們停止 `sysbench` 工作負載，這會關閉連線並釋放記憶體。再次檢查事件，我們可以確認記憶體已釋出，但 `high_alloc` 仍告訴我們什麼是高水位標記。`high_alloc` 欄在識別記憶體用量中的短峰值時非常有用，其中您可能無法立即識別來自 `current_alloc` 的用量，這只會顯示目前配置的記憶體。

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name='memory/sql/Prepared_statement::main_mem_root' LIMIT 10;

+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                   | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root |            17 | 253.80 KiB    | 14.93 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
1 row in set (0.00 sec)
```

如果您想要重設 `high_alloc`，您可以截斷 `performance_schema` 記憶體摘要資料表，但這會重設所有記憶體檢測。如需詳細資訊，請參閱 MySQL 文件中的[效能結構描述一般資料表特性](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-table-characteristics.html)。

在下列範例中，我們可以看到 `high_alloc` 會在截斷後重設。

```
mysql> TRUNCATE `performance_schema`.`memory_summary_global_by_event_name`;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name='memory/sql/Prepared_statement::main_mem_root' LIMIT 10;

+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                   | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root |            17 | 253.80 KiB    | 14.93 KiB         |         17 | 253.80 KiB | 14.93 KiB      |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
1 row in set (0.00 sec)
```

## 範例 2：暫時性記憶體峰值
<a name="ams-workload-memory.example2"></a>

另一個常見情況是資料庫伺服器上記憶體用量的短暫峰值。這些可能是在 `sys.memory_global_by_current_bytes` 中使用 `current_alloc` 時難以故障診斷的可用記憶體中定期下降，因為記憶體已釋放。

**注意**  
如果已重設效能結構描述統計資料，或資料庫執行個體已重新啟動，此資訊將無法在 `sys` 或 p`erformance_schema` 中使用。若要保留此資訊，建議您設定外部指標集合。

增強型監控中 `os.memory.free` 指標的下圖顯示記憶體用量的短暫 7 秒峰值。增強型監控可讓您以最短 1 秒的間隔進行監控，這非常適合用於捕捉像這樣的暫時性峰值。

![\[顯示暫時性記憶體用量隨時間遽增的圖表，週期性模式表示潛在的記憶體管理問題。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/AuroraUserGuide/images/ams-free-memory-spikes.png)


為了協助診斷此處記憶體用量的原因，我們可以在 `sys` 記憶體摘要檢視和[效能結構描述陳述式摘要資料表](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html)中使用 `high_alloc` 的組合，嘗試識別違規的工作階段和連線。

如預期，由於記憶體使用量目前不高，因此在 `current_alloc` 下的 `sys` 結構描述檢視中看不到任何主要違規項目。

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                                                  | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/innodb/hash0hash                                                     |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/innodb/os0event                                                      |        439372 | 60.34 MiB     |  144 bytes        |     439372 | 60.34 MiB  |  144 bytes     |
| memory/performance_schema/events_statements_summary_by_digest               |             1 | 40.28 MiB     | 40.28 MiB         |          1 | 40.28 MiB  | 40.28 MiB      |
| memory/mysys/KEY_CACHE                                                      |             3 | 16.00 MiB     | 5.33 MiB          |          3 | 16.00 MiB  | 5.33 MiB       |
| memory/performance_schema/events_statements_history_long                    |             1 | 14.34 MiB     | 14.34 MiB         |          1 | 14.34 MiB  | 14.34 MiB      |
| memory/performance_schema/events_errors_summary_by_thread_by_error          |           257 | 13.07 MiB     | 52.06 KiB         |        257 | 13.07 MiB  | 52.06 KiB      |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name |             1 | 11.81 MiB     | 11.81 MiB         |          1 | 11.81 MiB  | 11.81 MiB      |
| memory/performance_schema/events_statements_summary_by_digest.digest_text   |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
| memory/performance_schema/events_statements_history_long.digest_text        |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
| memory/performance_schema/events_statements_history_long.sql_text           |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.01 sec)
```

展開檢視以依 `high_alloc` 排序，我們現在可以在這裡看到 `memory/temptable/physical_ram` 元件是很好的候選項目。其最高耗用 515.00 MiB。

顧名思義，`memory/temptable/physical_ram` 會在 MySQL 8.0 中引入的 MySQL 中檢測 `TEMP` 儲存引擎的記憶體用量。如需有關 MySQL 如何使用暫存資料表的詳細資訊，請參閱 MySQL 文件中的 [MySQL 中的內部暫存資料表使用](https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html)。

**注意**  
我們在此範例中使用 `sys.x$memory_global_by_current_bytes` 檢視。

```
mysql> SELECT event_name, format_bytes(current_alloc) AS "currently allocated", sys.format_bytes(high_alloc) AS "high-water mark"  
FROM sys.x$memory_global_by_current_bytes ORDER BY high_alloc DESC LIMIT 10;

+-----------------------------------------------------------------------------+---------------------+-----------------+
| event_name                                                                  | currently allocated | high-water mark |
+-----------------------------------------------------------------------------+---------------------+-----------------+
| memory/temptable/physical_ram                                               | 4.00 MiB            | 515.00 MiB      |
| memory/innodb/hash0hash                                                     | 79.07 MiB           | 79.07 MiB       |
| memory/innodb/os0event                                                      | 63.95 MiB           | 63.95 MiB       |
| memory/performance_schema/events_statements_summary_by_digest               | 40.28 MiB           | 40.28 MiB       |
| memory/mysys/KEY_CACHE                                                      | 16.00 MiB           | 16.00 MiB       |
| memory/performance_schema/events_statements_history_long                    | 14.34 MiB           | 14.34 MiB       |
| memory/performance_schema/events_errors_summary_by_thread_by_error          | 13.07 MiB           | 13.07 MiB       |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name | 11.81 MiB           | 11.81 MiB       |
| memory/performance_schema/events_statements_summary_by_digest.digest_text   | 9.77 MiB            | 9.77 MiB        |
| memory/performance_schema/events_statements_history_long.sql_text           | 9.77 MiB            | 9.77 MiB        |
+-----------------------------------------------------------------------------+---------------------+-----------------+
10 rows in set (0.00 sec)
```

在 [範例 1：持續高記憶體用量](#ams-workload-memory.example1) 中，我們檢查了每個連線目前的記憶體用量，以判斷哪些連線負責使用有問題的記憶體。在此範例中，記憶體已釋放，因此檢查目前連線的記憶體用量並不實用。

為了深入了解並尋找違規的陳述式、使用者和主機，我們會使用效能結構描述。效能結構描述包含多個由不同維度分割的陳述式摘要資料表，例如事件名稱、陳述式摘要、主機、執行緒和使用者。每個檢視都可讓您深入了解特定陳述式的執行位置及其執行方式。本節著重於 `MAX_TOTAL_MEMORY`，但您可以在[效能結構描述陳述式摘要資料表](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html)文件中，找到所有可用資料欄的詳細資訊。

```
mysql> SHOW TABLES IN performance_schema LIKE 'events_statements_summary_%';

+------------------------------------------------------------+
| Tables_in_performance_schema (events_statements_summary_%) |
+------------------------------------------------------------+
| events_statements_summary_by_account_by_event_name         |
| events_statements_summary_by_digest                        |
| events_statements_summary_by_host_by_event_name            |
| events_statements_summary_by_program                       |
| events_statements_summary_by_thread_by_event_name          |
| events_statements_summary_by_user_by_event_name            |
| events_statements_summary_global_by_event_name             |
+------------------------------------------------------------+
7 rows in set (0.00 sec)
```

首先，我們會檢查 `events_statements_summary_by_digest` 以查看 `MAX_TOTAL_MEMORY`。

在這裡，我們可以看到以下內容：
+ 具有摘要 `20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a` 的查詢似乎適合此記憶體用量。`MAX_TOTAL_MEMORY` 是 537450710，符合我們在 `sys.x$memory_global_by_current_bytes` 中看到 `memory/temptable/physical_ram` 事件的高水位標記。
+ 它已執行四次 (`COUNT_STAR`)，第一個是 2024-03-26 04:08:34.943256，最後一個是 2024-03-26 04:43:06.998310。

```
mysql> SELECT SCHEMA_NAME,DIGEST,COUNT_STAR,MAX_TOTAL_MEMORY,FIRST_SEEN,LAST_SEEN
FROM performance_schema.events_statements_summary_by_digest ORDER BY MAX_TOTAL_MEMORY DESC LIMIT 5;

+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
| SCHEMA_NAME | DIGEST                                                           | COUNT_STAR | MAX_TOTAL_MEMORY | FIRST_SEEN                 | LAST_SEEN                  |
+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
| sysbench    | 20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a |          4 |        537450710 | 2024-03-26 04:08:34.943256 | 2024-03-26 04:43:06.998310 |
| NULL        | f158282ea0313fefd0a4778f6e9b92fc7d1e839af59ebd8c5eea35e12732c45d |          4 |          3636413 | 2024-03-26 04:29:32.712348 | 2024-03-26 04:36:26.269329 |
| NULL        | 0046bc5f642c586b8a9afd6ce1ab70612dc5b1fd2408fa8677f370c1b0ca3213 |          2 |          3459965 | 2024-03-26 04:31:37.674008 | 2024-03-26 04:32:09.410718 |
| NULL        | 8924f01bba3c55324701716c7b50071a60b9ceaf17108c71fd064c20c4ab14db |          1 |          3290981 | 2024-03-26 04:31:49.751506 | 2024-03-26 04:31:49.751506 |
| NULL        | 90142bbcb50a744fcec03a1aa336b2169761597ea06d85c7f6ab03b5a4e1d841 |          1 |          3131729 | 2024-03-26 04:15:09.719557 | 2024-03-26 04:15:09.719557 |
+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
5 rows in set (0.00 sec)
```

現在我們知道違規摘要，我們可以取得更多詳細資訊，例如查詢文字、執行該摘要的使用者，以及執行該摘要的位置。根據傳回的摘要文字，我們可以看到這是一個常見的資料表運算式 (CTE)，可建立四個暫存資料表並執行四個資料表掃描，這非常沒有效率。

```
mysql> SELECT SCHEMA_NAME,DIGEST_TEXT,QUERY_SAMPLE_TEXT,MAX_TOTAL_MEMORY,SUM_ROWS_SENT,SUM_ROWS_EXAMINED,SUM_CREATED_TMP_TABLES,SUM_NO_INDEX_USED
FROM performance_schema.events_statements_summary_by_digest
WHERE DIGEST='20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a'\G;

*************************** 1. row ***************************
           SCHEMA_NAME: sysbench
           DIGEST_TEXT: WITH RECURSIVE `cte` ( `n` ) AS ( SELECT ? FROM `sbtest1` UNION ALL SELECT `id` + ? FROM `sbtest1` ) SELECT * FROM `cte`
     QUERY_SAMPLE_TEXT: WITH RECURSIVE cte (n) AS (   SELECT 1  from sbtest1 UNION ALL   SELECT id + 1 FROM sbtest1) SELECT * FROM cte
      MAX_TOTAL_MEMORY: 537450710
         SUM_ROWS_SENT: 80000000
     SUM_ROWS_EXAMINED: 80000000
SUM_CREATED_TMP_TABLES: 4
     SUM_NO_INDEX_USED: 4
1 row in set (0.01 sec)
```

如需 `events_statements_summary_by_digest` 資料表和其他效能結構描述陳述式摘要資料表的詳細資訊，請參閱 MySQL 文件中的[陳述式摘要資料表](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html)。

您也可以執行 [EXPLAIN](https://dev.mysql.com/doc/refman/8.0/en/explain.html) 或 [EXPLAIN ANALYZE](https://dev.mysql.com/doc/refman/8.0/en/explain.html#explain-analyze) 陳述式，以查看更多詳細資訊。

**注意**  
`EXPLAIN ANALYZE` 可以提供比 `EXPLAIN` 更多的資訊，但它也會執行查詢，因此請注意。

```
-- EXPLAIN
mysql> EXPLAIN WITH RECURSIVE cte (n) AS (SELECT 1  FROM sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte;

+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
| id | select_type | table      | partitions | type  | possible_keys | key  | key_len | ref  | rows     | filtered | Extra       |
+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
|  1 | PRIMARY     | <derived2> | NULL       | ALL   | NULL          | NULL | NULL    | NULL | 19221520 |   100.00 | NULL        |
|  2 | DERIVED     | sbtest1    | NULL       | index | NULL          | k_1  | 4       | NULL |  9610760 |   100.00 | Using index |
|  3 | UNION       | sbtest1    | NULL       | index | NULL          | k_1  | 4       | NULL |  9610760 |   100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)

-- EXPLAIN format=tree 
mysql> EXPLAIN format=tree WITH RECURSIVE cte (n) AS (SELECT 1 FROM sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte\G;

*************************** 1. row ***************************
EXPLAIN: -> Table scan on cte  (cost=4.11e+6..4.35e+6 rows=19.2e+6)
    -> Materialize union CTE cte  (cost=4.11e+6..4.11e+6 rows=19.2e+6)
        -> Index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6)
        -> Index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6)
1 row in set (0.00 sec)

-- EXPLAIN ANALYZE 
mysql> EXPLAIN ANALYZE WITH RECURSIVE cte (n) AS (SELECT 1 from sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte\G;

*************************** 1. row ***************************
EXPLAIN: -> Table scan on cte  (cost=4.11e+6..4.35e+6 rows=19.2e+6) (actual time=6666..9201 rows=20e+6 loops=1)
    -> Materialize union CTE cte  (cost=4.11e+6..4.11e+6 rows=19.2e+6) (actual time=6666..6666 rows=20e+6 loops=1)
        -> Covering index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6) (actual time=0.0365..2006 rows=10e+6 loops=1)
        -> Covering index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6) (actual time=0.0311..2494 rows=10e+6 loops=1)
1 row in set (10.53 sec)
```

但誰執行了查詢？ 我們可以在效能結構描述中看到 `destructive_operator` 使用者擁有 537450710 的 `MAX_TOTAL_MEMORY`，這再次符合先前的結果。

**注意**  
效能結構描述存放在記憶體中，因此不應依賴而作為稽核的唯一來源。如果您需要維護陳述式執行的歷程記錄，以及從哪些使用者執行，我們建議您啟用 [Aurora 進階稽核](AuroraMySQL.Auditing.md)。如果您還需要維護記憶體用量的相關資訊，建議您設定監控以匯出和儲存這些值。

```
mysql> SELECT USER,EVENT_NAME,COUNT_STAR,MAX_TOTAL_MEMORY FROM performance_schema.events_statements_summary_by_user_by_event_name
ORDER BY MAX_CONTROLLED_MEMORY DESC LIMIT 5;

+----------------------+---------------------------+------------+------------------+
| USER                 | EVENT_NAME                | COUNT_STAR | MAX_TOTAL_MEMORY |
+----------------------+---------------------------+------------+------------------+
| destructive_operator | statement/sql/select      |          4 |        537450710 |
| rdsadmin             | statement/sql/select      |       4172 |          3290981 |
| rdsadmin             | statement/sql/show_tables |          2 |          3615821 |
| rdsadmin             | statement/sql/show_fields |          2 |          3459965 |
| rdsadmin             | statement/sql/show_status |         75 |          1914976 |
+----------------------+---------------------------+------------+------------------+
5 rows in set (0.00 sec)

mysql> SELECT HOST,EVENT_NAME,COUNT_STAR,MAX_TOTAL_MEMORY FROM performance_schema.events_statements_summary_by_host_by_event_name
WHERE HOST != 'localhost' AND COUNT_STAR>0 ORDER BY MAX_CONTROLLED_MEMORY DESC LIMIT 5;

+------------+----------------------+------------+------------------+
| HOST       | EVENT_NAME           | COUNT_STAR | MAX_TOTAL_MEMORY |
+------------+----------------------+------------+------------------+
| 10.0.8.231 | statement/sql/select |          4 |        537450710 |
+------------+----------------------+------------+------------------+
1 row in set (0.00 sec)
```

## 範例 3：可釋放的記憶體持續下降，且不會回收
<a name="ams-workload-memory.example3"></a>

InnoDB 資料庫引擎針對不同的元件採用一系列專門的記憶體追蹤事件。這些特定事件允許精細追蹤索引鍵 InnoDB 子系統中的記憶體用量，例如：
+ `memory/innodb/buf0buf` – 專用於監控 InnoDB 緩衝集區的記憶體配置。
+ `memory/innodb/ibuf0ibuf` – 專門追蹤與 InnoDB 變更緩衝區相關的記憶體變更。

為了識別記憶體的最高取用者，我們可以查詢 `sys.memory_global_by_current_bytes`：

```
mysql> SELECT event_name,current_alloc FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------+---------------+
| event_name                                                      | current_alloc |
+-----------------------------------------------------------------+---------------+
| memory/innodb/memory                                            | 5.28 GiB      |
| memory/performance_schema/table_io_waits_summary_by_index_usage | 495.00 MiB    |
| memory/performance_schema/table_shares                          | 488.00 MiB    |
| memory/sql/TABLE_SHARE::mem_root                                | 388.95 MiB    |
| memory/innodb/std                                               | 226.88 MiB    |
| memory/innodb/fil0fil                                           | 198.49 MiB    |
| memory/sql/binlog_io_cache                                      | 128.00 MiB    |
| memory/innodb/mem0mem                                           | 96.82 MiB     |
| memory/innodb/dict0dict                                         | 96.76 MiB     |
| memory/performance_schema/rwlock_instances                      | 88.00 MiB     |
+-----------------------------------------------------------------+---------------+
10 rows in set (0.00 sec)
```

結果顯示 `memory/innodb/memory` 是目前配置記憶體中使用 5.28 GiB 的最高取用者。此事件可做為與更具體等待事件無關之各種 InnoDB 元件的記憶體配置類別，如先前 `memory/innodb/buf0buf` 所述。

在確定 InnoDB 元件是記憶體的主要取用者之後，我們可以使用下列 MySQL 命令深入探討細節：

```
SHOW ENGINE INNODB STATUS \G;
```

[SHOW ENGINE INNODB STATUS](https://dev.mysql.com/doc/refman/8.4/en/show-engine.html) 命令提供 InnoDB 儲存引擎的完整狀態報告，包括不同 InnoDB 元件的詳細記憶體用量統計資料。它有助於識別哪些特定的 InnoDB 結構或操作耗用最多的記憶體。如需詳細資訊，請參閱 MySQL 文件中的 [InnoDB 記憶體內結構](https://dev.mysql.com/doc/refman/8.0/en/innodb-in-memory-structures.html)。

分析 InnoDB 狀態報告的 `BUFFER POOL AND MEMORY` 區段時，我們看到 5,051,647,748 個位元組 (4.7 GiB) 配置到[字典物件快取](https://dev.mysql.com/doc/refman/8.0/en/data-dictionary-object-cache.html)，該快取佔了 `memory/innodb/memory` 所追蹤記憶體的 89%。

```
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 0
Dictionary memory allocated 5051647748
Buffer pool size 170512
Free buffers 142568
Database pages 27944
Old database pages 10354
Modified db pages 6
Pending reads 0
```

字典物件快取是共用的全域快取，可將先前存取的資料字典物件存放在記憶體中，以啟用物件重複使用並改善效能。字典物件快取的高記憶體配置會建議資料字典快取中的大量資料庫物件。

現在我們知道資料字典快取是主要取用者，我們繼續檢查資料字典快取是否有開啟的資料表。若要尋找資料表定義快取中的資料表數目，請查詢全域狀態變數 [open\$1table\$1definitions](https://dev.mysql.com/doc/refman/8.4/en/server-status-variables.html#statvar_Open_table_definitions)。

```
mysql> show global status like 'open_table_definitions';

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Open_table_definitions | 20000 |
+------------------------+-------+
1 row in set (0.00 sec)
```

如需詳細資訊，請參閱 MySQL 文件中的 [MySQL 如何開啟及關閉資料表](https://dev.mysql.com/doc/refman/8.0/en/table-cache.html)。

您可以透過限制資料庫叢集或資料庫執行個體參數群組中的 `table_definition_cache` 參數，來限制資料字典快取中的資料表定義數目。對於 Aurora MySQL，此值可作為資料表定義快取中資料表數量的軟性限制。預設值取決於執行個體類別，並設定為以下內容：

```
LEAST({DBInstanceClassMemory/393040}, 20000)
```

當資料表數量超過 `table_definition_cache` 限制時，至少最近最少使用 (LRU) 機制會從快取中移出和移除資料表。不過，涉及外部索引鍵關係的資料表不會放置在 LRU 清單中，以防止其移除。

在我們目前的案例中，我們會執行 [FLUSH TABLES](https://dev.mysql.com/doc/refman/8.4/en/flush.html) 來清除資料表定義快取。此動作會導致 [Open\$1table\$1definitions](https://dev.mysql.com/doc/refman/8.0/en/server-status-variables.html#statvar_Open_table_definitions) 全域狀態變數從 20,000 大幅降至 12，如下所示：

```
mysql> show global status like 'open_table_definitions';

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Open_table_definitions | 12    |
+------------------------+-------+
1 row in set (0.00 sec)
```

儘管如此減少，我們仍觀察到 `memory/innodb/memory` 的記憶體配置在 5.18 GiB 維持很高，而配置的字典記憶體也保持不變。這在下列查詢結果中很明顯：

```
mysql> SELECT event_name,current_alloc FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------+---------------+
| event_name                                                      | current_alloc |
+-----------------------------------------------------------------+---------------+
| memory/innodb/memory                                            | 5.18 GiB      |
| memory/performance_schema/table_io_waits_summary_by_index_usage | 495.00 MiB    |
| memory/performance_schema/table_shares                          | 488.00 MiB    |
| memory/sql/TABLE_SHARE::mem_root                                | 388.95 MiB    |
| memory/innodb/std                                               | 226.88 MiB    |
| memory/innodb/fil0fil                                           | 198.49 MiB    |
| memory/sql/binlog_io_cache                                      | 128.00 MiB    |
| memory/innodb/mem0mem                                           | 96.82 MiB     |
| memory/innodb/dict0dict                                         | 96.76 MiB     |
| memory/performance_schema/rwlock_instances                      | 88.00 MiB     |
+-----------------------------------------------------------------+---------------+
10 rows in set (0.00 sec)
```

```
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 0
Dictionary memory allocated 5001599639
Buffer pool size 170512
Free buffers 142568
Database pages 27944
Old database pages 10354
Modified db pages 6
Pending reads 0
```

這種持續高的記憶體用量可以歸因於涉及外部索引鍵關係的資料表。這些資料表不會放在 LRU 清單中進行移除，這解釋了即使在清除資料表定義快取之後，記憶體配置仍保持很高的原因。

解決此問題：

1. 檢閱和最佳化資料庫結構描述，特別是外部索引鍵關係。

1. 請考慮移至具有更多記憶體的大型資料庫執行個體類別，以容納您的字典物件。

透過遵循這些步驟並了解記憶體配置模式，您可以更好地管理 Aurora MySQL 資料庫執行個體中的記憶體用量，並防止因記憶體壓力導致的潛在效能問題。

# 故障診斷 Aurora MySQL 資料庫記憶體不足的問題
<a name="AuroraMySQLOOM"></a>

Aurora MySQL `aurora_oom_response` 執行個體層級參數可啟用資料庫執行個體監控系統記憶體，並估計各種陳述式和連線耗用的記憶體。如果系統執行時記憶體不足，它可以執行一連串的動作來嘗試釋放記憶體。它會這樣做以嘗試避免因記憶體不足 (OOM) 導致資料庫重新啟動。此執行個體層級參數會使用一個字串，字串內容是以逗號分隔的動作，當記憶體不足時，資料庫執行個體即會採取這些動作。Aurora MySQL 第 2 版和第 3 版支援 `aurora_oom_response` 參數。

下列值及其組合可用於 `aurora_oom_response` 參數。空字串表示不採取任何動作，並有效地關閉此功能，讓資料庫容易重新啟動 OOM。
+ `decline` – 一旦資料庫執行個體記憶體不足，便拒絕新的查詢。
+ `kill_connect` – 關閉耗用大量記憶體的資料庫連線，並結束目前的交易和資料定義語言 (DDL) 陳述式。Aurora MySQL 第 2 版不支援此回應。

  如需詳細資訊，請參閱 MySQL 文件中的 [KILL 陳述式](https://dev.mysql.com/doc/refman/8.0/en/kill.html)。
+ `kill_query` – 依記憶體消耗的遞減順序結束查詢，直到執行個體記憶體高於低閾值。DDL 陳述式不會結束。

  如需詳細資訊，請參閱 MySQL 文件中的 [KILL 陳述式](https://dev.mysql.com/doc/refman/8.0/en/kill.html)。
+ `print` – 只會列印耗用大量記憶體的查詢。
+ `tune` – 調整內部資料表快取，以釋放部分記憶體給系統。Aurora MySQL 會在記憶體不足情況下減少用於快取 (例如 `table_open_cache` 和 `table_definition_cache`) 的記憶體。最終，當系統不再記憶體不足時，Aurora MySQL 會將記憶體使用量設回正常情況。

  如需詳細資訊，請參閱 MySQL 文件中的 [table\$1open\$1cache](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_table_open_cache) 和 [table\$1definition\$1cache](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_table_definition_cache)。
+ `tune_buffer_pool` – 減少緩衝集區的大小以釋出一些記憶體，並讓資料庫伺服器能夠處理連線。Aurora MySQL 3.06 版及更新版本支援此回應。

  您必須在 `aurora_oom_response` 參數值中與 `kill_query` 或 `kill_connect` 配對 `tune_buffer_pool`。如果沒有，即使您將 `tune_buffer_pool` 包含在參數值中，也不會發生緩衝集區調整大小。

在低於 3.06 的 Aurora MySQL 版本中，對於記憶體小於或等於 4 GiB 的資料庫執行個體類別，當執行個體處於記憶體壓力下時，預設動作包括 `print`、`tune`、`decline` 和 `kill_query`。如果資料庫執行個體的記憶體大於 4 GiB，則參數值依預設為空白 (停用)。

在 Aurora MySQL 3.06 版及更高版本中，對於記憶體小於或等於 4 GiB 的資料庫執行個體類別，Aurora MySQL 也會關閉最耗用記憶體的連線 (`kill_connect`)。對於記憶體大於 4 GiB 的資料庫執行個體類別，預設參數值為 `print`。

在 Aurora MySQL 3.09 版和更新版本中，對於記憶體大於 4 GiB 的資料庫執行個體類別，預設參數值為 `print,decline,kill_connect`。

如果您經常遇到記憶體不足問題，則可以在啟用 `performance_schema` 時，使用[記憶體摘要資料表](https://dev.mysql.com/doc/refman/8.3/en/performance-schema-memory-summary-tables.html)來監控記憶體用量。

如需與 OOM 相關的 Amazon CloudWatch 指標，請參閱 [Amazon Aurora 的執行個體層級指標](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)。如需與 OOM 相關的全域狀態變數，請參閱 [Aurora MySQL 全域狀態變數](AuroraMySQL.Reference.GlobalStatusVars.md)。

# 記錄 Aurora MySQL 資料庫
<a name="aurora-mysql-troubleshooting-logging"></a>

Aurora MySQL 日誌提供有關資料庫活動和錯誤的基本資訊。透過啟用這些日誌，您可以識別和故障診斷問題、了解資料庫效能，以及稽核資料庫活動。建議您為所有 Aurora MySQL 資料庫執行個體啟用這些日誌，以確保資料庫的最佳效能和可用性。您可以啟用下列類型的記錄。每個日誌都包含可能導致發現資料庫處理影響的特定資訊。
+ 錯誤 – 只有在啟動、當機以及發生錯誤時，Aurora MySQL 才會寫入錯誤日誌。資料庫執行個體可在未寫入新項目到錯誤日誌的情況下持續執行數小時或數日。若您沒有看到最近的項目，這是因為伺服器未遇到需寫入日誌項目的錯誤。錯誤記錄預設為啟用。如需更多詳細資訊，請參閱 [Aurora MySQL 錯誤日誌](USER_LogAccess.MySQL.LogFileSize.md#USER_LogAccess.MySQL.Errorlog)。
+ 一般 – 一般日誌提供有關資料庫活動的詳細資訊，包括資料庫引擎執行的所有 SQL 陳述式。如需啟用一般記錄和設定記錄參數的詳細資訊，請參閱 MySQL 文件中的 [Aurora MySQL 慢查詢與一般查詢](USER_LogAccess.MySQL.LogFileSize.md#USER_LogAccess.MySQL.Generallog) 和[一般查詢日誌](https://dev.mysql.com/doc/refman/8.0/en/query-log.html)。
**注意**  
一般日誌可能會成長為非常大，並消耗您的儲存體。如需更多詳細資訊，請參閱 [Aurora MySQL 的日誌輪換與保留](USER_LogAccess.MySQL.LogFileSize.md#USER_LogAccess.AMS.LogFileSize.retention)。
+ 緩​慢查詢日誌 — 包含執行時間超過 [long\$1query\$1time](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_long_query_time) 秒數，且至少有 [min\$1examined\$1row\$1limit](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_min_examined_row_limit) 列需要檢查之 SQL 陳述式的緩​慢查詢日誌。您可以使用緩慢查詢日誌來尋找需要很長時間才能執行的查詢，因此是最佳化的候選項目。

  `long_query_time` 的預設值為 10 秒。我們建議您從高值開始，以識別最慢的查詢，然後著手進行微調。

  您也可以使用相關參數，例如 `log_slow_admin_statements` 和 `log_queries_not_using_indexes`。比較 `rows_examined` 與 `rows_returned`。如果 `rows_examined` 明顯大於 `rows_returned`，則這些查詢可能會遭到封鎖。

  在 Aurora MySQL 第 3 版中，您可以讓 `log_slow_extra` 取得更多詳細資訊。如需詳細資訊，請參閱 MySQL 文件中的[緩慢查詢日誌內容](https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html#slow-query-log-contents)。您也可以在工作階段層級修改 `long_query_time`，以互動方式偵錯查詢執行，而如果 `log_slow_extra` 全域啟用，這特別有用。

  如需啟用緩慢查詢記錄和設定記錄參數的詳細資訊，請參閱 MySQL 文件中的 [Aurora MySQL 慢查詢與一般查詢](USER_LogAccess.MySQL.LogFileSize.md#USER_LogAccess.MySQL.Generallog)和[緩慢查詢日誌](https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html)。
+ 稽核 – 稽核日誌會監控和記錄資料庫活動。Aurora MySQL 的稽核日誌稱為進階稽核。若要啟用進階稽核，請設定某些資料庫叢集參數。如需更多詳細資訊，請參閱 [使用進階稽核與 Amazon Aurora MySQL 資料庫叢集搭配](AuroraMySQL.Auditing.md)。
+ 二進位 – 二進位日誌 (binlog) 包含描述資料庫變更的事件，例如資料表建立操作和資料表資料的變更。它還包含可能已進行變更之陳述式的事件 (例如，符合沒有資料列的 [DELETE](https://dev.mysql.com/doc/refman/8.0/en/delete.html))，除非使用資料列型記錄。二進位日誌也包含有關每個陳述式使用該更新資料多久的資訊。

  在啟用二進位記錄的情況下執行伺服器會使效能稍微變慢。不過，二進位登入的好處可讓您設定複寫和還原操作，通常超過此輕微效能降低的缺點。
**注意**  
Aurora MySQL 不需要二進位記錄即可進行還原操作。

  如需啟用二進位記錄和設定二進位日誌格式的詳細資訊，請參閱 MySQL 文件中的 [為單一可用區資料庫設定 Aurora MySQL 二進位記錄](USER_LogAccess.MySQL.BinaryFormat.md) 和[二進位日誌](https://dev.mysql.com/doc/refman/8.0/en/binary-log.html)。

您可以將錯誤、一般、緩慢、查詢和稽核日誌發佈至 Amazon CloudWatch Logs。如需更多詳細資訊，請參閱 [將資料庫日誌發佈至 Amazon CloudWatch Logs](USER_LogAccess.Procedural.UploadtoCloudWatch.md)。

另一個用於摘要緩慢、一般和二進位日誌檔案的實用工具是 [pt-query-digest](https://docs.percona.com/percona-toolkit/pt-query-digest.html)。

# 針對 Aurora MySQL 資料庫的連線問題進行疑難排解
<a name="mysql-troubleshooting-dbconn"></a>

確保應用程式與 RDS 資料庫執行個體之間的可靠連線，對於工作負載的順暢操作至關重要。不過，連線問題可能會因為各種因素而產生，例如網路組態、驗證問題或資源限制。本指南旨在提供全方位方法來針對 Aurora MySQL 的連線問題進行疑難排解。

**Contents**
+ [

## 識別 Aurora MySQL 的資料庫連線問題
](#mysql-dbconn-identify)
+ [

## 收集 Aurora MySQL 連線問題的資料
](#mysql-dbconn-gather)
+ [

## 監控 Aurora MySQL 的資料庫連線
](#mysql-dbconn-monitor)
  + [

### Aurora MySQL 的其他監控
](#mysql-dbconn-monitor-ams)
+ [

## Aurora MySQL 的連線錯誤代碼
](#mysql-dbconn-errors)
+ [

## Aurora MySQL 的參數調校建議
](#mysql-dbconn-params)
+ [

## 針對 Aurora MySQL 資料庫連線問題進行疑難排解的範例
](#mysql-dbconn-examples)
  + [

### 範例 1：針對失敗的連線嘗試進行疑難排解
](#mysql-dbconn-example1)
  + [

### 範例 2：針對異常用戶端中斷連線進行疑難排解
](#mysql-dbconn-example2)
  + [

### 範例 3：對 IAM 失敗的連線嘗試進行故障診斷
](#mysql-dbconn-example3)

## 識別 Aurora MySQL 的資料庫連線問題
<a name="mysql-dbconn-identify"></a>

識別連線問題的特定類別有助於縮小潛在原因範圍，並引導疑難排解程序。每個類別可能需要不同的診斷和解決方法和技術。資料庫連線問題可廣泛分類為下列類別。

**連線錯誤和例外狀況**  
連線錯誤和例外狀況可能因各種原因而發生，例如不正確的連線字串、驗證失敗、網路中斷或資料庫伺服器問題。原因可能包括設定錯誤的連線參數、無效的憑證、網路中斷或資料庫伺服器當機或重新啟動。設定錯誤的安全群組、虛擬私有雲端 (VPC) 設定、網路存取控制清單 (ACL) 以及與子網路相關聯的路由表也可能導致連線問題。

**達到連線限制**  
當資料庫伺服器的並行連線數目超過允許的上限時，就會發生此問題。資料庫伺服器通常具有由叢集和執行個體參數群組中的參數 max\$1connections 定義的可設定連線上限。透過強加連線限制，資料庫伺服器可確保其有足夠的資源 (例如記憶體、CPU 和檔案控點) 可有效率地處理現有連線並提供可接受的效能。原因可能包括應用程式中的連線洩漏、連線集區效率低下，或連線請求意外突增。

**連線逾時。**  
當用戶端應用程式無法在指定的逾時期間內與資料庫伺服器建立連線時，就會發生連線逾時。常見原因包括網路問題、伺服器過載、防火牆規則和設定錯誤的連線設定。

**閒置連線逾時**  
資料庫伺服器可能會自動關閉長時間處於非作用中狀態的閒置連線，以節省資源。此逾時通常可使用 `wait_timeout` 和 `interactive_timeout parameters` 來設定，且應根據應用程式的連線使用模式進行調整。原因可能包括讓連線長時間閒置的應用程式邏輯，或不當的連線管理。

**現有連線的間歇中斷連線**  
此錯誤類別是指用戶端應用程式與資料庫之間已建立的連線，即使處於作用中狀態和使用中，仍會以不規律的間隔意外終止或中斷連線的情況。這些中斷連線會間歇性發生，這表示它們會以不規律的間隔發生，而不是一致的間隔。原因可包含下列項目：  
+ 資料庫伺服器問題，例如重新啟動或容錯移轉
+ 不當的應用程式連線處理
+ 負載平衡和代理問題
+ 網路不穩定
+ 連線路徑中涉及的第三方元件或中介軟體問題
+ 查詢執行逾時
+ 伺服器端或用戶端的資源限制
透過全面監控、記錄和分析來識別根本原因至關重要，同時實作適當的錯誤處理、連線集區和重試機制，有助於緩解這些間歇性中斷連線對應用程式功能和使用者體驗的影響。

## 收集 Aurora MySQL 連線問題的資料
<a name="mysql-dbconn-gather"></a>

收集與應用程式、資料庫、網路和基礎設施元件相關的完整資料，對於有效針對應用程式與 Aurora MySQL 資料庫之間的連線問題進行疑難排解至關重要。透過收集相關的日誌、組態和診斷資訊，您可以獲得寶貴的洞察，以協助識別連線問題的根本原因，並引導您進行適當的解決方案。

網路日誌和組態，例如安全群組規則、VPC 設定和路由表，對於識別可能使應用程式無法與資料庫建立成功連線的潛在網路相關瓶頸或組態錯誤至關重要。透過分析這些網路元件，您可以確保必要的連接埠已開啟、允許 IP 地址，以及正確設定路由組態。

**時間戳記**  
發生連線問題時，請記錄確切的時間戳記。這有助於識別模式，或將問題與其他事件或活動建立關聯。

**資料庫引擎日誌**  
除了一般資料庫日誌之外，請檢閱資料庫引擎日誌 (例如 MySQL 錯誤日誌和慢查詢日誌) 是否有任何相關資訊或可能與間歇性連線問題相關的錯誤。如需詳細資訊，請參閱[記錄 Aurora MySQL 資料庫](aurora-mysql-troubleshooting-logging.md)。

**用戶端應用程式日誌**  
從連線至資料庫的用戶端應用程式收集詳細日誌。應用程式日誌可從應用程式的角度提供連線嘗試、錯誤和任何相關資訊的可見性，這可能會顯示與連線字串、驗證憑證或應用程式層級連線處理相關的問題。  
另一方面，資料庫日誌提供對資料庫端錯誤、慢速查詢或可能導致連線問題的事件的洞察。如需詳細資訊，請參閱[記錄 Aurora MySQL 資料庫](aurora-mysql-troubleshooting-logging.md)。

**用戶端環境變數**  
檢查用戶端的任何環境變數或組態設定是否可能影響資料庫連線，例如代理設定、SSL/TLS 設定或任何其他相關變數。

**用戶端程式庫版本**  
確定用戶端使用用於資料庫連線的任何資料庫驅動程式、程式庫或架構的最新版本。過期版本可能會有已知問題或相容性問題。

**用戶端網路擷取**  
使用 Wireshark 或 `tcpdump` 等工具在發生連線問題期間，在用戶端執行網路擷取。這有助於識別用戶端上任何網路相關問題或異常。

**用戶端網路拓撲**  
了解用戶端的網路拓撲，包括任何防火牆、負載平衡器或其他元件，例如 RDS Proxy 或 Proxy SQL，這些元件正在與資料庫進行連線，而不是用戶端直接進行連線。

**用戶端作業系統設定**  
檢查可能影響網路連線的用戶端作業系統設定，例如防火牆規則、網路轉接器設定，以及任何其他相關設定。

**連線集區組態**  
如果您在應用程式中使用連線集區機制，請檢閱組態設定並監控集區指標 (例如作用中連線、閒置連線和連線逾時)，以確保集區正常運作。同時檢閱集區設定，例如集區大小上限、集區大小下限和連線驗證設定，以確保設定正確。

**連接字串**  
連線字串通常包含主機名稱或端點、連接埠號碼、資料庫名稱和驗證憑證等參數。分析連線字串有助於識別可能導致連線問題的潛在錯誤組態或不正確的設定。例如，不正確的主機名稱或連接埠號碼可能會導致用戶端無法連線到資料庫執行個體，而無效的驗證憑證可能會導致驗證失敗和連線遭拒。此外，連線字串可能會顯示與連線集區、逾時或其他可能導致連線問題之連線特定設定相關的問題。提供用戶端應用程式使用的完整連線字串，有助於精確找出用戶端上的任何錯誤組態。

**資料庫指標**  
在發生連線問題期間監控資料庫指標，例如 CPU 用量、記憶體用量和磁碟 I/O。這些項目可協助識別資料庫執行個體是否遇到資源爭用或效能問題。

**DB engine version (資料庫引擎版本)**  
請注意 Aurora MySQL 資料庫引擎版本。 AWS 會定期發行更新，以解決已知問題、安全漏洞並引入效能增強功能。因此，強烈建議您升級至最新的可用版本，因為這些更新通常包含與連線能力、效能和穩定性相關的錯誤修正和改進。提供資料庫版本資訊以及其他收集的詳細資訊，可協助 支援 有效診斷和解決連線問題。

**網路指標**  
在發生連線問題期間收集網路指標，例如延遲、封包遺失和輸送量。`ping`、`traceroute` 和網路監控工具等工具可協助收集此資料。

**來源和用戶端詳細資訊**  
判斷正在啟動資料庫連線的應用程式伺服器、負載平衡器或任何其他元件的 IP 地址。這可以是單一 IP 地址或 IP 地址範圍 (CIDR 表示法)。如果來源是 Amazon EC2 執行個體，也有助於檢閱與執行個體相關聯的執行個體類型、可用區域、子網路 ID 和安全群組，以及私有 IP 地址和公有 IP 地址等網路介面詳細資訊。

透過徹底分析收集的資料，您可以識別錯誤組態、資源限制、網路中斷或其他導致間歇性或持久性連線問題的基礎問題。此資訊可讓您採取有針對性的動作，例如調整組態、解決網路問題，或解決應用程式層級連線處理。

## 監控 Aurora MySQL 的資料庫連線
<a name="mysql-dbconn-monitor"></a>

若要監控連線問題並進行疑難排解，您可以使用下列指標和功能。

**CloudWatch 指標**  
+ `CPUUtilization` – 資料庫執行個體上的高 CPU 用量可能會導致查詢執行緩慢，進而導致連線逾時或遭拒。
+ `DatabaseConnections` – 監控資料庫執行個體的作用中連線數目。接近已設定最大值的高連線數量，可能表示潛在的連線問題或連線集區耗盡。
+ `FreeableMemory` – 由於資源限制，可用記憶體不足可能會導致效能問題和連線問題。
+ `NetworkReceiveThroughput` 和 `NetworkTransmitThroughput` – 網路輸送量異常峰值或下降可能表示連線問題或網路瓶頸。

**績效詳情指標**  
若要使用 Performance Insights 針對 Aurora MySQL 中的連線問題進行疑難排解，請分析資料庫指標，如下所示：  
+ Aborted\$1clients
+ Aborted\$1connects
+ 連線
+ max\$1connections
+ Threads\$1connected
+ Threads\$1created
+ Threads\$1running
這些指標可協助您識別連線瓶頸、偵測網路或驗證問題、最佳化連線集區，並確保有效的執行緒管理。如需詳細資訊，請參閱[Aurora MySQL 的績效詳情計數器](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.Aurora_MySQL)。

**Performance Insights 功能**  
+ **資料庫負載** – 視覺化一段時間內的資料庫負載，並將其與連線問題或效能降級建立關聯。
+ **SQL 統計資料** – 分析 SQL 統計資料，以識別可能造成連線問題的低效率查詢或資料庫操作。
+ **熱門查詢** – 識別和分析資源最密集的查詢，這有助於識別可能導致連線問題的潛在效能瓶頸或長時間執行的查詢。

透過監控這些指標並利用 Performance Insights，您可以了解資料庫執行個體的效能、資源用量，以及可能導致連線問題的潛在瓶頸。例如：
+ 接近上限的高 `DatabaseConnections` 可能表示連線集區耗盡或不當的連線處理，導致連線問題。
+ 高 `CPUUtilization` 或低 `FreeableMemory` 可能表示資源限制，這可能會導致查詢執行緩慢和連線逾時或遭拒。
+ 分析**熱門查詢**和 **SQL 統計資料**有助於識別可能導致連線問題的效率低下或資源密集型查詢。

此外，監控 CloudWatch Logs 和設定警示可協助您在連線問題升級之前主動識別和回應。

請務必注意，雖然這些指標和工具可以提供寶貴的洞察，但應該與其他疑難排解步驟搭配使用。透過檢閱網路組態、安全群組規則和應用程式層級連線處理，您可以全面診斷和解決 Aurora MySQL 資料庫執行個體的連線問題。

### Aurora MySQL 的其他監控
<a name="mysql-dbconn-monitor-ams"></a>

**CloudWatch 指標**  
+ `AbortedClients` – 追蹤未正確關閉的用戶端連線數目。
+ `AuroraSlowConnectionHandleCount` – 追蹤緩慢連線處理操作的數量，指出潛在的連線問題或效能瓶頸。
+ `AuroraSlowHandshakeCount` – 測量緩慢交握操作的數量，這也可能是連線問題的指標。
+ `ConnectionAttempts` – 測量對 Aurora MySQL 資料庫執行個體進行的連線嘗試次數。

**全域狀態變數**  
`Aurora_external_connection_count` – 顯示資料庫執行個體的資料庫連線數目，排除用於資料庫運作狀態檢查的 RDS 服務連線。

透過監控這些指標和全域狀態變數，您可以了解可能導致 Amazon Aurora MySQL 執行個體連線問題的連線模式、錯誤和潛在瓶頸。

例如，大量 `AbortedClients` 或 `AuroraSlowConnectionHandleCount` 可能表示連線問題。

此外，設定 CloudWatch 警示和通知可協助您在連線問題升級並影響應用程式效能之前，主動識別和回應連線問題。

## Aurora MySQL 的連線錯誤代碼
<a name="mysql-dbconn-errors"></a>

以下是 Aurora MySQL 資料庫的一些常見連線錯誤，以及其錯誤代碼和說明。

**錯誤代碼 1040：太多連線**  
當用戶端嘗試建立的連線數量超過資料庫伺服器允許的上限時，就會發生此錯誤。可能的子句包括：  
+ 連線集區錯誤組態 – 如果使用連線集區機制，請確定集區大小上限未設定得太高，且連線已正確釋放回集區。
+ 資料庫執行個體組態 – 驗證資料庫執行個體允許的連線設定上限，並視需要設定 `max_connections` 參數進行調整。
+ 高並行 – 如果多個用戶端或應用程式同時連線到資料庫，可能會達到允許的連線上限。

**錯誤代碼 1045：拒絕使用者 '...'@'...' 的存取 (使用密碼：是/否)**  
此錯誤表示嘗試連線至資料庫時發生驗證失敗。可能的子句包括：  
+ 驗證外掛程式相容性 – 檢查用戶端使用的驗證外掛程式是否與資料庫伺服器的驗證機制相容。
+ 不正確的使用者名稱和密碼 – 確認在連線字串或驗證機制中使用正確的使用者名稱和密碼。
+ 使用者許可 – 確定使用者具有從指定主機或網路連線至資料庫執行個體的必要許可。

**錯誤代碼 1049：不明資料庫 '...'**  
此錯誤表示用戶端嘗試連線到伺服器上不存在的資料庫。可能的子句包括：  
+ 未建立資料庫 – 確定已在資料庫伺服器上建立指定的資料庫。
+ 資料庫名稱不正確 – 再次檢查在連線字串或查詢中使用的資料庫名稱是否正確。
+ 使用者許可 – 確認使用者具有存取指定資料庫的必要許可。

**錯誤代碼 1153：擁有大於 'max\$1allowed\$1packet' 位元組的封包**  
當用戶端嘗試傳送或接收的資料超過資料庫伺服器允許的封包大小上限時，就會發生此錯誤。可能的子句包括：  
+ 大型查詢或結果集 – 如果執行涉及大量資料的查詢，可能會超過封包大小限制。
+ 設定錯誤的封包大小設定 – 檢查資料庫伺服器上的 `max_allowed_packet` 設定，並視需要進行調整。
+ 網路組態問題 – 確定網路組態 (例如 MTU 大小) 允許所需的封包大小。

**錯誤代碼 1226：使用者 '...' 已超過 'max\$1user\$1connections' 資源 (目前值：...)**  
此錯誤表示使用者已超過資料庫伺服器允許的並行連線數目上限。可能的原因包括下列項目：  
+ 連線集區錯誤組態 – 如果使用連線集區機制，請確定集區大小上限針對使用者的連線限制未設定得太高。
+ 資料庫執行個體組態 – 驗證資料庫執行個體的 `max_user_connections` 設定，並視需要進行調整。
+ 高並行 – 如果多個用戶端或應用程式同時使用相同使用者連線到資料庫，可能會達到使用者特定連線限制。

**錯誤代碼 2003：無法在 '...' 上連線至 MySQL 伺服器 (10061)**  
此錯誤通常發生在用戶端無法與資料庫伺服器建立 TCP/IP 連線時。其可能由各種問題造成，例如下列項目：  
+ 資料庫執行個體狀態 – 確定資料庫執行個體處於 `available` 狀態，而且不會進行任何維護或備份操作。
+ 防火牆規則 – 檢查是否有任何防火牆 (作業系統、網路或安全群組) 封鎖指定連接埠上的連線 (針對 MySQL 通常是 3306)。
+ 不正確的主機名稱或端點 – 請確定在連線字串中使用的主機名稱或端點正確且符合資料庫執行個體。
+ 網路連線問題 – 確認用戶端機器可以透過網路連線資料庫執行個體。檢查是否有任何網路中斷、路由問題，或 VPC 或子網路錯誤組態。

**錯誤代碼 2005：不明 MySQL 伺服器主機 '...' (11001)**  
當用戶端無法將資料庫伺服器的主機名稱或端點解析為 IP 地址時，就會發生此錯誤。可能的子句包括：  
+ DNS 解析問題 – 確認用戶端機器可以使用 DNS 正確解析主機名稱。檢查 DNS 設定、DNS 快取，並嘗試使用 IP 地址而非主機名稱。
+ 不正確的主機名稱或端點 – 再次檢查在連線字串中使用的主機名稱或端點是否正確。
+ 網路組態問題 – 確定用戶端的網路組態 (例如 VPC、子網路和路由表) 允許 DNS 解析和連線至資料庫執行個體。

**錯誤代碼 2026：SSL 連線錯誤**  
當連線嘗試期間發生 SSL/TLS 組態或憑證驗證問題時，就會發生此錯誤。可能的子句包括：  
+ 憑證過期 – 檢查伺服器使用的 SSL/TLS 憑證是否已過期且需要續約。
+ 憑證驗證問題 – 驗證用戶端是否能夠正確驗證伺服器的 SSL/TLS 憑證，以及憑證是否可信任。
+ 網路組態問題 – 確定網路組態允許 SSL/TLS 連線，而且不會封鎖或干擾 SSL/TLS 交握程序。
+ SSL/TLS 組態不符 – 確定用戶端和伺服器上的 SSL/TLS 設定 (例如，密碼套件和通訊協定版本) 相容。

透過了解每個錯誤代碼的詳細說明和潛在原因，您可以在使用 Aurora MySQL 資料庫時更好地疑難排解和解決連線問題。

## Aurora MySQL 的參數調校建議
<a name="mysql-dbconn-params"></a>

**連線數上限**  
調整這些參數有助於防止因達到允許的最大連線限制而導致的連線問題。請確定根據應用程式的並行要求和資源限制，適當地設定這些值。  
+ `max_connections` – 此參數指定允許的資料庫執行個體並行連線數目上限。
+ `max_user_connections` – 您可以在使用者建立和修改期間指定此參數，並設定針對特定使用者帳戶允許的並行連線數目上限。

**網路緩衝區大小**  
增加這些值可以改善網路效能，尤其是涉及大型資料傳輸或結果集的工作負載。不過請小心謹慎，因為較大的緩衝區大小可能會耗用更多記憶體。  
+ `net_buffer_length` – 此參數會設定用戶端連線和結果緩衝區的初始大小，平衡記憶體用量與查詢效能。
+ `max_allowed_packet` – 此參數指定資料庫執行個體可傳送或接收的單一網路封包大小上限。

**網路壓縮 (用戶端)**  
啟用網路壓縮可以減少網路頻寬用量，但可能會增加用戶端和伺服器端的 CPU 額外負荷。  
+ `compress` – 此參數會啟用或停用用戶端/伺服器通訊的網路壓縮。
+ `compress_protocol` – 此參數指定用於網路通訊的壓縮通訊協定。

**網路效能調校**  
調整這些逾時有助於管理閒置連線並防止資源耗盡，但請小心謹慎，因為低值可能會導致連線提早終止。  
+ `interactive_timeout` – 此參數指定伺服器在互動式連線上關閉活動之前等待的秒數。
+ `wait_timeout` – 此參數決定伺服器在非互動式連線上關閉活動之前等待的秒數。

**網路逾時設定**  
調整這些逾時有助於解決與緩慢或無回應連線相關的問題。但請小心不要將其設得太低，因為這可能會導致連線過早失敗。  
+ `net_read_timeout` – 此參數指定在結束讀取操作之前等待來自連線之更多資料的秒數。
+ `net_write_timeout` – 此參數決定在結束寫入操作之前等待區塊寫入連線的秒數。

## 針對 Aurora MySQL 資料庫連線問題進行疑難排解的範例
<a name="mysql-dbconn-examples"></a>

下列範例示範如何識別 Aurora MySQL 的資料庫連線問題並進行疑難排解。

### 範例 1：針對失敗的連線嘗試進行疑難排解
<a name="mysql-dbconn-example1"></a>

連線嘗試可能會因為多種原因而失敗，包括驗證失敗、SSL/TLS 交握失敗、達到 `max_connections` 限制，以及資料庫執行個體的資源限制。

您可以從 Performance Insights 或使用下列命令來追蹤失敗連線的數量。

```
mysql> show global status like 'aborted_connects';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| Aborted_connects | 7     |
+------------------+-------+
1 row in set (0.00 sec)
```

如果 `Aborted_connects` 的數量隨時間增加，則應用程式可能會有間歇性連線問題。

您可以使用 [Aurora 進階稽核](AuroraMySQL.Auditing.md)來記錄與用戶端連線的連線和中斷連線。您可以在資料庫叢集參數群組中設定下列參數來執行此操作：
+ `server_audit_logging` = `1`
+ `server_audit_events` = `CONNECT`

 以下是失敗登入之稽核日誌的擷取。

```
1728498527380921,auora-mysql-node1,user_1,172.31.49.222,147189,0,FAILED_CONNECT,,,1045
1728498527380940,auora-mysql-node1,user_1,172.31.49.222,147189,0,DISCONNECT,,,0
```

其中：
+ `1728498527380921` – 失敗登入發生時的 epoch 時間戳記
+ `aurora-mysql-node1` – 連線失敗之 Aurora MySQL 叢集節點的執行個體識別符
+ `user_1` – 登入失敗的資料庫使用者名稱
+ `172.31.49.222` – 建立連線之用戶端的私有 IP 地址
+ `147189` – 失敗登入的連線 ID
+ `FAILED_CONNECT` – 表示連線失敗。
+ `1045` – 傳回碼。非零值表示錯誤。在此情況下，`1045` 對應至存取遭拒。

如需詳細資訊，請參閱 MySQL 文件中的[伺服器錯誤代碼](https://dev.mysql.com/doc/mysql-errors/5.7/en/server-error-reference.html)和[用戶端錯誤代碼](https://dev.mysql.com/doc/mysql-errors/5.7/en/client-error-reference.html)。

 您也可以檢查 Aurora MySQL 錯誤日誌是否有任何相關的錯誤訊息，例如：

```
2024-10-09T19:26:59.310443Z 220 [Note] [MY-010926] [Server] Access denied for user 'user_1'@'172.31.49.222' (using password: YES) (sql_authentication.cc:1502)
```

### 範例 2：針對異常用戶端中斷連線進行疑難排解
<a name="mysql-dbconn-example2"></a>

您可以從 Performance Insights 或使用下列命令來追蹤異常用戶端中斷連線的數量。

```
mysql> show global status like 'aborted_clients';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| Aborted_clients | 9     |
+-----------------+-------+
1 row in set (0.01 sec)
```

如果 `Aborted_clients` 的數量隨著時間增加，則應用程式無法正確關閉與資料庫的連線。如果連線未正確關閉，可能會導致資源洩漏和潛在的效能問題。不必要地讓連線保持開啟可能會耗用系統資源，例如記憶體和檔案描述項，最終可能導致應用程式或伺服器變得無回應或重新啟動。

您可以使用下列查詢來識別未正確關閉連線的帳戶。它會擷取使用者帳戶名稱、使用者連線的主機、未關閉的連線數，以及未關閉的連線百分比。

```
SELECT
    ess.user,
    ess.host,
    (a.total_connections - a.current_connections) - ess.count_star AS not_closed,
    (((a.total_connections - a.current_connections) - ess.count_star) * 100) / (a.total_connections - a.current_connections) AS pct_not_closed
FROM
    performance_schema.events_statements_summary_by_account_by_event_name AS ess
    JOIN performance_schema.accounts AS a ON (ess.user = a.user AND ess.host = a.host)
WHERE
    ess.event_name = 'statement/com/quit'
    AND (a.total_connections - a.current_connections) > ess.count_star;

+----------+---------------+------------+----------------+
| user     | host          | not_closed | pct_not_closed |
+----------+---------------+------------+----------------+
| user1    | 172.31.49.222 |          1 |        33.3333 |
| user1    | 172.31.93.250 |       1024 |        12.1021 |
| user2    | 172.31.93.250 |         10 |        12.8551 |
+----------+---------------+------------+----------------+
3 rows in set (0.00 sec)
```

識別未關閉連線的使用者帳戶和主機之後，您可以繼續檢查未正常關閉連線的程式碼。

例如，使用 Python 中的 MySQL 連接器，使用連線物件的 `close()` 方法來關閉連線。以下是建立資料庫連線、執行查詢及關閉連線的範例函數：

```
import mysql.connector

def execute_query(query):
    # Establish a connection to the database
    connection = mysql.connector.connect(
        host="your_host",
        user="your_username",
        password="your_password",
        database="your_database"
    )

    try:
        # Create a cursor object
        cursor = connection.cursor()

        # Execute the query
        cursor.execute(query)

        # Fetch and process the results
        results = cursor.fetchall()
        for row in results:
            print(row)

    finally:
        # Close the cursor and connection
        cursor.close()
        connection.close()
```

在此範例中，會在 `finally` 區塊中呼叫 `connection.close()` 方法，以確保連線已關閉，無論是否發生例外狀況。

### 範例 3：對 IAM 失敗的連線嘗試進行故障診斷
<a name="mysql-dbconn-example3"></a>

與 AWS Identity and Access Management (IAM) 使用者的連線可能會失敗，原因如下：
+ 不正確的 IAM 政策組態
+ 過期的安全登入資料
+ 網路連線問題
+ 資料庫許可不相符

若要疑難排解這些身分驗證錯誤，請在 Amazon Relational Database Service (RDS) 或 Aurora 資料庫中啟用`iam-db-auth-error`日誌匯出功能。這可讓您在 Amazon RDS 或 Amazon Aurora 叢集的 CloudWatch Log 群組中檢視詳細的身分驗證錯誤訊息。

啟用後，您可以檢閱這些日誌，以識別和解決 IAM 身分驗證失敗的特定原因。

例如：

```
2025-09-22T12:02:30,806 [ERROR] Failed to authorize the connection request for user 'user_1' due to an internal IAM DB Auth error. (Status Code: 500, Error Code: InternalError)
```

以及

```
2025-09-22T12:02:51,954 [ERROR] Failed to authenticate the connection request for user 'user_2' because the provided token is malformed or otherwise invalid. (Status Code: 400, Error Code: InvalidToken)
```

如需疑難排解指引，請參閱 IAM 資料庫身分驗證的 [Aurora](UsingWithRDS.IAMDBAuth.Troubleshooting.md) 疑難排解指南。

# 針對 Aurora MySQL 資料庫的查詢效能進行故障診斷
<a name="aurora-mysql-troubleshooting-query"></a>

MySQL 透過系統變數提供[查詢最佳化工具控制](https://dev.mysql.com/doc/refman/8.0/en/controlling-optimizer.html)，這些變數會影響查詢計劃的評估方式、可切換最佳化、最佳化工具與索引提示，以及最佳化工具成本模型。這些資料點不僅可以比較不同的 MySQL 環境，還可以比較先前的查詢執行計劃與目前的執行計劃，以及了解 MySQL 查詢在任何時間點的整體執行。

查詢效能取決於許多因素，包括執行計劃、資料表結構描述和大小、統計資料、資源、索引和參數組態。查詢調校需要識別瓶頸並最佳化執行路徑。
+ 尋找查詢的執行計劃，並檢查查詢是否使用適當的索引。您可以使用 `EXPLAIN` 並檢閱每個計劃的詳細資訊，以最佳化查詢。
+ Aurora MySQL 第 3 版 (與 MySQL 8.0 Community Edition 相容) 使用 `EXPLAIN ANALYZE` 陳述式。`EXPLAIN ANALYZE` 陳述式是一種分析工具，可顯示 MySQL 在查詢上花費的時間和原因。透過 `EXPLAIN ANALYZE`，Aurora MySQL 會規劃、準備和執行查詢，同時計數資料列並測量在執行計劃的各個點所花費的時間。查詢完成時，`EXPLAIN ANALYZE` 會列印計劃及其測量結果，而不是查詢結果。
+ 使用 `ANALYZE` 陳述式來更新您的結構描述統計資料。由於統計資料過時，查詢最佳化工具有時可以選擇不佳的執行計劃。這可能會導致查詢效能不佳，因為資料表和索引的基數預估不正確。[innodb\$1table\$1stats](https://dev.mysql.com/doc/refman/8.0/en/innodb-persistent-stats.html#innodb-persistent-stats-tables) 資料表的 `last_update` 欄會顯示您的結構描述統計資料上次更新的時間，這是「過時」的良好指標。
+ 可能會發生其他問題，例如未考慮資料表基數的資料分佈扭曲。如需詳細資訊，請參閱 MySQL 文件中的[估算 InnoDB 資料表的 ANALYZE TABLE 複雜性](https://dev.mysql.com/doc/refman/8.0/en/innodb-analyze-table-complexity.html)和 [MySQL 中的直方圖統計資料](https://dev.mysql.com/blog-archive/histogram-statistics-in-mysql/)。

## 了解查詢所花費的時間
<a name="ams-query-time"></a>

以下是判斷查詢所花費時間的方法：
+ [分析](https://dev.mysql.com/doc/refman/8.0/en/show-profile.html)
+ [效能結構描述](https://dev.mysql.com/doc/refman/8.0/en/performance-schema.html)
+ [查詢最佳化工具](https://dev.mysql.com/doc/refman/8.0/en/controlling-optimizer.html)

**分析**  
根據預設，分析已停用。啟用分析，然後執行緩慢查詢並檢閱其設定檔。  

```
SET profiling = 1;
Run your query.
SHOW PROFILE;
```

1. 識別花費最多時間的階段。根據 MySQL 文件中的[一般執行緒狀態](https://dev.mysql.com/doc/refman/8.0/en/general-thread-states.html)，讀取和處理 `SELECT` 陳述式的資料列通常是指定查詢生命週期中執行時間最長的狀態。您可以使用 `EXPLAIN` 陳述式來了解 MySQL 如何執行此查詢。

1. 檢閱緩慢查詢日誌以評估 `rows_examined` 和 `rows_sent`，以確保工作負載在每個環境中都類似。如需詳細資訊，請參閱[記錄 Aurora MySQL 資料庫](aurora-mysql-troubleshooting-logging.md)。

1. 針對屬於已識別查詢一部分的資料表執行下列命令：

   ```
   SHOW TABLE STATUS\G;
   ```

1. 在每個環境上執行查詢之前和之後擷取下列輸出：

   ```
   SHOW GLOBAL STATUS;
   ```

1. 在每個環境上執行下列命令，以查看是否有任何其他查詢/工作階段會影響此範例查詢的效能。

   ```
   SHOW FULL PROCESSLIST;
   
   SHOW ENGINE INNODB STATUS\G;
   ```

   有時，當伺服器上的資源忙碌時，它會影響伺服器上的所有其他操作，包括查詢。您也可以在執行查詢或設定 `cron` 任務時定期擷取資訊，以有用的間隔擷取資訊。

**效能結構描述**  
效能結構描述提供有關伺服器執行時期效能的實用資訊，同時對該效能的影響最小。這與提供資料庫執行個體相關結構描述資訊的 `information_schema` 不同。如需詳細資訊，請參閱[Aurora MySQL 上 Performance Insights 的效能結構描述概觀](USER_PerfInsights.EnableMySQL.md)。

**查詢最佳化工具追蹤**  
若要了解為何[選擇特定查詢計劃執行](https://dev.mysql.com/doc/refman/8.0/en/execution-plan-information.html)，您可以設定 `optimizer_trace` 來存取 MySQL 查詢最佳化工具。  
執行最佳化工具追蹤，以顯示最佳化工具及其選擇可用的所有路徑的廣泛資訊。  

```
SET SESSION OPTIMIZER_TRACE="enabled=on"; 
SET optimizer_trace_offset=-5, optimizer_trace_limit=5;

-- Run your query.
SELECT * FROM table WHERE x = 1 AND y = 'A';

-- After the query completes:
SELECT * FROM information_schema.OPTIMIZER_TRACE;
SET SESSION OPTIMIZER_TRACE="enabled=off";
```

## 檢閱查詢最佳化工具設定
<a name="ams-query-parameters"></a>

相較於 Aurora MySQL 第 2 版 (與 MySQL 5.7 Community Edition 相容)，Aurora MySQL 第 3 版 (與 MySQL 8.0 Community Edition 相容) 有許多最佳化工具相關的變更。如果您有 `optimizer_switch` 的一些自訂值，建議您檢閱預設值的差異，並設定最適合工作負載的 `optimizer_switch` 值。我們也建議您測試 Aurora MySQL 第 3 版可用的選項，以檢查您的查詢如何執行。

**注意**  
Aurora MySQL 第 3 版針對 [innodb\$1stats\$1persistent\$1sample\$1pages](https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_stats_persistent_sample_pages) 參數使用社群預設值 20。

您可以使用下列命令來顯示 `optimizer_switch` 值：

```
SELECT @@optimizer_switch\G;
```

下表顯示 Aurora MySQL 第 2 版和第 3 版的預設 `optimizer_switch` 值。


| 設定 | Aurora MySQL 第 2 版 | Aurora MySQL 第 3 版 | 
| --- | --- | --- | 
| batched\$1key\$1access | off | off | 
| block\$1nested\$1loop | on | on | 
| condition\$1fanout\$1filter | on | on | 
| derived\$1condition\$1pushdown | – | on | 
| derived\$1merge | on | on | 
| duplicateweedout | on | on | 
| engine\$1condition\$1pushdown | on | on | 
| firstmatch | on | on | 
| hash\$1join | off | on | 
| hash\$1join\$1cost\$1based | on | – | 
| hypergraph\$1optimizer | – | off | 
| index\$1condition\$1pushdown | on | on | 
| index\$1merge | on | on | 
| index\$1merge\$1intersection | on | on | 
| index\$1merge\$1sort\$1union | on | on | 
| index\$1merge\$1union | on | on | 
| loosescan | on | on | 
| materialization | on | on | 
| mrr | on | on | 
| mrr\$1cost\$1based | on | on | 
| prefer\$1ordering\$1index | on | on | 
| semijoin | on | on | 
| skip\$1scan | – | on | 
| subquery\$1materialization\$1cost\$1based | on | on | 
| subquery\$1to\$1derived | – | off | 
| use\$1index\$1extensions | on | on | 
| use\$1invisible\$1indexes | – | off | 

如需詳細資訊，請參閱 MySQL 文件中的[切換最佳化 (MySQL 5.7)](https://dev.mysql.com/doc/refman/5.7/en/switchable-optimizations.html) 和[切換最佳化 (MySQL 8.0)。](https://dev.mysql.com/doc/refman/8.0/en/switchable-optimizations.html)