Error 28 (No space left on device) 深度排查:根分區滿導致臨時表無法建立
執行 SHOW TRIGGERS 等需要建立內部臨時表的操作時,報錯 ERROR 1030 (HY000): Got error 28 from storage engine,伴隨 Error on delete of '/tmp/#sql_xxx.MYI' (Errcode: 2)。本文詳細排查流程與解決方案。
錯誤碼對照
| 錯誤碼 | 含義 | MySQL 映射 |
| OS Error 28 | No space left on device | Got error 28 from storage engine |
| OS Error 2 | No such file or directory | Error on delete of '/tmp/#sql...' (Errcode: 2) |
排查步驟實錄
- 查看具體錯誤碼**:
mysql> \! perror 28
OS error code 28: No space left on device
mysql> \! perror 2
OS error code 2: No such file or directory
- 檢查磁碟空間**:
[root@server ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 4.9G 4.9G 0 100% / ← 根分區滿!
tmpfs 252M 0 252M 0% /dev/shm
/dev/sdb1 9.9G 2.8G 6.6G 30% /opt/sdb ← MySQL 數據在這裡,有空間
- 確認臨時目錄位置**:
mysql> SHOW VARIABLES LIKE 'tmpdir';
+-------+------+
| Variable_name | Value |
+-------+------+
| tmpdir | /tmp ← 落在根分區!
+-------+------+
MySQL 內部操作 (SHOW TRIGGERS、複雜排序、ALTER TABLE、內部臨時表) 在 tmpdir 建立臨時檔案,根分區滿 → 無法建立 → Error 28。
- 清理根分區空間**:
# 清理日誌、快取、舊核心、臨時檔
journalctl --vacuum-time=7d
yum clean all
rm -rf /tmp/*
rm -rf /var/tmp/*
# 或遷移大目錄到數據盤並軟連結
- 驗證恢復**:
[root@server ~]# df -h
/dev/sda1 4.9G 3.5G 1.1G 77% / ← 釋放空間
mysql> SHOW TRIGGERS; ← 正常返回
根因總結
- MySQL 數據目錄在
/opt/sdb (數據盤),但 tmpdir 指向 /tmp (根分區)
- 根分區僅 5GB,系統日誌、核心更新、套件快取長期累積耗盡
- 操作需建立臨時表 (如
SHOW TRIGGERS、ORDER BY 大結果集、ALTER TABLE) 時在 tmpdir 寫入失敗
- Error 28 是 OS 層面「磁碟滿」,非 MySQL 邏輯錯誤
永久解決方案
| 方案 | 操作 | 優缺點 |
| 遷移 tmpdir 到數據盤 | mkdir -p /opt/sdb/tmp && chown mysql:mysql /opt/sdb/tmp && chmod 1777 /opt/sdb/tmp
my.cnf: tmpdir = /opt/sdb/tmp 重啟 MySQL | ✅ 徹底解決,推薦 |
| 擴容根分區 | LVM 擴容、新增磁碟掛載、遷移大目錄 | ⚠️ 需停機/風險較大 |
| 定期清理腳本 | cron 清理 /var/log、/tmp、yum cache、journald | 🔧 輔助手段,治標不治本 |
| 監控告警 | Prometheus node_filesystem_avail_bytes < 10% 告警 | 🔔 預防複發 |
相關參數與最佳實踐
tmpdir:支援多目錄輪詢 tmpdir = /path1:/path2:/path3 (冒號分隔)
slave_load_tmpdir:Replica 執行 LOAD DATA 臨時目錄,同理需空間充足
innodb_tmpdir (8.0+):InnoDB 臨時表空間目錄,獨立於 tmpdir
- 臨時表引擎:
internal_tmp_mem_storage_engine (8.0+) 可選 TempTable (預設、記憶體) 或 MyISAM (磁碟)
舉一反三:其他「磁碟滿」異常表現
ERROR 3 (HY000): Error writing file './db/tbl.MYD' (Errcode: 28) — 數據盤滿
InnoDB: Write to file ./ibdata1 failed — 系統表空間盤滿
Binlog 沒有切換、Replica SQL Thread 停止 — Relay log 盤滿
mysqldump 導出中斷 — 目標備份盤滿
核心認知:MySQL 多處依賴臨時檔案寫入,**tmpdir/數據目錄/Binlog目錄/備份目錄** 任一分區滿即導致服務異常。生產環境必須**分盤規劃、獨立監控、預留 20%+ 餘量**。
- 上一篇文章: MySQL Proxy 讀寫分離 Lua 腳本遷坑指南:rwsplitting 升級、Prepare 模式、Keepalive 高可用
- 下一篇文章: mysqldump 導出觸發器重複導入錯誤:--triggers=false 解決方案
Copyright ©
程式碼之家 All Rights Reserved