首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL Server「文件組 DEFAULT 磁碟空間不足,無法為 TEMPDB 分配新頁」根因與解決

     編輯:MySQL 資料庫相關知識

錯誤訊息:

由於文件組 'DEFAULT' 中的磁盤空間不足,無法為數據庫 'TEMPDB' 分配新頁

實際磁碟剩餘 40GB,但 tempdb.mdf 僅 4GB 即報錯 → 根因:資料檔所在磁碟分區為 FAT32,單檔限制 4GB。

緊急處理 (恢復服務)

  1. 重啟 SQL Server 服務,tempdb 會重建回初始大小 (預設 8MB)。
  2. 若無法重啟,執行縮減:
DBCC SHRINKFILE (tempdev, 10);  -- 縮至 10MB
DBCC SHRINKFILE (templog, 10);
  1. 立即設定 tempdev、templog 最大值 4000 MB (略低於 4GB 限制)。

根治方案

  1. 轉換檔案系統為 NTFS (無資料損失):
    convert X: /fs:ntfs (需排程重啟)。
  2. 新增多個 tempdb 資料檔分散 I/O (最佳實踐):
ALTER DATABASE tempdb ADD FILE (NAME = tempdev2, FILENAME = 'X:\MSSQL\Data\tempdev2.ndf', SIZE = 100MB, MAXSIZE = 4000MB, FILEGROWTH = 100MB);
ALTER DATABASE tempdb ADD FILE (NAME = tempdev3, FILENAME = 'Y:\MSSQL\Data\tempdev3.ndf', SIZE = 100MB, MAXSIZE = 4000MB, FILEGROWTH = 100MB);
-- 建議檔案數 = 邏輯 CPU 核心數 (最多 8),分佈於不同物理磁碟
  1. 程式碼優化 (根本):觸發此錯誤的案例為「600 萬表 JOIN 100 萬表單次大交易寫入」。
-- 錯誤模式:單一巨大交易
BEGIN TRAN
INSERT INTO target SELECT ... FROM big_table_a JOIN big_table_b ...  -- 產生海量 tempdb 排序/雜湊
COMMIT TRAN

-- 優化模式:分批提交
DECLARE @batch INT = 10000, @rowcount INT = 1;
WHILE @rowcount > 0
BEGIN
  BEGIN TRAN
  INSERT TOP (@batch) INTO target SELECT ... FROM ... WHERE id > @last_id ORDER BY id;
  SET @rowcount = @@ROWCOUNT;
  SET @last_id = (SELECT MAX(id) FROM target);
  COMMIT TRAN
  CHECKPOINT;  -- 釋放 tempdb 空間
  WAITFOR DELAY '00:00:00.100';  -- 降低鎖衝突
END

預防配置清單

  • [ ] tempdb 置於 NTFS/ReFS 專用高速磁碟 (NVMe/SSD)。
  • [ ] 多資料檔 (CPU 核心數,上限 8),預設大小足夠避免自動增長。
  • [ ] MAXSIZE 設定略低於磁碟剩餘空間,FILEGROWTH 固定 MB (非百分比)。
  • [ ] 監控 tempdb 空間使用率,設定告警 > 70%。
  • [ ] 定期檢視 sys.dm_db_file_space_usage、sys.dm_db_session_space_usage 找出大消費者。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved