type
status
date
slug
summary
tags
category
icon
password
症狀
當執行語句時,返回
ERROR 1114 (HY000): The table '/tmp/#sql1967_9_3' is full
錯誤,但是 Disk 仍有充足的空間:我們都知道當 tempoary table 使用的 memory 不足夠時會轉換到 disk 上操作,因此照理來說只有當 memory、disk 都不足夠時才應該出現這類錯誤訊息。
原因
前置知識 - 關於 internal tempoary table 的引擎
在 8.0.13 版本之前,是使用 MEMORY 引擎來建立 internal tempoary table,其不足之處在於不支援可變長度的資料型態,這導致了以下問題:
- 當欄位出現 TEXT、BLOB 型態會直接改為在 disk 上建立 tempoary table。
- 對於 VARCHAR 型態總會映射為 CHAR 型態,導致內存浪費。
因此在 8.0.13 開始引進了 TempTable 引擎解決這些問題,且預設 internal tempoary table 使用 TempTable 引擎。
BUG 細節
當使用 temporary table 進行 aggregation 操作情況下,如果
group-by
欄位的值已經存在則會 update
該行,否則會 insert
新的一行。從 bug#99100 說明中可以看到回報者透過 gdb 發現,當 temporary table(TempTable 引擎) 在進行
update
操作 (table()->file->ha_update_row) 時,消耗的 memory 如果超過 temptable_max_ram 會直接就拋出 HA_ERR_RECORD_FILE_FULL 的錯誤。temptable_max_ram:所有的 internal tempoary table(TempTable) 的最大內存使用量
也就是說在 TempTable 引擎下,雖然
insert
操作會在 memory 不足時轉到 Disk 上操作,但是 update
操作並沒有而是直接返回錯誤。觸發情境
版本:MySQL 8.0.13~8.0.26
當使用到
internal tempoary table
(Using tempoary) 進行 aggregation
操作,且當包含可變長度欄位 (例如:varchar) 時,就有可能會因為 temptable_max_ram
不足夠,即使 Disk 空間足夠也會引發此錯誤。修正方案
- 此 BUG 在 8.0.27 中修復,因此可以透過升級修正:
InnoDB: A query that used a temporary table for aggregation exhausted the memory available to the TempTable storage engine, causing an update operation to fail with a table is full error. (Bug #31117893, Bug #99100)
https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-27.html
修正方案根據 github 內修正的 commit 上說明:
當使用 temporary table 進行 aggregation 操作情況下,如果 group-by 欄位的值已經存在則會
update
該行,否則會 insert
新的一行。
如果 temporary table 中包含可變長度欄位(例如:varchar),則 TempTable 在實現時可能會在 update
操作耗盡 memory。
修正方案是當發生此狀況時將 tempoary table 移動到 disk 上並重新執行剛剛的 update 操作。- 暫時將
internal_tmp_mem_storage_engine
由TempTable
調整為Memory
: