MySQL8.0臨時表空間的使用及解讀
以下的這段文檔是 MySQL 8.0+ 中關于 InnoDB 臨時表空間(Temporary Tablespaces) 的詳細說明。
它分為兩個部分:會話級臨時表空間(Session Temporary Tablespaces) 和 全局臨時表空間(Global Temporary Tablespace)。
下面我們用通俗易懂的方式,結合系統(tǒng)原理和實際運維場景,來深入理解這個機制。
一、核心概念:為什么需要“臨時表空間”?
在 MySQL 執(zhí)行復雜查詢時(如排序、分組、連接、子查詢等),內存不夠用時就會將中間數據寫入磁盤——這些數據存儲在 “臨時表” 中。
這些臨時表也需要存儲引擎支持,就像普通表一樣。
從 MySQL 8.0.16 起,InnoDB 成為磁盤臨時表的默認存儲引擎(之前是 MyISAM),因此引入了專門的 InnoDB 臨時表空間機制 來高效管理這些臨時數據。
二、InnoDB 臨時表空間的兩種類型
| 類型 | 名稱 | 文件 | 用途 |
|---|---|---|---|
| ? 會話級臨時表空間 | Session Temporary Tablespaces | temp_N.ibt | 存儲用戶創(chuàng)建的臨時表 + 優(yōu)化器生成的內部臨時表 |
| ? 全局臨時表空間 | Global Temporary Tablespace | ibtmp1 | 存儲臨時表的“回滾段”(rollback segments) |
重點:這兩個表空間都只用于 臨時表(temporary tables),不是普通表!
1. 會話級臨時表空間(Session Temporary Tablespaces)
作用:
存放每個連接(session)中創(chuàng)建的:
- 用戶定義的臨時表:
CREATE TEMPORARY TABLE ... - 優(yōu)化器自動創(chuàng)建的內部臨時表(用于排序、JOIN 等操作)
? 從 MySQL 8.0.16 開始,這些臨時表默認使用 InnoDB 引擎,而不是以前的 MyISAM。
工作機制:
啟動時創(chuàng)建一個“池子”:
- MySQL 啟動時會預先創(chuàng)建 10 個臨時表空間文件(
.ibt),組成一個“池” - 默認路徑:
datadir/#innodb_temp/ - 文件名如:
temp_1.ibt,temp_2.ibt, …,temp_10.ibt - 每個文件初始大小為 5 個 InnoDB 頁面(比如
innodb_page_size=16K→ 5×16K = 80KB)
會話需要時分配:
- 當某個連接第一次需要創(chuàng)建磁盤臨時表時,MySQL 從池中分配最多 2 個表空間 給該會話:
- 1 個用于 用戶創(chuàng)建的臨時表
- 1 個用于 優(yōu)化器創(chuàng)建的內部臨時表
- 這些表空間在整個會話期間被復用
會話結束時回收:
- 客戶端斷開連接后,這兩個表空間被 清空(truncated)并放回池中
- 文件不會被刪除,只是內容清空,下次可再分配
動態(tài)擴容池子:
- 如果 10 個不夠用,MySQL 會自動創(chuàng)建更多
temp_N.ibt文件 - 池子大小永不收縮,即使負載下降也不會刪掉多余的文件
空間 ID 不持久:
- 所有臨時表空間的
space_id是臨時分配的 - 每次重啟 MySQL,這些 ID 都會重新分配,可能重復使用舊值
配置參數
[mysqld] # 設置臨時表空間池的目錄(必須存在) innodb_temp_tablespaces_dir = /path/to/temp/dir
默認值:datadir/#innodb_temp
示例查看:
cd /var/lib/mysql/#innodb_temp ls # 輸出示例: # temp_1.ibt temp_2.ibt ... temp_10.ibt
查看元數據
-- 查看所有會話臨時表空間信息 SELECT * FROM INFORMATION_SCHEMA.INNODB_SESSION_TEMP_TABLESPACES; -- 查看當前活躍的用戶臨時表 SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO;
2. 全局臨時表空間(Global Temporary Tablespace)——ibtmp1
作用
- 存儲 所有臨時表的“回滾段”(rollback segments)
- 回滾段用于支持事務:
INSERT,UPDATE,DELETE臨時表時的 undo log
注意:ibtmp1 不存儲臨時表的數據本身,只存它的事務日志(undo logs)!
生命周期
- 每次正常啟動時創(chuàng)建
- 每次正常關閉時刪除
- 如果異常宕機,
ibtmp1可能殘留,但下次啟動時會被自動刪除并重建
文件特性
- 默認文件名:
ibtmp1 - 默認路徑:由
innodb_data_home_dir決定(通常是datadir) - 初始大?。杭s 12MB
- 支持自動擴展(autoextend)
- 不能放在裸設備(raw device)上
配置參數
[mysqld] # 自定義全局臨時表空間配置 innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:500M
參數說明:
ibtmp1: 文件名12M: 初始大小autoextend: 允許自動增長max:500M: 最大不超過 500MB
? 修改此參數必須重啟 MySQL!
查看ibtmp1狀態(tài)
-- 查看是否自動擴展 SELECT @@innodb_temp_data_file_path; -- 查看當前大小、已用空間等 SELECT FILE_NAME, TABLESPACE_NAME, ENGINE, INITIAL_SIZE, TOTAL_EXTENTS * EXTENT_SIZE AS CurrentSizeBytes, DATA_FREE, MAXIMUM_SIZE FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME = 'innodb_temporary';
輸出示例:
FILE_NAME: ./ibtmp1 TABLESPACE_NAME: innodb_temporary CurrentSizeBytes: 104857600 -- 當前 100MB DATA_FREE: 50331648 -- 還有 48MB 可擴展 MAXIMUM_SIZE: 524288000 -- 最大 500MB
三、關鍵特性總結
| 特性 | 會話級臨時表空間(temp_N.ibt) | 全局臨時表空間(ibtmp1) |
|---|---|---|
| ? 文件名 | temp_*.ibt | ibtmp1 |
| ? 路徑配置 | innodb_temp_tablespaces_dir | innodb_temp_data_file_path |
| ? 是否自動創(chuàng)建 | 是(啟動時) | 是(啟動時) |
| ? 是否自動刪除 | 是(正常關閉) | 是(正常關閉) |
| ? 是否可殘留 | 否 | 是(異常宕機時) |
| ? 是否自動重建 | 是 | 是(重啟時) |
| ? 是否支持 autoextend | 否(固定大?。?/td> | 是(可配置) |
| ? 存儲內容 | 臨時表數據(用戶/內部) | 臨時表的回滾段(undo logs) |
| ? 是否可手動清理 | ?(自動管理) | ?(重啟 MySQL 即可) |
四、如何清理臨時表空間占用的空間?
問題:ibtmp1越來越大怎么辦?
由于 ibtmp1 是自動擴展的,長時間運行后可能達到幾十 GB。
解決方案:重啟 MySQL 服務
# 重啟后 ibtmp1 會按配置重新創(chuàng)建 systemctl restart mysql
?? 注意:重啟會影響業(yè)務,需安排在維護窗口。
更優(yōu)方案:限制最大大小
[mysqld] innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G
這樣即使負載高,也不會無限增長。
五、主從復制中的特殊行為
在 基于語句的復制(SBR) 模式下:
- 從庫(replica)上的臨時表統(tǒng)一存放在 一個共享的會話臨時表空間中
- 這個空間不會在會話斷開時釋放
- 只有在 MySQL 服務關閉時才會被清空
潛在風險:從庫上長期運行的復制可能導致臨時表空間堆積。
建議:
- 使用 混合模式(MIXED)或基于行的復制(RBR)
- 避免在主庫上長時間使用臨時表
六、最佳實踐建議
| 場景 | 建議 |
|---|---|
| ? 生產環(huán)境部署 | 將 #innodb_temp 和 ibtmp1 放在獨立磁盤(如 SSD) |
| ? 防止磁盤爆滿 | 設置 max 限制:ibtmp1:12M:autoextend:max:5G |
| ? 監(jiān)控空間使用 | 定期查詢 INFORMATION_SCHEMA.FILES 表 |
| ? 手動清理 | 計劃性重啟 MySQL(或使用 ALTER INSTANCE ROTATE INNODB MASTER KEY 觸發(fā)重建?不適用) |
| ? 避免濫用臨時表 | 優(yōu)化 SQL,減少 ORDER BY, GROUP BY, DISTINCT 導致的磁盤臨時表 |
| ? 權限控制 | 臨時表空間不受普通數據庫權限控制,注意安全 |
總結:一句話理解
InnoDB 臨時表空間分為兩部分:
temp_N.ibt(會話級):存放臨時表的數據,每個連接用完就還,像“臨時工位”ibtmp1(全局):存放臨時表的事務日志(undo),像“臨時檔案室”
它們都在 MySQL 啟動時創(chuàng)建、關閉時刪除,重啟即可釋放所有空間,是完全自動管理的“一次性”資源。
如果你關心:
- 如何監(jiān)控
ibtmp1增長趨勢? - 如何判斷是否因臨時表導致性能下降?
- 如何優(yōu)化 SQL 減少臨時表使用?
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SQL實現(xiàn)LeetCode(181.員工掙得比經理多)
這篇文章主要介紹了SQL實現(xiàn)LeetCode(181.員工掙得比經理多),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-08-08
MySQL優(yōu)化器追蹤(Optimizer Trace)的使用小結
MySQL OptimizerTrace 是用于分析查詢優(yōu)化器決策過程的工具,通過輸出JSON格式的詳細執(zhí)行信息,幫助開發(fā)者理解優(yōu)化器如何選擇執(zhí)行計劃,感興趣的可以了解一下2025-08-08
IDEA使用mybatis-generator及配上mysql8.0.3版本遇到的bug
這篇文章主要介紹了IDEA使用mybatis-generator以及配上mysql8.0.3版本遇到的問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
MYSQL 5.6 從庫復制的部署和監(jiān)控的實現(xiàn)
這篇文章主要介紹了MYSQL 5.6 從庫復制的部署和監(jiān)控的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12
MYSQL5.6.33數據庫主從(Master/Slave)同步安裝與配置詳解(Master-Linux Slave-w
這篇文章主要為大家詳細介紹了MYSQL5.6.33數據庫主從(Master/Slave)同步安裝與配置,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06

