DBCC大全集之(適用版本MS SQLServer 2008 R2)----DBCC SHRINKDATABASE收縮指定資料庫中的資料檔案和日誌檔案的大小
收縮指定資料庫中的資料檔案和日誌檔案的大小。
DBCC SHRINKDATABASE ( database_name | database_id | 0 [ , target_percent ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ) [ WITH NO_INFOMSGS ]引數
database_name | database_id | 0
要收縮的資料庫的名稱或 ID。如果指定 0,則使用當前資料庫。
target_percent資料庫收縮後的資料庫檔案中所需的剩餘可用空間百分比。
通過將已分配的頁從檔案末尾移動到檔案前面的未分配頁來壓縮資料檔案中的資料。target_percent 是可選引數。
檔案末尾的可用空間不會返回給作業系統,檔案的物理大小也不會更改。因此,指定 NOTRUNCATE 時,資料庫看起來未收縮。
NOTRUNCATE 只適用於資料檔案。日誌檔案不受影響。
TRUNCATEONLY將檔案末尾的所有可用空間釋放給作業系統,但不在檔案內部執行任何頁移動。資料檔案只收縮到最近分配的區。如果與 TRUNCATEONLY 一起指定,將忽略 target_percent。
TRUNCATEONLY 只適用於資料檔案。日誌檔案不受影響。
WITH NO_INFOMSGS取消嚴重級別從 0 到 10 的所有資訊性訊息。
下表對結果集中的列進行了說明。
列名 |
說明 |
---|---|
DbId |
資料庫引擎試圖收縮的檔案的資料庫標識號。 |
FileId |
資料庫引擎嘗試收縮的檔案的檔案標識號。 |
CurrentSize |
檔案當前佔用的 8 KB 頁數。 |
MinimumSize |
檔案最低可以佔用的 8 KB 頁數。這與檔案的最小大小或最初建立時的大小相對應。 |
UsedPages |
檔案當前使用的 8 KB 頁數。 |
EstimatedPages |
資料庫引擎估計檔案能夠收縮到的 8 KB 頁數。 |
注意 |
---|
資料庫引擎不顯示未收縮的檔案的行。 |
若要收縮特定資料庫的所有資料和日誌檔案,請執行 DBCC SHRINKDATABASE 命令。若要一次收縮一個特定資料庫中的一個數據或日誌檔案,請執行 DBCC SHRINKFILE 命令。
若要檢視資料庫中當前的可用(未分配)空間量,請執行 sp_spaceused。
可在程序中的任一點停止 DBCC SHRINKDATABASE 操作,任何已完成的工作都將保留。
收縮後的資料庫不能小於資料庫的最小大小。最小大小是在資料庫最初建立時指定的大小,或是使用檔案大小更改操作(如 DBCC SHIRNKFILE 或 ALTER DATABASE)顯式設定的最後大小。例如,如果資料庫最初建立時的大小為 10 MB,後來增長到 100 MB,則該資料庫最小隻能收縮到 10 MB,即使已經刪除資料庫的所有資料也是如此。
執行 DBCC SHRINKDATABASE 而不指定 NOTRUNCATE 選項或 TRUNCATEONLY 選項等價於帶 NOTRUNCATE 執行 DBCC SHRINKDATABASE 操作,然後再帶 TRUNCATEONLY 執行 DBCC SHRINKDATABASE 操作。
要收縮的資料庫不必在單使用者模式下;其他的使用者仍可以在資料庫收縮時對其進行工作。這也包括系統資料庫。
不能在備份資料庫時收縮資料庫。反之,也不能在資料庫執行收縮操作時備份資料庫。
DBCC SHRINKDATABASE 的工作原理
DBCC SHRINKDATABASE 以每個檔案為單位對資料檔案進行收縮。然而,DBCC SHRINKDATABASE 在對日誌檔案進行收縮時,它將視為所有的日誌檔案都存在於一個連續的日誌池中。檔案始終從末尾開始收縮。
假設名為 mydb 的資料庫有一個數據檔案和兩個日誌檔案。資料檔案和日誌檔案分別是 10 MB,並且資料檔案包含 6 MB 資料。
對於每個檔案,資料庫引擎都會計算一個目標大小。這就是檔案將要收縮到的大小。將 target_percent 與 DBCC SHRINKDATABASE 一起指定時,資料庫引擎計算的目標大小是收縮後文件中的 target_percent 可用空間大小。例如,如果在收縮 mydb 時將 target_percent 指定為 25,則資料庫引擎將此檔案的目標大小計算為 8 MB(6 MB 資料加上 2 MB 可用空間)。因此,資料庫引擎將任何資料從資料檔案的後 2 MB 中移動到資料檔案前 8 MB 的可用空間中,然後對該檔案進行收縮。
假設 mydb 的資料檔案包含 7 MB 的資料。將 target_percent 指定為 30,以允許將此資料檔案收縮到可用空間的 30%。但是,將 target_percent 指定為 40 卻不會收縮資料檔案,因為資料庫引擎收縮檔案的目標大小不能小於資料當前佔用空間大小。您還可以用另一種方法來考慮此問題:所要求的 40% 可用空間加上整個資料檔案大小的 70%(10 MB 中的 7 MB),超過了 100%。因為所要求的可用百分比加上資料檔案佔用的當前百分比大於 100%(多出 10%),所以任何大於 30 的 target_size 都不會收縮此資料檔案。
對於日誌檔案,資料庫引擎使用 target_percent 來計算整個日誌的目標大小;因此,target_percent 是收縮操作後日志中的可用空間大小。之後,整個日誌的目標大小轉換為每個日誌檔案的目標大小。
DBCC SHRINKDATABASE 嘗試立即將每個物理日誌檔案收縮到其目標大小。如果虛擬日誌中的所有邏輯日誌部分都沒有超出日誌檔案的目標大小,則該檔案將成功截斷,DBCC SHRINKDATABASE 完成且不顯示任何訊息。但是,如果部分邏輯日誌位於超出目標大小的虛擬日誌中,則資料庫引擎將釋放盡可能多的空間,併發出一條資訊性訊息。該訊息說明需要執行哪些操作來將邏輯日誌移出位於檔案末尾的虛擬日誌。執行該操作以後,DBCC SHRINKDATABASE 可用於釋放剩餘空間。有關詳細資訊,請參閱收縮事務日誌。
因為日誌檔案只能收縮到虛擬日誌檔案邊界,所以不可能將日誌檔案收縮到比虛擬日誌檔案更小(即使現在沒有使用該檔案)。虛擬日誌檔案的大小在建立或擴充套件這些日誌檔案時由資料庫引擎動態選擇。有關虛擬日誌檔案的詳細資訊,請參閱事務日誌物理體系結構。
最佳做法
當您計劃收縮資料庫時,請考慮以下資訊:
-
在執行會產生許多未使用空間的操作(如截斷表或刪除表操作)後,執行收縮操作最有效。
-
大多數資料庫都需要一些可用空間,以供常規日常操作使用。如果反覆收縮資料庫並注意到資料庫大小變大,則表明收縮的空間是常規操作所必需的。在這種情況下,反覆收縮資料庫是一種無謂的操作。
-
收縮操作不會保留資料庫中索引的碎片狀態,通常還會在一定程度上增加碎片。這是不要反覆收縮資料庫的另一個原因。
-
除非有特定要求,否則不要將 AUTO_SHRINK 資料庫選項設定為 ON。
故障排除
在基於行版本控制的隔離級別下執行的事務可能會阻塞收縮操作。例如,執行 DBCC SHRINK DATABASE 操作時,如果在基於行版本控制的隔離級別下執行的大型刪除操作正在進行中,則收縮操作將等到刪除操作完成才會收縮檔案。出現這種情況時,DBCC SHRINKFILE 和 DBCC SHRINKDATABASE 操作會在第一個小時每五分鐘將資訊性訊息(對於 SHRINKDATABASE 為 5202,對於 SHRINKFILE 為 5203)輸出到 SQL Server 錯誤日誌,之後每一個小時輸出一次。例如,如果錯誤日誌包含以下錯誤訊息:
DBCC SHRINKDATABASE for database ID 9 is waiting for the snapshot transaction with timestamp 15 and other snapshot transactions linked to timestamp 15 or with timestamps older than 109 to finish.
這意味著收縮操作被時間戳早於 109 的快照事務阻塞,它是收縮操作所完成的上一事務。它還說明 sys.dm_tran_active_snapshot_database_transactions 動態管理檢視中的 transaction_sequence_num 或 first_snapshot_sequence_num 列包含值 15。如果該檢視中的 transaction_sequence_num 或first_snapshot_sequence_num 列包含的數字小於收縮操作完成的上一事務 (109),則收縮操作將等待這些事務完成。
若要解決此問題,請執行下列任務之一:
-
終止阻塞收縮操作的事務。
-
終止收縮操作。將保留任何已完成的工作。
-
不執行任何操作,並允許收縮操作等到阻塞事務完成。
有關 SQL Server 錯誤日誌的詳細資訊,請參閱檢視 SQL Server 錯誤日誌。
要求具有 sysadmin 固定伺服器角色或 db_owner 固定資料庫角色的成員身份。
要求具有 sysadmin 固定伺服器角色或 db_owner 固定資料庫角色的成員身份。
A. 收縮資料庫並指定可用空間的百分比
以下示例將減小 UserDB 使用者資料庫中資料檔案和日誌檔案的大小,以便在資料庫中留出 10% 的可用空間。
Transact-SQLDBCC SHRINKDATABASE (UserDB, 10); GO
B. 截斷資料庫
以下示例使 AdventureWorks2008R2 示例資料庫中的資料檔案收縮到最後分配的區。
Transact-SQLDBCC SHRINKDATABASE (AdventureWorks2008R2, TRUNCATEONLY);