交易日誌(Transaction logs)是資料庫結構中非常重要但又經常被忽略的部分。由於它並不像資料庫中的schema那樣活躍,因此很少有人關注交易日誌。
交易日誌是針對資料庫改變所做的記錄,它可以記錄針對資料庫的任何操作,並將記錄結果儲存在獨立的檔案中。對於任何每一個交易過程,交易日誌都有非常全面的記錄,根據這些記錄可以將資料檔案恢複成交易前的狀態。從交易動作開始,交易日誌就處於選項組,交易過程中對資料庫的任何操作都在記錄範圍,直到使用者點擊提交或後退後才結束記錄。每個資料庫都擁有至少一個交易日誌以及一個資料檔案。
出於效能上的考慮,SQL Server將使用者的改動存入緩衝中,這些改變會立即寫入交易日誌,但不會立即寫入資料檔案。交易日誌會通過一個標記點來確定某個交易是否已將緩衝中的資料寫入資料檔案。當SQL Server重啟後,它會查看日誌中最新的標記點,並將這個標記點後面的交易記錄抹去,因為這些交易記錄並沒有真正的將緩衝中的資料寫入資料檔案。這可以防止那些中斷的交易修改資料檔案。
維護交易日誌
因為很多人經常遺忘交易日誌,因此它也會給系統帶來一些問題。隨著系統的不斷運行,日誌記錄的內容會越來越多,記錄檔的體積也會越來越大,最終導致可用磁碟空間不足。除非日常工作中經常對日誌進行清理,否則記錄檔最終會侵佔分區內的全部可用空間。日誌的預設配置為不限容量,如果以這種配置工作,它就會不斷膨脹,最終也會佔據全部可用空間。這兩種情況都會導致資料庫停止工作。
對交易日誌的日常備份工作可以有效防止記錄檔過分消耗磁碟空間。備份過程會將日誌中不再需要的部分截除。截除的方法是首先把舊記錄標記為非使用中,然後將新日誌覆蓋到舊日誌的位置上,這樣就可以防止交易日誌的體積不斷膨脹。如果無法對日誌進行經常性的備份工作,最好將資料庫設定為"簡單復原模式"。在這種模式下,系統會強制交易日誌在每次記錄標記點時,自動進行截除操作,以新日誌覆蓋舊日誌。
截除過程發生在備份或將舊標記點標為非使用中時,它使得舊的交易記錄可以被覆蓋,但這並不會減少交易日誌實際佔用的磁碟空間。就算不再使用日誌,它依然會佔據一定的空間。因此在維護時,還需要對交易日誌進行壓縮。壓縮交易日誌的方法是刪除非活動記錄,從而減少記錄檔所佔用的物理硬碟空間。
通過使用DBCC SHRINKDATABASE語句可以壓縮當前資料庫的交易記錄檔,DBCC SHRINKFILE語句用來壓縮指定的交易記錄檔,另外也可以在資料庫中啟用自動壓縮操作。當壓縮日誌時,首先會將舊記錄標記為非使用中,然後將帶有非主動標記的記錄徹底刪除。根據所使用的壓縮方式的不同,你可能不會立即看到結果。在理想情況下,壓縮工作應該選在系統不是非常繁忙的時段進行,否則有可能影響資料庫效能。
恢複資料庫
交易記錄備份可以用來將資料庫恢複到某一指定狀態,但交易記錄備份本身不足以完成恢複資料庫的任務,還需要備份的資料檔案參與恢複工作。恢複資料庫時,首先進行的是資料檔案的恢複工作。在整個資料檔案恢複完成前,不要將其設為完成狀態,否則交易日誌就不會被恢複。當資料檔案恢複完成,系統會通過交易日誌的備份將資料庫恢複成使用者希望的狀態。如果在資料庫最後一次備份後,存在多個記錄檔的備份,備份程式會按照它們建立的時間依次將其恢複。
另一種被稱為log shipping的過程可以提供更強的Database Backup能力。當log shipping配置好後,它可以將資料庫整個複製到另一台伺服器上。在這種情況下,交易日誌也會定期發送到備份伺服器上供恢複資料使用。這使得伺服器一直處於熱備份狀態,當資料發生改變時它也隨之更新。另一個伺服器被稱作監視(monitor)伺服器,可以用來監視按規定時間間隔發送的shipping訊號。如果在規定時間內沒有收到訊號,監視伺服器會將這一事件記錄到事件記錄。這種機制使得log shipping經常成為災難恢複計劃中使用的方案。