【基本語法】
DBCC SHRINKFILE
收縮相關(guān)數(shù)據(jù)庫的指定數(shù)據(jù)文件或日志文件大小。
語法
DBCC SHRINKFILE
    ( { file_name | file_id }
        { [ ,target_size ]
            | [ , { EMPTYFILE | NOTRUNCATE | TRUNCATEONLY } ] 
        }
    )
參數(shù)
file_name: 是已收縮文件的邏輯名稱。文件名必須符合標(biāo)識符的規(guī)則。有關(guān)更多信息,請參見使用標(biāo)識符。
file_id: 是要收縮的文件的標(biāo)識 (ID) 號。若要獲得文件 ID,請使用 FILE_ID 函數(shù)或在當(dāng)前數(shù)據(jù)庫中搜索 sysfiles。
target_size:是用兆字節(jié)表示的所要的文件大小(用整數(shù)表示)。如果沒有指定,DBCC SHRINKFILE 將文件大小減少到默認(rèn)文件大小。
如果指定 target_size,DBCC SHRINKFILE 將試圖將文件收縮到指定大小。將要釋放的文件部分中的已使用頁將重新定位到保留的文件部分中的可用空間。
例如,如果數(shù)據(jù)文件為 10MB,則帶有 target_size 為 8 的 DBCC SHRINKFILE 將導(dǎo)致文件最后 2 MB 中所有已用頁重新分配到文件前 8 MB 中的任何可用槽中。
DBCC SHRINKFILE 不會將文件收縮到小于存儲文件中的數(shù)據(jù)所需要的大小。例如,如果使用 10MB 數(shù)據(jù)文件中的7 MB,帶有 target_size 為 6 的 DBCC SHRINKFILE 語句只能將該文件收縮到 7 MB,而不能收縮到 6 MB。
EMPTYFILE:將所有數(shù)據(jù)從指定文件中遷移到同一文件組中的其它文件。Microsoft® SQL Server™ 不再允許將數(shù)據(jù)放在用于 EMPTYFILE 選項(xiàng)的文件上。該選項(xiàng)允許使用 ALTER DATABASE 語句除去文件。
NOTRUNCATE :導(dǎo)致將釋放的文件空間保留在文件中。
當(dāng)與 target_size 一起指定 NOTRUNCATE 時,釋放的空間不會釋放給操作系統(tǒng)。
DBCC SHRINKFILE 的唯一影響是將已使用的頁從 target_size 行上面重新定位到文件的前面。當(dāng)未指定 NOTRUNCATE 時,所有釋放的文件空間返回給操作系統(tǒng)。
TRUNCATEONLY:導(dǎo)致文件中的任何未使用的空間釋放給操作系統(tǒng),并將文件收縮到上一次分配的大小,從而減少文件大小,而不移動任何數(shù)據(jù)。不嘗試將行重新定位到未分配頁。如果使用 TRUNCATEONLY,將忽略 target_size。
【注意事項(xiàng)】
(1)要切換到被收縮文件所在數(shù)據(jù)庫,use db
DBCC SHRINKFILE 適用于當(dāng)前數(shù)據(jù)庫中的文件。
將上下文切換到數(shù)據(jù)庫,以發(fā)出引用該特定數(shù)據(jù)庫中文件的 DBCC SHRINKFILE 語句。有關(guān)更改當(dāng)前數(shù)據(jù)庫的更多信息,請參見 USE。
所生成的數(shù)據(jù)庫不能比 model 數(shù)據(jù)庫更小。
使用 DBCC SHRINKFILE 以將文件減小到比其最初創(chuàng)建時更小。之后,文件的最小大小重置為新指定的大小。
若要刪除在文件中可能出現(xiàn)的任何數(shù)據(jù),請?jiān)趫?zhí)行ALTER DATABASE 之前執(zhí)行 DBCC SHRINKFILE(''''''''file_name'''''''', EMPTYFILE)。
(2)收縮時不用單用戶
要收縮的數(shù)據(jù)庫不必在單用戶模式下;收縮文件時,同時其他用戶可以在數(shù)據(jù)庫中工作。不必在單用戶模式下運(yùn)行 SQL Server 以對系統(tǒng)數(shù)據(jù)庫進(jìn)行收縮。
(3)收縮日志文件注意事項(xiàng)
對于日志文件,SQL Server 使用 target_size 以計(jì)算整個日志的目標(biāo)大小;因此,target_size 是收縮操作完成后日志中的可用空間大小。
之后,整個日志的目標(biāo)大小可以解釋為每個日志文件的目標(biāo)大小。DBCC SHRINKFILE 嘗試立即將每個物理日志文件收縮至其目標(biāo)大小。
如果虛擬日志中的所有邏輯日志部分都沒有超出日志文件的目標(biāo)大小,該文件將成功截?cái)啵珼BCC SHRINKFILE 完成且不顯示任何消息。
然而,如果虛擬日志中的邏輯日志部分超出目標(biāo)大小,則 SQL Server 釋放盡可能多的空間并發(fā)出一條消息。
該信息告訴您需要執(zhí)行什么操作來移動文件末尾超出虛擬日志的邏輯日志部分。
執(zhí)行完該操作后,可以重新發(fā)出 DBCC SHRINKFILE 命令以釋放剩余的空間。有關(guān)收縮事務(wù)日志的更多信息,請參見收縮事務(wù)日志。
因?yàn)槿罩疚募荒苁湛s到虛擬日志文件邊界,所以不可能將日志文件收縮到比虛擬日志文件更小(即使現(xiàn)在沒有使用該文件)。
例如,可以將數(shù)據(jù)庫的 1 GB 日志文件收縮到只有 128 MB。有關(guān)截?cái)嗟母嘈畔ⅲ垍⒁?A style="TEXT-DECORATION: none" rel=nofollow target=_blank>截?cái)嗍聞?wù)日志。有關(guān)確定虛擬日志文件大小的更多信息,請參見虛擬日志文件。
(4)收縮結(jié)果集中列
下表描述結(jié)果集內(nèi)的列。
DbId:SQL Server 試圖收縮的文件的數(shù)據(jù)庫標(biāo)識號。FileIdSQL Server 試圖收縮的文件的文件標(biāo)識號。
CurrentSize文件當(dāng)前占用的 8KB 頁數(shù)。MinimumSize文件可以占用的最小 8KB 頁數(shù)。這與文件的最小大小或最初創(chuàng)建時的大小相對應(yīng)。UsedPages文件當(dāng)前使用的 8KB 頁數(shù)。EstimatedPagesSQL Server 估計(jì)文件能夠收縮到的 8KB 頁數(shù)。
權(quán)限:DBCC SHRINKFILE 權(quán)限默認(rèn)授予 sysadmin 固定服務(wù)器角色或 db_owner 固定數(shù)據(jù)庫角色的成員且不可轉(zhuǎn)讓。
示例:
下例將 UserDB 用戶數(shù)據(jù)庫中名為 DataFil1 的文件收縮到 7 MB。這個名稱是邏輯名稱
USE UserDB
GO
DBCC SHRINKFILE (DataFil1, 7)
GO
【收縮數(shù)據(jù)文件、日志文件的影響】
(1)收縮數(shù)據(jù)文件的影響
數(shù)據(jù)庫使用數(shù)據(jù)文件(擴(kuò)展名是mdf 或 ndf)來存儲數(shù)據(jù),使用日志文件(擴(kuò)展名是ldf)來存儲事務(wù)日志,通常情況下,數(shù)據(jù)文件會持續(xù)增長,不會自動釋放空閑空間,這樣會導(dǎo)致硬盤空間耗盡。
如果一個數(shù)據(jù)庫的文件有很多空閑空間,收縮數(shù)據(jù)庫文件是一種解決硬盤空間緊張的直接方式。
原理與影響:
在SQL Server中,我們可以使用 DBCC ShrinkFile命令收縮數(shù)據(jù)文件,該命令首先將文件尾部的區(qū)(extent)移動到文件的開頭,文件結(jié)尾的空閑的硬盤空間被釋放給操作系統(tǒng)。
這種操作就像截?cái)鄬⑽募奈膊恳粯樱@種方式不需要消耗很多IO就能釋放空間;
但是,如果空閑部分不在文件末尾時,收縮操作必須掃描數(shù)據(jù)文件,并對正在讀取的頁面加鎖,把文件末尾的區(qū)移動到文件開頭,這是一個IO密集型的操作,影響數(shù)據(jù)庫的性能;
1、收縮操作不是一個獨(dú)占行為,在做文件收縮時,其他用戶仍然可以對數(shù)據(jù)庫進(jìn)行讀寫操作。
2、收縮會鎖表,會阻塞
3、在任意一個時間點(diǎn)停止dbcc shrinkfile命令,任何已經(jīng)完成的工作都將保留。
建議:
收縮 數(shù)據(jù)庫 是非常耗費(fèi)server性能的操作,如果沒有必要不要收縮
收縮 無非就是把已經(jīng)分配給數(shù)據(jù)庫文件空間收回來,但是,收縮的時候 要移動數(shù)據(jù)頁,而且可能造成大量的碎片,影響性能。
日志收縮和數(shù)據(jù)文件收縮不一樣,日志中的虛擬文件狀態(tài) 只有 在可復(fù)用 時候  才能收縮。
而且 凡是有活動的日志的日志虛擬文件都是活動的不能收縮。
(2)收縮日志文件的影響
日志文件收縮, 回收磁盤空間。
數(shù)據(jù)文件 根據(jù)設(shè)計(jì)  設(shè)計(jì)的大小,一般情況不用收縮,收縮可能帶來性能的問題。
日志
如果 選擇的日志恢復(fù)模型是完全,如果沒有日志截?cái)啵罩驹鲩L的很大,
建議
備份日志。
backup log db to disk=''''''''備份設(shè)備''''''''
截?cái)嗳罩?BR data-filtered="filtered"> backup log db with no_log
然后收縮。
dbcc shrinkfile(2,10)
  原理參考:https://www.cnblogs.com/gallen-n/archive/2017/03/15/6555283.html
【最佳實(shí)踐步驟-收縮數(shù)據(jù)文件】
1、實(shí)際工作中收縮數(shù)據(jù)文件的情況比收縮庫的情況多,不建議直接收縮數(shù)據(jù)庫
2、收縮很容易出現(xiàn)等待,收縮會話對應(yīng) sys.sysprocesses 的字段 waitresource 值類似為15:1:4700649,sys.sysprocesses 的字段  lastwaittype 值為PAGEIOLATCH_SH或PAGEIOLATCH_EX等
3、收縮數(shù)據(jù)文件時,不要一次性全部收縮。 可以每次收縮5G左右,比如DataFile1有32G,則每次收縮如下
USE UserDB
DBCC SHRINKFILE (DataFile1, 27000)
GO
DBCC SHRINKFILE (DataFile1, 22000)
GO
4、數(shù)據(jù)文件的可用空間可以結(jié)合sys.master_files 和 FILEPROPERTY(name,''''''''SpaceUsed'''''''') 來查看
5、收縮的100%進(jìn)度可以通過 sys.dm_exec_requests 的字段 percent_complete 來看
6、收縮完后,記得重建索引
alter index all on table_name rebuild   with(online=on) 這個參數(shù)加了不影響線上
【最佳實(shí)踐步驟-收縮日志文件】
ALTER DATABASE [test] SET RECOVERY SIMPLE
WITH NO_WAIT
GOEXEC(
''''''''
USE [Db_Tank]
DBCC SHRINKFILE (''''''''''''''''test_Log'''''''''''''''' , 2048)  sql server默認(rèn)文件單位為M,所以這里是2G
'''''''')
print ''''''''【''''''''+CONVERT(
varchar(
20),
GETDATE(),
120)
+''''''''】恢復(fù)庫模式''''''''GO
參考:"http://www.yesky.com/imagesnew/software/tsql/ts_dbcc_8b51.htm"