如何壓縮SQL Server 2005指定數(shù)據(jù)庫文件和日志的大小?

2010-08-28 10:54:03來源:西部e網(wǎng)作者:

下面有兩個(gè)SQL語句可以達(dá)到在SQL Server 2005/2008壓縮指定數(shù)據(jù)庫文件和日志的大小的效果:

1、DBCC SHRINKDATABASE (Transact-SQL)

收縮指定數(shù)據(jù)庫中的數(shù)據(jù)文件和日志文件的大小。

語法

DBCC SHRINKDATABASE
( 'database_name' | database_id | 0
     [ ,target_percent ]
     [ , { NOTRUNCATE | TRUNCATEONLY } ]
)
[ WITH NO_INFOMSGS ]

參數(shù)

'database_name' | database_id | 0    要收縮的數(shù)據(jù)庫的名稱或 ID。如果指定 0,則使用當(dāng)前數(shù)據(jù)庫。

target_percent    數(shù)據(jù)庫收縮后的數(shù)據(jù)庫文件中所需的剩余可用空間百分比。

NOTRUNCATE    通過將已分配的頁從文件末尾移動(dòng)到文件前面的未分配頁來壓縮數(shù)據(jù)文件中的數(shù)據(jù)。target_percent 是可選參數(shù)。    文件末尾的可用空間不會(huì)返回給操作系統(tǒng),文件的物理大小也不會(huì)更改。因此,指定 NOTRUNCATE 時(shí),數(shù)據(jù)庫看起來未收縮。    NOTRUNCATE 只適用于數(shù)據(jù)文件。日志文件不受影響。

TRUNCATEONLY    將文件末尾的所有可用空間釋放給操作系統(tǒng),但不在文件內(nèi)部執(zhí)行任何頁移動(dòng)。數(shù)據(jù)文件只收縮到最近分配的區(qū)。如果與 TRUNCATEONLY 一起指定,將忽略 target_percent。    TRUNCATEONLY 只適用于數(shù)據(jù)文件。日志文件不受影響。

WITH NO_INFOMSGS    取消嚴(yán)重級別從 0 到 10 的所有信息性消息。


結(jié)果集

列名   說明

DbId   數(shù)據(jù)庫引擎試圖收縮的文件的數(shù)據(jù)庫標(biāo)識號。

FileId  數(shù)據(jù)庫引擎嘗試收縮的文件的文件標(biāo)識號。

CurrentSize 文件當(dāng)前占用的 8 KB 頁數(shù)。

MinimumSize 文件最低可以占用的 8 KB 頁數(shù)。這與文件的最小大小或最初創(chuàng)建時(shí)的大小相對應(yīng)。

UsedPages   文件當(dāng)前使用的 8 KB 頁數(shù)。

EstimatedPages 數(shù)據(jù)庫引擎估計(jì)文件能夠收縮到的 8 KB 頁數(shù)。


備注

若要收縮特定數(shù)據(jù)庫的所有數(shù)據(jù)和日志文件,請執(zhí)行 DBCC SHRINKDATABASE 命令。若要一次收縮一個(gè)特定數(shù)據(jù)庫中的一個(gè)數(shù)據(jù)或日志文件,請執(zhí)行 DBCC SHRINKFILE 命令。

若要查看數(shù)據(jù)庫中當(dāng)前的可用(未分配)空間量,請運(yùn)行 sp_spaceused。

可在進(jìn)程中的任一點(diǎn)停止 DBCC SHRINKDATABASE 操作,任何已完成的工作都將保留。

收縮后的數(shù)據(jù)庫不能小于數(shù)據(jù)庫的最小大小。最小大小是在數(shù)據(jù)庫最初創(chuàng)建時(shí)指定的大小,或是使用文件大小更改操作(如 DBCC SHIRNKFILE 或 ALTER DATABASE)顯式設(shè)置的最后大小。例如,如果數(shù)據(jù)庫最初創(chuàng)建時(shí)的大小為 10 MB,后來增長到 100 MB,則該數(shù)據(jù)庫最小只能收縮到 10 MB,即使已經(jīng)刪除數(shù)據(jù)庫的所有數(shù)據(jù)也是如此。

運(yùn)行 DBCC SHRINKDATABASE 而不指定 NOTRUNCATE 選項(xiàng)或 TRUNCATEONLY 選項(xiàng)等價(jià)于帶 NOTRUNCATE 運(yùn)行 DBCC SHRINKDATABASE 操作,然后再帶 TRUNCATEONLY 運(yùn)行 DBCC SHRINKDATABASE 操作。

要收縮的數(shù)據(jù)庫不必在單用戶模式下;其他的用戶仍可以在數(shù)據(jù)庫收縮時(shí)對其進(jìn)行工作。這也包括系統(tǒng)數(shù)據(jù)庫。

不能在備份數(shù)據(jù)庫時(shí)收縮數(shù)據(jù)庫。反之,也不能在數(shù)據(jù)庫執(zhí)行收縮操作時(shí)備份數(shù)據(jù)庫。

DBCC SHRINKDATABASE 的工作原理

DBCC SHRINKDATABASE 以每個(gè)文件為單位對數(shù)據(jù)文件進(jìn)行收縮。然而,DBCC SHRINKDATABASE 在對日志文件進(jìn)行收縮時(shí),它將視為所有的日志文件都存在于一個(gè)連續(xù)的日志池中。文件始終從末尾開始收縮。

假設(shè)名為 mydb 的數(shù)據(jù)庫有一個(gè)數(shù)據(jù)文件和兩個(gè)日志文件。數(shù)據(jù)文件和日志文件分別是 10 MB,并且數(shù)據(jù)文件包含 6 MB 數(shù)據(jù)。

Microsoft SQL Server 2005 數(shù)據(jù)庫引擎對每個(gè)文件計(jì)算一個(gè)目標(biāo)大小。這就是文件將要收縮到的大小。將 target_percent 與 DBCC SHRINKDATABASE 一起指定時(shí),數(shù)據(jù)庫引擎計(jì)算的目標(biāo)大小是收縮后文件中的 target_percent 可用空間大小。例如,如果在收縮 mydb 時(shí)將 target_percent 指定為 25,則數(shù)據(jù)庫引擎將此文件的目標(biāo)大小計(jì)算為 8 MB(6 MB 數(shù)據(jù)加上 2 MB 可用空間)。因此,數(shù)據(jù)庫引擎將任何數(shù)據(jù)從數(shù)據(jù)文件的后 2 MB 中移動(dòng)到數(shù)據(jù)文件前 8 MB 的可用空間中,然后對該文件進(jìn)行收縮。

假設(shè) mydb 的數(shù)據(jù)文件包含 7 MB 的數(shù)據(jù)。將 target_percent 指定為 30,以允許將此數(shù)據(jù)文件收縮到可用空間為 30%。但是,將 target_percent 指定為 40 卻不會(huì)收縮數(shù)據(jù)文件,因?yàn)閿?shù)據(jù)庫引擎收縮文件的目標(biāo)大小不能小于數(shù)據(jù)當(dāng)前占用空間大小。您還可以用另一種方法來考慮此問題:所要求的 40% 可用空間加上整個(gè)數(shù)據(jù)文件大小的 70%(10 MB 中的 7 MB),超過了 100%。因?yàn)樗蟮目捎冒俜直燃由蠑?shù)據(jù)文件占用的當(dāng)前百分比大于 100%(多出 10%),所以任何大于 30 的 target_size 都不會(huì)收縮此數(shù)據(jù)文件。

對于日志文件,數(shù)據(jù)庫引擎使用 target_percent 來計(jì)算整個(gè)日志的目標(biāo)大。灰虼,target_percent 是收縮操作后日志中的可用空間大小。之后,整個(gè)日志的目標(biāo)大小轉(zhuǎn)換為每個(gè)日志文件的目標(biāo)大小。

DBCC SHRINKDATABASE 嘗試立即將每個(gè)物理日志文件收縮到其目標(biāo)大小。如果虛擬日志中的所有邏輯日志部分都沒有超出日志文件的目標(biāo)大小,則該文件將成功截?cái)啵珼BCC SHRINKDATABASE 完成且不顯示任何消息。但是,如果部分邏輯日志位于超出目標(biāo)大小的虛擬日志中,則數(shù)據(jù)庫引擎將釋放盡可能多的空間,并發(fā)出一條信息性消息。該消息說明需要執(zhí)行哪些操作來將邏輯日志移出位于文件末尾的虛擬日志。執(zhí)行該操作以后,DBCC SHRINKDATABASE 可用于釋放剩余空間。有關(guān)詳細(xì)信息,請參閱收縮事務(wù)日志。

因?yàn)槿罩疚募荒苁湛s到虛擬日志文件邊界,所以不可能將日志文件收縮到比虛擬日志文件更。词宫F(xiàn)在沒有使用該文件)。虛擬日志文件的大小在創(chuàng)建或擴(kuò)展這些日志文件時(shí)由數(shù)據(jù)庫引擎動(dòng)態(tài)選擇。有關(guān)虛擬日志文件的詳細(xì)信息,請參閱事務(wù)日志物理體系結(jié)構(gòu)。


權(quán)限

要求具有 sysadmin 固定服務(wù)器角色或 db_owner 固定數(shù)據(jù)庫角色的成員身份。、


示例

A. 收縮數(shù)據(jù)庫并指定可用空間的百分比

以下示例將減小 UserDB 用戶數(shù)據(jù)庫中數(shù)據(jù)文件和日志文件的大小,以便在數(shù)據(jù)庫中留出 10% 的可用空間。

DBCC SHRINKDATABASE (UserDB, 10);
GO


B. 截?cái)鄶?shù)據(jù)庫

以下示例使 AdventureWorks 示例數(shù)據(jù)庫中的數(shù)據(jù)文件收縮到最后分配的區(qū)。

DBCC SHRINKDATABASE (AdventureWorks, TRUNCATEONLY);

請參考:http://msdn.microsoft.com/zh-cn/vs2008/ms190488(SQL.90).aspx


2、DBCC SHRINKFILE (Transact-SQL)

收縮當(dāng)前數(shù)據(jù)庫的指定數(shù)據(jù)或日志文件的大小,或通過將數(shù)據(jù)從指定的文件移動(dòng)到相同文件組中的其他文件來清空文件,以允許從數(shù)據(jù)庫中刪除該文件。文件大小可以收縮到比創(chuàng)建該文件時(shí)所指定的大小更小。這樣會(huì)將最小文件大小重置為新值。

語法

DBCC SHRINKFILE  (      { 'file_name' | file_id }      { [ , EMPTYFILE ]      | [ [ , target_size ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ]     } ) [ WITH NO_INFOMSGS ]


參數(shù)

 ' file_name '

    要收縮的文件的邏輯名稱。

file_id

    要收縮的文件的標(biāo)識 (ID) 號。若要獲得文件 ID,請使用 FILE_IDEX 系統(tǒng)函數(shù),或查詢當(dāng)前數(shù)據(jù)庫中的 sys.database_files 目錄視圖。

target_size

    用兆字節(jié)表示的文件大。ㄓ谜麛(shù)表示)。如果未指定,則 DBCC SHRINKFILE 將文件大小減少到默認(rèn)文件大小。默認(rèn)大小是創(chuàng)建文件時(shí)指定的大小,或者是使用 ALTER DATABASE 所設(shè)置的最后大小。

    如果指定了 target_size,則 DBCC SHRINKFILE 嘗試將文件收縮到指定大小。將要釋放的文件部分中的已使用頁重新定位到保留的文件部分中的可用空間。例如,如果數(shù)據(jù)文件為 10 MB,則 target_size 為 8 的 DBCC SHRINKFILE 操作會(huì)將文件最后 2 MB 中所有的已使用頁重新分配到文件前 8 MB 中的任何未分配頁中。DBCC SHRINKFILE 不會(huì)將文件收縮到小于存儲(chǔ)文件中的數(shù)據(jù)所需要的大小。例如,如果使用 10 MB 數(shù)據(jù)文件中的 7 MB,則帶有 target_size 為 6 的 DBCC SHRINKFILE 語句只能將該文件收縮到 7 MB,而不能收縮到 6 MB。

EMPTYFILE

    將指定文件中的所有數(shù)據(jù)遷移到同一文件組中的其他文件。由于數(shù)據(jù)庫引擎不再允許將數(shù)據(jù)放在空文件內(nèi),因此可以使用 ALTER DATABASE 語句來刪除該文件。

NOTRUNCATE

    在指定或不指定 target_percent 的情況下,將已分配的頁從數(shù)據(jù)文件的末尾移動(dòng)到該文件前面的未分配頁。文件末尾的可用空間不會(huì)返回給操作系統(tǒng),文件的物理大小也不會(huì)更改。因此,指定 NOTRUNCATE 時(shí),文件看起來未收縮。

    NOTRUNCATE 只適用于數(shù)據(jù)文件。日志文件不受影響。

TRUNCATEONLY

    將文件末尾的所有可用空間釋放給操作系統(tǒng),但不在文件內(nèi)部執(zhí)行任何頁移動(dòng)。數(shù)據(jù)文件只收縮到最后分配的區(qū)。

    如果隨 TRUNCATEONLY 指定了 target_size,則會(huì)忽略該參數(shù)。

    TRUNCATEONLY 只適用于數(shù)據(jù)文件。

WITH NO_INFOMSGS

    取消顯示所有信息性消息。


結(jié)果集

列名   說明

DbId    數(shù)據(jù)庫引擎試圖收縮的文件的數(shù)據(jù)庫標(biāo)識號。

FileId  數(shù)據(jù)庫引擎試圖收縮的文件的文件標(biāo)識號。

CurrentSize 文件當(dāng)前占用的 8 KB 頁數(shù)。

MinimumSize 文件最低可以占用的 8 KB 頁數(shù)。這與文件的最小大小或最初創(chuàng)建時(shí)的大小相對應(yīng)。

UsedPages   文件當(dāng)前使用的 8 KB 頁數(shù)。

EstimatedPages 數(shù)據(jù)庫引擎估計(jì)文件能夠收縮到的 8 KB 頁數(shù)。


收縮日志文件

對于日志文件,SQL Server 2005 數(shù)據(jù)庫引擎使用 target_size 來計(jì)算整個(gè)日志的目標(biāo)大;因此,target_size 是收縮操作后日志中的可用空間大小。之后,整個(gè)日志的目標(biāo)大小轉(zhuǎn)換為每個(gè)日志文件的目標(biāo)大小。DBCC SHRINKFILE 嘗試立即將每個(gè)物理日志文件收縮到其目標(biāo)大小。但是,如果部分邏輯日志位于超出目標(biāo)大小的虛擬日志中,則數(shù)據(jù)庫引擎將釋放盡可能多的空間,并發(fā)出一條信息性消息。該消息說明需要執(zhí)行哪些操作來將邏輯日志移出位于文件末尾的虛擬日志。執(zhí)行這些操作以后,DBCC SHRINKFILE 可用于釋放剩余空間。


如果文件不收縮

如果收縮操作運(yùn)行時(shí)未出現(xiàn)錯(cuò)誤,但文件大小看起來沒有發(fā)生更改,則請執(zhí)行下列操作之一以驗(yàn)證文件是否有足夠的可用空間可供刪除:

運(yùn)行以下查詢。

SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
FROM sys.database_files;


權(quán)限

要求具有 sysadmin 固定服務(wù)器角色或 db_owner 固定數(shù)據(jù)庫角色的成員身份。


示例

A. 將數(shù)據(jù)文件收縮到指定的目標(biāo)大小

以下示例將 UserDB 用戶數(shù)據(jù)庫中名為 DataFile1 的數(shù)據(jù)文件的大小收縮到 7MB。

USE UserDB;
GO
DBCC SHRINKFILE (DataFile1, 7);
GO


B. 將日志文件收縮到指定的目標(biāo)大小

以下示例將 AdventureWorks 數(shù)據(jù)庫中的日志文件收縮到 1 MB。若要允許 DBCC SHRINKFILE 命令收縮文件,首先需要通過將數(shù)據(jù)庫恢復(fù)模式設(shè)置為 SIMPLE 來截?cái)嘣撐募?/P>

USE AdventureWorks;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks
SET RECOVERY FULL;
GO


C. 截?cái)鄶?shù)據(jù)文件

以下示例將截?cái)?AdventureWorks 數(shù)據(jù)庫中的主數(shù)據(jù)文件。需要查詢 sys.database_files 目錄視圖以獲得數(shù)據(jù)文件的 file_id。

USE AdventureWorks;
GO
SELECT file_id, name
FROM sys.database_files;
GO
DBCC SHRINKFILE (1, TRUNCATEONLY);


D. 清空文件

以下示例演示了清空文件以便從數(shù)據(jù)庫中將其刪除的步驟。針對此示例,首先創(chuàng)建一個(gè)數(shù)據(jù)文件,并假設(shè)該文件包含數(shù)據(jù)。

USE AdventureWorks;
GO
-- Create a data file and assume it contains data.
ALTER DATABASE AdventureWorks
ADD FILE (
    NAME = Test1data,
    FILENAME = 'C:\t1data.ndf',
    SIZE = 5MB
    );
GO
-- Empty the data file.
DBCC SHRINKFILE (Test1data, EMPTYFILE);
GO
-- Remove the data file from the database.
ALTER DATABASE AdventureWorks
REMOVE FILE Test1data;
GO

請參考:http://msdn.microsoft.com/zh-cn/vs2008/ms189493(SQL.90).aspx

關(guān)鍵詞:SQLServer