Tempdb

為什麼 FREEPROCCACHE 讓你收縮 tempdb?

  • March 29, 2019

有人做了一些愚蠢的事情,tempdb 的大小爆炸了。由於驅動器已滿,警報正在觸發。我嘗試縮小它,它不會縮小(即使縮小查詢說它們有效)。

tempdb (SQL2014 SP1) 中有大量可用空間;tempdb > Tasks > Shrink > Files > (顯示我可以釋放多少可用空間)

我縮小(SSMS 2016)以留下更多空間,然後是“最小縮小尺寸”。但文件實際上並沒有縮小。

我正在與企業主合作,我正在觀察伺服器(sp_whoisactive 等)伺服器處於靜止狀態。

尋找解決方案導致我在收縮 Tempdb 時不會收縮(brentozar.com)

我執行以下命令,它可以工作 tempdb,恢復到原始大小。

DBCC FREEPROCCACHE

USE [tempdb]
GO
DBCC SHRINKFILE (N'tempdev' , 2048)
GO

我了解DBCC FREEPROCCACHE會釋放所有記憶體數據,並影響計劃。但是如果它在 tempdb 中佔用空間,它應該顯示為已用空間,並且不能用於正常收縮。

為什麼這樣做?

根據指向重要的是記憶體對象與查詢計劃相關聯的評論,並且通過釋放過程記憶體,您可以使這些對象消失,從而允許您縮小文件。 讓我從另一個方面來表述這個問題。

Tempdb 認為它有空間可以擺脫,正如“最小縮小到大小”所證明的那樣,不會消失的空間是在不再執行的臨時程序中創建的。有一大塊已分配和未使用的空間,為什麼我不能在不破壞查詢計劃的情況下釋放它?

查詢計劃或記憶體是否不在分配的磁碟空間上,但仍受到保護而不會縮小?

類比: “最小縮小尺寸”顯示玻璃杯是半滿/空的,但如果不打破玻璃杯並失去幾乎所有內容物,就不可能轉移到較小的玻璃杯中。


幾年後,SQL 2014 實例上的相同問題,不太緊急,允許有時間嘗試實驗。

如果您能以某種方式辨識查詢計劃,您也許可以刪除該計劃以釋放頁面上的保留,然後能夠縮小 tempdb。我正在尋找實現這一目標的方法,但尚未成功。

也許您可以使用DBCC PAGE來查看該頁面上的內容,以便解決它?

DBCC TRACEON (3604)  -- By default, the output is sent to the errorlog. If you want the output to come back to your current connection, turn on trace flag 3604.
GO
DBCC PAGE ([tempdb], 1, 1, 3); -- detailed dump of the PFS page
GO 

我看到最後一頁是937,所以我去看看。

DBCC PAGE ([tempdb], 1, 937, 3);
GO

那裡沒有明顯的問題,最後幾頁看起來很空。

我已經嘗試了Mike Fields 的建議(2016 年 2 月 4 日下午 12:01)多次嘗試甚至沒有釋放 1MB。

我昨天遇到了這個問題,使用 SSMS 任務來收縮文件從來沒有完成任何事情,然後我重新閱讀了 Shrink File 上的文件並意識到我需要嘗試這個:

DBCC SHRINKFILE (N'tempdev' , NOTRUNCATE) -- Move allocated pages from end of file to top of file
DBCC SHRINKFILE (N'tempdev' , 0, TRUNCATEONLY) -- Drop unallocated pages from end of file

我對所有 8 個 tempdev 文件都這樣做了,隨著時間的推移,它慢慢地恢復了大約 80% 的空間。我對此感到非常驚訝,因為沒有其他方法起作用。我不得不在一天中每 15 分鐘執行一次工作,但它最終恢復了空間

在 SQL 2014 實例上,當使用聚集列儲存索引(夜間程序)重建大型數據庫時,我“自然”地清除了記憶體。前一天不會做任何事情的相同 SHRINKFILE 在早上按預期工作。

USE [tempdb]
GO
DBCC SHRINKFILE (N'tempdev' , 2000)
GO

也許如果我可以使用 Query Store 在 2016+ 實例上按需重新創建問題,那麼準確追踪正在發生的事情會更容易嗎?

此答案基於@MrTCS 指向此連結的問題下的評論以及@KrisGruttemeyer 與此摘要的評論

TL;DR - “重要的是記憶體對象與查詢計劃相關聯,通過釋放過程記憶體,您可以使這些對象消失,從而縮小文件。”

據我了解:

當您無法縮小 tempdb 時會發生什麼,因為在數據文件的最後一頁上有一個物理上的指針(或其他東西)。它指嚮導致 tempdb 被填滿的查詢計劃。只要該查詢計劃存在,該頁面就不會被釋放。核選項是DBCC FREEPROCCACHE,清除所有查詢計劃,釋放頁面。

引用自:https://dba.stackexchange.com/questions/154514