SQL Server 大數據空間管理——數據庫數據文件循環收縮

最近在進行數據歸檔整理,整理完後,需要對數據庫進行收縮,釋放未使用空間。爲方便後期重複使用,將相關腳本進行整理。同時也將之分享給業界朋友,希望在您的管理中給予一些提示或者幫助。寫到這裏也讓我回想起第一次收縮一個數據庫時候的糗事,收縮兩天沒有完成,回滾一天還沒有結束,最後直接用爆了所有存儲^^。每天積累一點,每天進步一點。

本文沒有使用 DBCC SHRINKDATABASE 進行數據庫收縮,而DBCC SHRINKDATABASE 本質上也是對各個文件(包括數據文件、和日誌文件)同時進行收縮,使用其進行數據庫收縮,但不容易控制收縮的文件(由其自身控制,無法人爲干預)。本人選擇使用更容易人爲干預控制的 DBCC SHRINKFILE 循環對數據文件進行收縮。爲了方便,首先將循環收縮的一個數據文件的腳本封裝爲一個系統過程,以方便各個庫調用,具體腳本如下:

use master
go
/*
	循環收縮數據庫的一個數據文件
*/
create proc sp_DBA_ShrinkFile
	@fileName varchar(256)
	,@space int
	,@usedSpace int
	,@shrinkSpace int=10000	--默認每次收縮10GB
as
begin
	while @space>@usedSpace
	begin
		DBCC SHRINKFILE (@fileName , @space)
		set @space=@space-@shrinkSpace	
	end
end

go

腳本每次將文件收縮到一個指定值,循環直至數據文件分配的大小和使用的大小一致時結束。

下面使用 DBCC showfilestats 獲取每個數據文件的分配總空間和使用空間,這裏返回的是每個數據文件的總 Extent 和 使用的 Extent,SQL Server 中 最小的存儲單位是頁,一頁爲8KB,連續的8頁稱爲一個 Extent。

循環數據庫中的所有數據文件,調用上面的 sp_DBA_ShrinkFile,對數據庫中所有數據文件進行收縮,具體腳本如下:

/************************************************************
	***注意:
	在進行文件收縮時,如果收縮導致死鎖,將會導致日誌文件迅速增長,注意觀察文件大小變化情況,及死鎖情況
************************************************************/
use DBA_Monitor

declare @fileName varchar(256)
declare @space int	--第一次收縮後的空間(MB),第一次收縮的空間建議1~2GB
declare @usedSpace int
if OBJECT_ID('tempdb..#dbInfo') is not null
	drop table #dbInfo
create table #dbInfo(Fileid smallint
,FileGroup smallint
,TotalExtents int
,UsedExtents int
,name varchar(256)
,FileName varchar(520)
)

insert into #dbInfo
exec('dbcc showfilestats')

update #dbInfo set TotalExtents=TotalExtents*8*8/1024-1000,UsedExtents=UsedExtents*8*8/1024

declare cur cursor for select name,TotalExtents,UsedExtents from #dbInfo
open cur
fetch next from cur into @fileName,@space,@usedSpace
--set @space=@space*8*8/1024-1000
--set @usedSpace=@usedSpace*8*8/1024
while @@FETCH_STATUS=0
begin
	exec sp_DBA_ShrinkFile @fileName,@space,@usedSpace
	fetch next from cur into @fileName,@space,@usedSpace
	--set @space=@space*8*8/1024-1000
	--set @usedSpace=@usedSpace*8*8/1024
end
close cur
deallocate cur
drop table #dbInfo

注意:在進行數據庫數據文件收縮時,要嚴密關注死鎖、日誌文件的變化及存儲空間的變化。因爲一旦收縮文件導致死鎖,將會導致日誌迅猛增長,從而導致空間急劇減少。

使用這個循環文件收縮腳本收縮一個近2T的數據文件,用了不到1個小時的時間,釋放近40%的空間,效率還是蠻可以的,同時想要停止收縮,幾乎可以秒停。對於有許多分區文件、大量數據庫(聽說有人需要管理數百個數據庫)的收縮更是一大福音,幾乎可以一鍵搞定(在SSMS中F5運行腳本)。

如果喜歡,可以搜索注公衆 MSQLServer,將有更多精彩。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章