

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

# Aurora MySQL 第 3 版的新暫時資料表行為
<a name="ams3-temptable-behavior"></a>

Aurora MySQL 第 3 版會以與舊版 Aurora MySQL 不同的方式處理暫時資料表。這種新行為是從 MySQL 8.0 社群版繼承的。有兩種類型的暫時資料表可以使用 Aurora MySQL 第 3 版建立：
+ 內部 (或*隱含*) 暫時資料表 – 由 Aurora MySQL 引擎建立，可處理如排序彙總、衍生資料表，或通用資料表表達式 (CTE) 等操作。
+ 使用者建立 (或*明確*) 的暫時資料表 –當您使用 `CREATE TEMPORARY TABLE` 陳述式時由 Aurora MySQL 引擎建立。

Aurora 讀取器資料庫執行個體上的內部暫時資料表和使用者建立的暫時資料表皆有其他注意事項。我們會在下列各節討論這些變更。

**Topics**
+ [內部 (隱含) 暫時資料表的儲存引擎](#ams3-temptable-behavior-engine)
+ [限制記憶體內部暫存資料表的大小](#ams3-temptable-behavior-limit)
+ [緩解 Aurora 複本上內部暫時資料表的完整性問題](#ams3-temptable-behavior-mitigate)
+ [在 Aurora MySQL 資料庫執行個體上最佳化 temptable\_max\_mmap 參數](#ams-optimize-temptable_max_mmap)
+ [讀取器資料庫執行個體上的使用者建立 (明確) 的暫時資料表](#ams3-temptable-behavior.user)
+ [暫時資料表建立時發生的錯誤和緩解措施](#ams3-temptable-behavior.errors)

## 內部 (隱含) 暫時資料表的儲存引擎
<a name="ams3-temptable-behavior-engine"></a>

產生中繼結果集時，Aurora MySQL 一開始會嘗試寫入記憶體內暫時資料表。這可能不成功，因為資料類型不相容或設定了限制。若是如此，則暫存資料表會轉換為磁碟上暫存資料表，而不是保留在記憶體中。如需詳細資訊，請參閱 MySQL 文件中的 [MySQL 中內部暫時資料表的使用](https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html)。

在 Aurora MySQL 第 3 版中，內部暫時資料表的運作方式與早期的 Aurora MySQL 版本不同。現在您可以在 與 InnoDB 儲存引擎之間進行選擇，而不是為這類暫時資料表，在 `TempTable` 和 `MEMORY` 儲存引擎之間進行選擇。

使用 `TempTable` 儲存引擎，您可以另外選擇如何處理特定資料。受影響的資料溢出記憶體集區，此記憶體集區保留資料庫執行個體的所有內部暫時資料表。

這些選擇可能會影響產生大量暫存資料之查詢的效能，例如在大型資料表上執行彙總 (例如 `GROUP BY`) 時。

**提示**  
如果您的工作負載包含產生內部暫時資料表的查詢，請執行基準化分析並監控效能相關指標，以確認您的應用程式如何搭配此變更執行。  
在某些情況下，暫存資料量容納於 `TempTable` 記憶體集區內，或僅少量溢出記憶體集區。在這些情況下，我們建議將 `TempTable` 設定用於內部暫時資料表，並使用記憶體映射檔案來保留任何溢位資料。此設定是預設值。

`TempTable` 儲存引擎是預設值。`TempTable` 會針對使用此引擎的所有暫時資料表使用一般記憶體集區，而不是每個資料表的最大記憶體限制。此記憶體集區的大小是由 [temptable\_max\_ram](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_temptable_max_ram) 參數指定。其在具有 16 GiB 或更多記憶體的資料庫執行個體上預設為 1 GiB，而在記憶體少於 16 GiB 的資料庫執行個體上則預設為 16 MB。記憶體集區的大小會影響工作階段層級的記憶體耗用量。

在某些情況下，當您使用 `TempTable` 儲存引擎時，暫存資料可能會超過記憶體集區的大小。若是如此，Aurora MySQL 會使用次要機制來存放溢位資料。

您可以設定 [temptable\_max\_mmap](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_temptable_max_mmap) 參數來指定資料是否溢出到記憶體對應的暫存檔案，還是溢出到磁碟上的 InnoDB 內部暫時資料表。這些溢位機制的不同資料格式和溢位準則可能會影響查詢效能。它們會藉由影響寫入至磁碟的資料量以及對磁碟儲存輸送量的需求來達到此目的。

Aurora MySQL 第 3 版會以下列方式存放溢出資料：
+ 在寫入器資料庫執行個體上，溢出至 InnoDB 內部暫存資料表或記憶體映射暫存檔案的資料會存放在執行個體上的本機儲存體中。
+ 在讀取器執行個體上，溢出資料始終位於本機儲存上的記憶體映射暫存檔中。

  唯讀執行個體無法在 Aurora 叢集磁碟區上存放任何資料。

與內部暫時資料表相關的組態參數會以不同方式套用至叢集中的寫入器和讀取器執行個體：
+ 在讀取器執行個體上，MySQL Aurora 始終使用 `TempTable` 儲存引擎。
+ 對於寫入器和讀取器執行個體，不論資料庫執行個體的記憶體大小為何，`temptable_max_mmap` 的大小都會預設為 1 GiB。您可以在寫入器和讀取器執行個體上調整此值。
+ 將 `temptable_max_mmap` 設為 `0` 會關閉在寫入器執行個體上使用記憶體映射暫存檔案的功能。
+ 您無法在讀取器執行個體上將 `temptable_max_mmap` 設為 `0`。

**注意**  
我們不建議使用 [temptable\_use\_mmap](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_temptable_use_mmap) 參數。該參數已被棄用，且預計未來的 MySQL 版本不會再支援該參數。

## 限制記憶體內部暫存資料表的大小
<a name="ams3-temptable-behavior-limit"></a>

正如 [內部 (隱含) 暫時資料表的儲存引擎](#ams3-temptable-behavior-engine) 中所討論，您可以使用 [temptable\_max\_ram](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_temptable_max_ram) 和 [temptable\_max\_mmap](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_temptable_max_mmap) 設定控制全域資源暫存資料表。

您也可以使用 [tmp\_table\_size](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tmp_table_size) 資料庫參數限制個別內部、記憶體內暫存資料表的大小。此限制是為了防止個別查詢耗用大量的全域資源暫存資料表資源，這可能會影響同時需要這些資源的查詢效能。

`tmp_table_size` 參數定義 `MEMORY` 儲存體引擎在 Aurora MySQL 3 版中建立暫存資料表的大小上限。

Aurora MySQL 3.04 版及更新版本中，`tmp_table_size` 還定義 `aurora_tmptable_enable_per_table_limit` 資料庫參數設定為 `ON` 時，`TempTable` 儲存體引擎建立臨時資料表的大小上限。此行為預設為停用 (`OFF`)，這與 Aurora MySQL 3.03 版及更低版本中的行為相同。
+ 當 `aurora_tmptable_enable_per_table_limit` 為 `OFF` 時，透過 `TempTable` 儲存體引擎建立記憶體內部暫存資料表不用考慮 `tmp_table_size`。

  但是，全域 `TempTable` 資源限制仍然適用。當全域 `TempTable` 資源達到限制時，Aurora MySQL 具有下列行為：
  + 寫入器資料庫執行個體 – Aurora MySQL 會自動將記憶體內暫存資料表轉換為 InnoDB 磁碟上的暫存資料表。
  + 讀取器資料庫執行個體 – 查詢因錯誤而結束。

    ```
    ERROR 1114 (HY000): The table '/rdsdbdata/tmp/#sql{{xx_xxx}}' is full
    ```
+ 當 `aurora_tmptable_enable_per_table_limit` 為 `ON` 時，全域 `tmp_table_size` 資源達到限制，Aurora MySQL 具有下列行為：
  + 寫入器資料庫執行個體 – Aurora MySQL 會自動將記憶體內暫存資料表轉換為 InnoDB 磁碟上的暫存資料表。
  + 讀取器資料庫執行個體 – 查詢因錯誤而結束。

    ```
    ERROR 1114 (HY000): The table '/rdsdbdata/tmp/#sql{{xx_xxx}}' is full
    ```

    在這種情況下，全域 `TempTable` 資源限制和每個資料表限制都適用。

**注意**  
當 [ internal\_tmp\_mem\_storage\_engine](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_internal_tmp_mem_storage_engine) 設定為 `MEMORY` 時，`aurora_tmptable_enable_per_table_limit` 參數沒有作用。在這種情況下，記憶體內暫存資料表的大小上限由 [tmp\_table\_size](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tmp_table_size) 或者 [max\_heap\_table\_size](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_heap_table_size) 值定義，以較小者為準。

下列範例顯示 `aurora_tmptable_enable_per_table_limit` 參數對寫入器和讀取器資料庫執行個體的行為。

**Example 或者將寫入器資料庫執行個體 `aurora_tmptable_enable_per_table_limit` 設定為 `OFF`**  
記憶體內的暫存資料表不會轉換為 InnoDB 磁碟上的暫存資料表。  

```
mysql> set aurora_tmptable_enable_per_table_limit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@innodb_read_only,@@aurora_version,@@aurora_tmptable_enable_per_table_limit,@@temptable_max_ram,@@temptable_max_mmap;
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
| @@innodb_read_only | @@aurora_version | @@aurora_tmptable_enable_per_table_limit | @@temptable_max_ram | @@temptable_max_mmap |
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
|                  0 | 3.04.0           |                                        0 |          1073741824 |           1073741824 |
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
1 row in set (0.00 sec)

mysql> show status like '%created_tmp_disk%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0     |
+-------------------------+-------+
1 row in set (0.00 sec)

mysql> set cte_max_recursion_depth=4294967295;
Query OK, 0 rows affected (0.00 sec)

mysql> WITH RECURSIVE cte (n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 60000000) SELECT max(n) FROM cte;
+----------+
| max(n)   |
+----------+
| 60000000 |
+----------+
1 row in set (13.99 sec)

mysql> show status like '%created_tmp_disk%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0     |
+-------------------------+-------+
1 row in set (0.00 sec)
```

**Example 或者將寫入器資料庫執行個體 `aurora_tmptable_enable_per_table_limit` 設定為 `ON`**  
記憶體內的暫存資料表會轉換為 InnoDB 磁碟上的暫存資料表。  

```
mysql> set aurora_tmptable_enable_per_table_limit=1;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@innodb_read_only,@@aurora_version,@@aurora_tmptable_enable_per_table_limit,@@tmp_table_size;
+--------------------+------------------+------------------------------------------+------------------+
| @@innodb_read_only | @@aurora_version | @@aurora_tmptable_enable_per_table_limit | @@tmp_table_size |
+--------------------+------------------+------------------------------------------+------------------+
|                  0 | 3.04.0           |                                        1 |         16777216 |
+--------------------+------------------+------------------------------------------+------------------+
1 row in set (0.00 sec)

mysql> set cte_max_recursion_depth=4294967295;
Query OK, 0 rows affected (0.00 sec)

mysql> show status like '%created_tmp_disk%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0     |
+-------------------------+-------+
1 row in set (0.00 sec)

mysql> WITH RECURSIVE cte (n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 6000000) SELECT max(n) FROM cte;
+---------+
| max(n)  |
+---------+
| 6000000 |
+---------+
1 row in set (4.10 sec)

mysql> show status like '%created_tmp_disk%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 1     |
+-------------------------+-------+
1 row in set (0.00 sec)
```

**Example 將讀取器資料庫執行個體 `aurora_tmptable_enable_per_table_limit` 設定為 `OFF`**  
查詢結束時沒有錯誤，因為 `tmp_table_size` 不適用，並且全域 `TempTable` 資源尚未達到限制。  

```
mysql> set aurora_tmptable_enable_per_table_limit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@innodb_read_only,@@aurora_version,@@aurora_tmptable_enable_per_table_limit,@@temptable_max_ram,@@temptable_max_mmap;
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
| @@innodb_read_only | @@aurora_version | @@aurora_tmptable_enable_per_table_limit | @@temptable_max_ram | @@temptable_max_mmap |
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
|                  1 | 3.04.0           |                                        0 |          1073741824 |           1073741824 |
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
1 row in set (0.00 sec)

mysql> set cte_max_recursion_depth=4294967295;
Query OK, 0 rows affected (0.00 sec)

mysql> WITH RECURSIVE cte (n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 60000000) SELECT max(n) FROM cte;
+----------+
| max(n)   |
+----------+
| 60000000 |
+----------+
1 row in set (14.05 sec)
```

**Example 將讀取器資料庫執行個體 `aurora_tmptable_enable_per_table_limit` 設定為 `OFF`**  
此查詢已達到全域 TempTable 資源限制，將 `aurora_tmptable_enable_per_table_limit` 設定為關閉。查詢因讀取器執行個體上發生錯誤而結束。  

```
mysql> set aurora_tmptable_enable_per_table_limit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@innodb_read_only,@@aurora_version,@@aurora_tmptable_enable_per_table_limit,@@temptable_max_ram,@@temptable_max_mmap;
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
| @@innodb_read_only | @@aurora_version | @@aurora_tmptable_enable_per_table_limit | @@temptable_max_ram | @@temptable_max_mmap |
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
|                  1 | 3.04.0           |                                        0 |          1073741824 |           1073741824 |
+--------------------+------------------+------------------------------------------+---------------------+----------------------+
1 row in set (0.00 sec)

mysql> set cte_max_recursion_depth=4294967295;
Query OK, 0 rows affected (0.01 sec)

mysql> WITH RECURSIVE cte (n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 120000000) SELECT max(n) FROM cte;
ERROR 1114 (HY000): The table '/rdsdbdata/tmp/#sqlfd_1586_2' is full
```

**Example 將讀取器資料庫執行個體 `aurora_tmptable_enable_per_table_limit` 設定為 `ON`**  
已達到 `tmp_table_size` 限制，查詢因發生錯誤而結束。  

```
mysql> set aurora_tmptable_enable_per_table_limit=1;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@innodb_read_only,@@aurora_version,@@aurora_tmptable_enable_per_table_limit,@@tmp_table_size;
+--------------------+------------------+------------------------------------------+------------------+
| @@innodb_read_only | @@aurora_version | @@aurora_tmptable_enable_per_table_limit | @@tmp_table_size |
+--------------------+------------------+------------------------------------------+------------------+
|                  1 | 3.04.0           |                                        1 |         16777216 |
+--------------------+------------------+------------------------------------------+------------------+
1 row in set (0.00 sec)

mysql> set cte_max_recursion_depth=4294967295;
Query OK, 0 rows affected (0.00 sec)

mysql> WITH RECURSIVE cte (n) AS (SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 6000000) SELECT max(n) FROM cte;
ERROR 1114 (HY000): The table '/rdsdbdata/tmp/#sqlfd_8_2' is full
```

## 緩解 Aurora 複本上內部暫時資料表的完整性問題
<a name="ams3-temptable-behavior-mitigate"></a>

若要避免發生暫時資料表的大小限制問題，請將 `temptable_max_ram` 和 `temptable_max_mmap` 參數設定為符合工作負載需求的合併值。

設定 `temptable_max_ram` 參數的值時請小心。將此值設定得過高，會減少資料庫執行個體上的可用記憶體，這可能會導致發生記憶體不足的狀況。監控資料庫執行個體上的平均可用記憶體。然後為 `temptable_max_ram` 決定適合的值，以便執行個體上仍能保留合理的可用記憶體量。如需詳細資訊，請參閱[Amazon Aurora 中的可用記憶體問題](CHAP_Troubleshooting.md#Troubleshooting.FreeableMemory)。

監控本機儲存空間的大小和暫時資料表空間的耗用狀況，也很重要。您可以使用 `FreeLocalStorage` Amazon CloudWatch 指標來監控特定資料庫執行個體可用的暫存空間，如 [Amazon Aurora 的 Amazon CloudWatch 指標](Aurora.AuroraMonitoring.Metrics.md) 中所述。

**注意**  
當 `aurora_tmptable_enable_per_table_limit` 參數設定為 `ON` 時，此程序不適用。如需詳細資訊，請參閱[限制記憶體內部暫存資料表的大小](#ams3-temptable-behavior-limit)。

**Example 1**  
您知識暫時資料表的大小會累積成長至 20 GiB。您希望將記憶體內暫時資料表設定為 2 GiB，並在磁碟上成長到上限 20 GiB。  
將 `temptable_max_ram` 設定為 **2,147,483,648**，將 `temptable_max_mmap` 設定為 **21,474,836,480**。這些值以位元組為單位。  
這些參數設定確保暫時資料表可累積成長到總共 22 GiB。

**Example 2**  
您目前的執行個體大小為 16xlarge 或以上。您不知道您可能需要的暫時資料表總大小。您希望能夠在記憶體中使用多達 4 GiB，最多達磁碟上的可用儲存空間大小上限。  
將 `temptable_max_ram` 設定為 **4,294,967,296**，將 `temptable_max_mmap` 設定為 **1,099,511,627,776**。這些值以位元組為單位。  
在此您將 `temptable_max_mmap` 設定為 1 TiB，這小於 16xlarge Aurora 資料庫執行個體上 1.2 TiB 的本機儲存空間上限。  
在大小較小的執行個體上，調整 `temptable_max_mmap` 的值，使其不會填滿可用的本機儲存空間。例如，一個 2xlarge 執行個體只有 160 GiB 的可用本機儲存空間。因此，建議將該值設定為小於 160 GiB。如需資料庫執行個體大小的可用本機儲存空間詳細資訊，請參閱 [Aurora MySQL 的暫存空間限制暫存空間限制](AuroraMySQL.Managing.Performance.md#AuroraMySQL.Managing.TempStorage)。

## 在 Aurora MySQL 資料庫執行個體上最佳化 temptable\_max\_mmap 參數
<a name="ams-optimize-temptable_max_mmap"></a>

Aurora MySQL 中的 `temptable_max_mmap` 參數控制記憶體映射檔案在溢出至磁碟上 InnoDB 暫存資料表 (寫入器資料庫執行個體上) 或導致錯誤 (讀取器資料庫執行個體上) 之前可使用的本機磁碟空間上限。正確設定此資料庫執行個體參數有助於最佳化資料庫執行個體的效能。

**先決條件**  

1. 確定已啟用效能結構描述。您可以透過執行以下 SQL 命令來進行確認。

   ```
   SELECT @@performance_schema;
   ```

   `1` 的輸出值表示已啟用。

1. 確認已啟用暫存資料表記憶體檢測。您可以透過執行以下 SQL 命令來進行確認。

   ```
   SELECT name, enabled FROM performance_schema.setup_instruments WHERE name LIKE '%memory%temptable%';
   ```

   `enabled` 欄會針對相關的暫存資料表記憶體檢測項目顯示 `YES`。

**監控暫存資料表用量**  
設定 `temptable_max_mmap` 的初始值時，建議您從使用的資料庫執行個體類別的本機儲存體大小的 80% 開始。這可確保暫存資料表有足夠的磁碟空間可有效運作，同時為執行個體上的其他磁碟使用保留空間。  
若要尋找資料庫執行個體類別的本機儲存體大小，請參閱 [Aurora MySQL 的暫存空間限制暫存空間限制](AuroraMySQL.Managing.Performance.md#AuroraMySQL.Managing.TempStorage)。  
例如，如果您使用的是 db.r5.large 資料庫執行個體類別，則本機儲存體大小為 32 GiB。在這種情況下，您一開始會將 `temptable_max_mmap` 參數設定為 32 GiB 的 80%，也就是 25.6 GiB。  
設定初始 `temptable_max_mmap` 值後，在 Aurora MySQL 執行個體上執行尖峰工作負載。使用下列 SQL 查詢監控目前和高暫存資料表磁碟用量：  

```
SELECT event_name, current_count, current_alloc, current_avg_alloc, high_count, high_alloc, high_avg_alloc
FROM sys.memory_global_by_current_bytes WHERE event_name LIKE 'memory/temptable/%';
```
此查詢會擷取下列資訊：  
+ `event_name` – 暫存資料表記憶體或磁碟用量事件的名稱。
+ `current_count` – 目前配置的暫存資料表記憶體或磁碟區塊數量。
+ `current_alloc` – 針對暫存資料表配置的目前記憶體或磁碟數量。
+ `current_avg_alloc` – 暫存資料表記憶體或磁碟區塊的目前平均大小。
+ `high_count` – 配置的暫存資料表記憶體或磁碟區塊數量上限。
+ `high_alloc` – 針對暫存資料表配置的最高記憶體或磁碟數量。
+ `high_avg_alloc` – 暫存資料表記憶體或磁碟區塊的平均大小上限。
如果您的查詢失敗，且使用此設定時發生資料表已滿錯誤，則表示您的工作負載需要更多磁碟空間來執行暫存資料表操作。在此情況下，請考慮將資料庫執行個體大小增加為具有更多本機儲存空間的執行個體大小。

**設定最佳 `temptable_max_mmap` 值**  
使用下列程序來監控和設定 `temptable_max_mmap` 參數的正確大小。  

1. 檢閱上一個查詢的輸出，並識別尖峰暫存資料表磁碟用量，如 `high_alloc` 欄所示。

1. 根據尖峰暫存資料表磁碟用量，調整 Aurora MySQL 資料庫執行個體資料庫參數群組中的 `temptable_max_mmap` 參數。

   將值設為稍微高於尖峰暫存資料表磁碟用量，以適應未來的成長。

1. 將參數群組變更套用至資料庫執行個體。

1. 在尖峰工作負載期間再次監控暫存資料表磁碟用量，以確保新 `temptable_max_mmap` 值是適當的。

1. 視需要重複上述步驟，以微調 `temptable_max_mmap` 參數。

## 讀取器資料庫執行個體上的使用者建立 (明確) 的暫時資料表
<a name="ams3-temptable-behavior.user"></a>

您可以在 `CREATE TABLE` 陳述式中使用 `TEMPORARY` 的關鍵字建立明確的暫時資料表。Aurora 資料庫叢集中寫入器資料庫執行個體支援明確暫時資料表。您也可以在讀取器資料庫執行個體上使用明確暫時資料表，但該資料表無法強制使用 InnoDB 儲存引擎。

若要避免在 Aurora MySQL 讀取器資料庫執行個體上建立明確暫時資料表時發生錯誤，請確定您以下列其中一種或兩種方式執行所有 `CREATE TEMPORARY TABLE` 陳述句：
+ 不指定 `ENGINE=InnoDB` 子句。
+ 不將 SQL 模式設為 `NO_ENGINE_SUBSTITUTION`。

## 暫時資料表建立時發生的錯誤和緩解措施
<a name="ams3-temptable-behavior.errors"></a>

您收到的錯誤會有所不同，取決於您使用純 `CREATE TEMPORARY TABLE` 陳述式，還是變異 `CREATE TEMPORARY TABLE AS SELECT`。下列範例顯示不同類型的錯誤。

此暫時資料表行為僅適用於唯讀執行個體。這個第一個範例確認其是工作階段連線到的執行個體類型。

```
mysql> select @@innodb_read_only;
+--------------------+
| @@innodb_read_only |
+--------------------+
|                  1 |
+--------------------+
```

對於純 `CREATE TEMPORARY TABLE` 陳述式，陳述式會在 `NO_ENGINE_SUBSTITUTION` SQL 模式開啟時失敗。當 `NO_ENGINE_SUBSTITUTION` 關閉時 (預設值),會進行適當的引擎替換，並會成功建立暫時資料表。

```
mysql> set sql_mode = 'NO_ENGINE_SUBSTITUTION';

mysql>  CREATE TEMPORARY TABLE tt2 (id int) ENGINE=InnoDB;
ERROR 3161 (HY000): Storage engine InnoDB is disabled (Table creation is disallowed).

mysql> SET sql_mode = '';

mysql> CREATE TEMPORARY TABLE tt4 (id int) ENGINE=InnoDB;

mysql> SHOW CREATE TABLE tt4\G
*************************** 1. row ***************************
       Table: tt4
Create Table: CREATE TEMPORARY TABLE `tt4` (
  `id` int DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
```

對於 `CREATE TEMPORARY TABLE AS SELECT` 陳述式，陳述式會在 `NO_ENGINE_SUBSTITUTION` SQL 模式開啟時失敗。當 `NO_ENGINE_SUBSTITUTION` 關閉時 (預設值),會進行適當的引擎替換，並會成功建立暫時資料表。

```
mysql> set sql_mode = 'NO_ENGINE_SUBSTITUTION';

mysql> CREATE TEMPORARY TABLE tt1 ENGINE=InnoDB AS SELECT * FROM t1;
ERROR 3161 (HY000): Storage engine InnoDB is disabled (Table creation is disallowed).

mysql> SET sql_mode = '';

mysql> show create table tt3;
+-------+----------------------------------------------------------+
| Table | Create Table                                             |
+-------+----------------------------------------------------------+
| tt3   | CREATE TEMPORARY TABLE `tt3` (
  `id` int DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+----------------------------------------------------------+
1 row in set (0.00 sec)
```

如需有關 Aurora MySQL 第 3 版中臨時資料表儲存方面和效能影響的詳細資訊，請參閱部落格文章 [Use the TempTable storage engine on Amazon RDS for MySQL and Amazon Aurora MySQL](https://aws.amazon.com/blogs/database/use-the-temptable-storage-engine-on-amazon-rds-for-mysql-and-amazon-aurora-mysql/) (在 Amazon RDS for MySQL 和 Amazon Aurora MySQL 上使用 TempTable 儲存引擎)。