# MsSql 壓縮資料庫(含修復資料庫)
###### tags: `MSSQL`
使用情境:
通常資料庫壓力測試後會留下大量的廢資料,但刪除完廢資料後(Delete/Truncate Table),並沒有讓原本的資料庫檔案(.mdf/.ldf)變小,DB空間還是被原本的廢資料撐到虛胖了...
這時候就可以做壓縮資料庫( Shrink Database )的動作,此行為會釋放被占用的可用空間。
※ 執行前建議要==先備份資料庫==一次。
# 1. 壓縮指令
以下範例將縮小 [MyDatabase] 資料庫中資料檔案和日誌檔案的大小,並且在資料庫中保留 1% 的可用空間。
例: mdf檔有100GB可用空間,會壓縮99%空間變成1GB。
```sql=
--切換成簡單模式
ALTER DATABASE [MyDatabase] SET RECOVERY SIMPLE
GO
--壓縮資料庫
DBCC SHRINKDATABASE ([MyDatabase], 1)
GO
--切換回完整模式
ALTER DATABASE [MyDatabase] SET RECOVERY FULL
GO
```
# 2. 特殊狀況: 壓縮資料庫指令無效
>感謝 Carey 大大救援
正常情況下,使用步驟1.的方式就可以釋出空間。
但這次有遇到一個狀況,使用正常流程去壓縮後,
既**沒有錯誤訊息,mdf檔也沒有瘦身**...
這時候就可以透過以下步驟來修復資料庫。
## 2.1 檢查DB
先用下面的命令檢查 db
```sql=
--檢查DB
DBCC CheckDB('MyDatabase')
GO
```
發現下圖的錯誤,有三個 GAM 異常,導致無法正常配置檔案區

## 2.2 修復資料庫
使用下面的指令修復後,DB就恢復正常,可以使用步驟1.正常壓縮了~~
```sql=
ALTER DATABASE [MyDatabase]
--切換單一模式
SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
--修復資料庫
DBCC CHECKDB('MyDatabase', REPAIR_ALLOW_DATA_LOSS)
GO
--切換成多人模式
ALTER DATABASE [MyDatabase]
SET MULTI_USER;
GO
```
## 2.3 後記
>來自Carey大大講解筆記
MsSql 對他自己的檔案會做內部的配置,
這裡面包含 gam、sgam、iam data,sp 這些資訊的儲存,
但這次問題是他有三個配置區塊因為不見了,
他就直接認定每一個區塊有 4g 的空間3個 gam 就有 12g。
這幾個儲存方式,有點像我們以前的磁碟裡面會有個 FAT 做檔案位置紀錄的功能,
而磁碟的**快速格式化**會這麼快,就是直接把 FAT 的資料清了,就以為硬碟變全新的。
名詞參考:
https://topic.alibabacloud.com/tc/a/differences-between-gam-sgam-pam-iam-dcm-and-bcm-in-sql-server_1_42_32302767.html