為什麼我不能在完全恢復模式下收縮日誌文件
我有一個 302MB 的日誌文件。
我做了一個日誌備份,它使日誌文件大部分空閒(我可以通過磁碟使用標準報告看到這一點)
如果我嘗試跑步
DBCC SHRINKFILE (N'AdventureWorks2014_Log' , 0, TRUNCATEONLY)
或者
DBCC SHRINKFILE (N'AdventureWorks2014_Log' , 0)
該文件仍顯示為 302MB。
我知道我可以將數據庫更改為簡單恢復,然後執行上述命令之一併設置回完全恢復(然後進行完全備份以確保數據庫不處於偽簡單恢復模式)
但是,為什麼我不能在完全恢復模式下縮小文件?
我知道收縮不是你應該做的事情,但在我的真實世界數據庫中,由於沒有人備份過事務日誌,它已經增長到 30GB,現在定期日誌備份已經到位,以防止這個級別的增長
但是,為什麼我不能在完全恢復模式下縮小文件?
它按設計工作。您只需要更多地了解正在發生的事情,這樣您就可以決定採取哪些適當的措施。
那,或者你只是想在錯誤的時間縮小它(見下面我的註釋#7)。
首先,“日誌文件”有點用詞不當:SQL 使用事務日誌作為它所做的一切的“工作空間”,因此它的大小總是非零。根據我的經驗,我通常希望 tran 日誌在數據文件大小的 10% 到 25% 之間,具體取決於您使用的恢復模式以及數據庫上的活動類型。你沒有提到你的數據文件的大小,所以我無法判斷 302MB 是否很大(坦率地說,這對我來說聽起來不是很大)。
關於恢復模式,這裡的關鍵問題是:如果您必須恢復數據庫(由於緊急情況),您是否需要“時間點”恢復?還是恢復到最新的完整備份就足夠了?
撇開一些不尋常的情況(複製/CDC/鏡像/可用性組)不談,您的恢復模式選擇更多的是業務決策,而不是技術決策。在任何一種模式下,SQL Server 都將事務日誌用於程序內事務,不同之處在於接下來會發生什麼:
- 完全恢復模式:當事務完成時,它會保留在 tran 日誌中,直到您執行事務日誌備份。這往往會使日誌變大(取決於您執行日誌備份的頻率),但這意味著您可以在發生災難時進行“時間點”恢復:您可以恢復最新的完整備份,然後使用tran 日誌備份“前滾”到災難發生之前。
- 簡單恢復模式:當一個事務完成時,它在 tran 日誌中使用的空間立即可供以後的事務重用。這使事務日誌文件(相對而言)較小,但意味著在發生災難時您唯一的選擇是從最新的完整備份中恢復。
在某些公司中,您將對所有生產數據庫使用 FULL,對所有 QA/DEV 環境使用 SIMPLE。或者,某些特定的數據庫(例如用於報告和/或數據處理的數據庫)可能不需要完全恢復,因為您可以簡單地重新執行前一天的處理以恢復最新狀態。但就像我說的,這是一個業務決策/風險分析問題,而不是真正的技術問題。
因此,如果您不需要時間點恢復,請將其切換到簡單模式,然後保持這種狀態。
如果您確實需要時間點恢復,則將其切換到完整模式,並根據您的業務風險/恢復需求全天執行定期 tran 日誌備份。每小時很受歡迎,但有些人更頻繁地推薦它們。
我之前提到的最後一點:一旦你選擇了正確的恢復模式,你可能仍然需要收縮一個過大的日誌。要記住幾件事:
- 再次確保您選擇了正確的恢復模式
- 如果您在 FULL 模式下執行,請確保您正在執行頻繁的 tran 日誌備份
- 為日誌選擇一個合理的目標大小,切勿嘗試將其縮小為零。我通常根據數據文件的總大小(或至少數據文件中的已用空間)對其進行縮放
- 閱讀並理解有關 VLF 大小的重要建議。這可能會為確定合理的日誌大小提供更多指導,或者為您提供更好的方法來使日誌達到該大小。
- 永遠不要用
SHRINKDATABASE
,永遠用SHRINKFILE
- 在簡單模式和完整模式下,日誌文件的結尾都有可能目前正被 SQL 用於活動事務。如果是這種情況,那麼它不會像你想要的那樣縮小。幾分鐘後再次收縮,如果事務完成,第二次應該會更好。
- 在完全恢復模式下使用特別頑固的 tran 日誌,我很幸運
SHRINKFILE
,緊接著是事務日誌備份,緊接著是另一個SHRINKFILE
.
有關 SQL Server 事務日誌文件的相關資訊是它們是以循環方式寫入的。這會過度簡化事情,並省略一些細節,如虛擬日誌文件(它實際上是如何在內部處理的),但它是對現實的合理複製。
想像一下,您創建了一個數據庫並給它一個 100 MB 的事務日誌文件。事務將從文件的開頭開始寫入。假設您有 50 MB 的事務活動。您現在正在使用 100 MB 事務日誌的前 50 MB。然後進行事務日誌備份。現在您幾乎沒有使用事務日誌中的空間;實際上,整個東西都可以(重新)使用。但是,如果您嘗試將日誌縮小到 20 MB,會發生什麼?它會將其縮小到(大約)50 MB。
這是因為日誌的活動部分恰好位於 50 MB 標記附近,並且 SQL Server 不會將日誌縮小到目前活動的位置。可以把它想像成盒式磁帶上的播放磁頭,SQL Server 不會/不能對已經在捲軸上的磁帶做任何事情。
這就是為什麼收縮事務日誌通常是一個兩步過程:您進行第一次備份和收縮(切掉播放頭之後的所有空磁帶),然後生成一些事務活動,以便 SQL Server 被迫迴繞繞到日誌文件的開頭(倒帶磁帶),最後再做一次備份和收縮(切掉更多的空磁帶以達到您的目標大小)。
請注意,還有一些其他情況可能會阻止您重用(從而縮小)日誌。
log_reuse_wait_desc
通常您可以通過查看 中的列來找出原因master.sys.databases
。事務複製、數據庫鏡像和 AlwaysOn 可用性組是常見的罪魁禍首。