sqlserver自動收縮數據庫引起大量阻塞
最近遇到一個數據庫設置了自動收縮,收縮期間引起大量阻塞的問題,記錄下看到的文章學習
什么是自動收縮?

隨着數據量的增加數據庫的設備文件(MDF\LDF)會不斷增長,當數據庫中的某些數據刪除,數據庫設備文件的大小並不會隨着數據量的減少而減少,數據庫設備需要占用的磁盤空間就沒那么大了,這時候自動收縮就可以釋放出磁盤空間,主要直觀體現在數據庫設備文件的大小上,避免資源的浪費.
在什么條件下會觸發?
在開啟自動收縮選項的情況下,SQL Server定期會檢查文件使用情況。如果空閑空間大於25%,SQL Server就會自動運行自動收縮數據庫文件的動作。
例如:數據遷移刪除大量數據時,空閑空間大於25%時,會觸發自動收縮功能。
帶來的危害(自動收縮和手動收縮)?
對於一個磁盤空間很緊張的系統,這個設置無疑是有幫助的。但是從數據庫自身的健康和性能考慮,這個設置並不建議多用。這是因為:
1、數據文件收縮導致了索引的完全碎片化,索引的效率大大降低,嚴重影響性能。
2、數據文件的收縮同樣產生了大量的I/O操作,耗費大量的CPU資源,性能下降。
3、在業務高峰期的時候可能會造成大量的阻塞。
關於收縮的建議
不到萬不得已,千萬不要收縮數據庫。收縮數據庫影響極大:
1.收縮數據庫對數據庫的影響極大,產生大量日志和碎片,而且會鎖表。如果你的庫當前正在被使用,收縮不下去非常正常。
2.收縮數據庫一定要手工來做的,而且是在維護窗口期做。
3.盡量使用語句來執行,可以提示錯誤
4.盡量一次不要收縮太多,分幾次收縮。
下面的文章詳細介紹:
http://www.sqlskills.com/blogs/paul/why-you-should-not-shrink-your-data-files/.
收縮的正確姿勢
在不得不收縮的時候,參考下面的步驟
1.找到數據庫中最大的幾個表,重建所有索引。首先嘗試指定Truncate Only收縮方式.它只是移除文件尾部的空閑空間,並不重新組織已經使用的數據頁。
DBCC SHRINKDATABASE (AdventureWorks2012, TRUNCATEONLY);
2 最后才考慮,不帶選項的收縮。收縮不要一次性全部收縮。 可以每次收縮2G左右。不要把空間可用空間全部收縮了,可以剩余一部分比如4G。收縮完后,記得重建索引.
補充:
還有一種辦法就是新建文件組,使用CREATE INDEX ... WITH(DROP_EXISTING = ON)ON語法將所有相關的的表和索引移動到新文件組。然后收縮舊的文件組。
3.可在進程中的任一點停止 DBCC SHRINKDATABASE 操作,任何已完成的工作都將保留。
4. 不能在備份數據庫時收縮數據庫
可能需要收縮的場景
1.你刪除了大量數據,而且數據不太可能增長。
2.要移除某個文件時,你需要先清空數據文件。
總結
那我們處理磁盤空間不足的最好的辦法是什么呢?最好的辦法是在最初規划時,預估好未來一年或者二年的數據增長。給磁盤划分足夠的空間。設置好數據庫的初始大小,並且將自動增長使用固定量增長。
收縮數據庫可以半途停止嗎
收縮數據庫可以中途停止嗎?
數據庫太大了,有100多個G的可以釋放空閒,想要收縮,現在已經收縮15個小時了,還沒完成,請問可以停止嗎?對數據庫又有影響嗎?
執行語句:
DUMP TRANSACTION TelODS WITH NO_LOG
BACKUP LOG TelODS WITH NO_LOG
DBCC SHRINKDATABASE(N'TelODS' )
------解決方案--------------------
可以停止,沒影響的,下次再收縮,建議100M一次來做
------解決方案--------------------
微軟的sql server文檔中寫的,你可以輸入 dbcc shrinkdatabase搜索,就有的:
可在進程中的任一點停止 DBCC SHRINKDATABASE 操作,任何已完成的工作都將保留。
------解決方案--------------------
如果在確定沒有影響正常使用的情況下, 100G的可用空間,值得等待下去。
收縮停止,對應數據庫沒有特別的影響。 損失的,就只之前執行所用的這15個小時時間成本。
說不定再等一個小時,收縮就完成了。
目前為止,我碰到最長的等待大概在22小時左右。 不停業務的情況下。
------解決方案--------------------
在使用此語句前,關閉所有調用數據庫的程序,重啟sqlserver
建議已經收縮了的繼續等待,
其實在做收縮前做好進行測試,mssql 還是有一定的風險,特別在刪除數據並收縮的時候
