由湯尼戴維斯,2012 / 01 / 27 web
這篇文章是樓梯系列的一部分:在SQL Server事務日誌管理的樓梯sql
當事情進展順利,沒有須要特別在乎日誌或它是如何工做的交易。你只須要相信,每個數據庫已經有正確的備份制度。當事情出錯時,瞭解事務日誌是重要的採起糾正措施,特別是在一個時間點恢復數據庫是必需的,迫切的!Tony Davis只給出正確的細節層次,每一個DBA都應該知道。數據庫
在這個層面咱們會反省爲什麼以及如何執行日誌備份,當工做在所有
恢復模式,以及如何執行數據庫恢復使用這些日誌備份文件,在完整數據庫備份相結合。所有
恢復模式支持數據庫恢復到任什麼時候間點內可用的日誌備份,若是尾日誌備份能夠用,到最後提交的事務的時間,在發生故障。服務器
進入所有
恢復模式下,全部的操做都是徹底記錄。爲插入
,更新
和刪除
操做,這意味着每行被修改,會有一個日誌記錄描述交易進行聲明的ID,當交易開始和結束,哪些頁面被改變,數據變化了,等等。less
操做能夠最小日誌記錄選擇
成
,散裝
插入
和創造
指數
,仍然徹底記錄在工做所有
恢復模式,但它是略有不一樣。行受這些操做不記錄個別;只數據庫頁被記錄,由於他們獲得了。這下降了測井聽到這樣的操做,同時確保存在的信息存在,須要進行回滾,重作和時間點恢復。Kalen Delaney已經發表了一些調查記錄選擇進入
(http://sqlblog.com/blogs/kalen_delaney/archive/2011/03/15/what-gets-logged-for-select-into.aspx)和重建索引(http://sqlblog.com/blogs/kalen_delaney/archive/2011/03/08/what-gets-logged-for-index-rebuilds.aspx)操做,在所有
和bulk_logged
恢復模式。在最小日誌記錄操做日誌記錄的差別,當工做在bulk_logged
模式,更詳細的討論,在6級–管理登陸 大容量日誌 恢復模式。工具
進入所有
恢復模式,只有一個日誌備份能夠致使日誌截斷。所以,事務日誌將保持完整的交易自上次事務日誌備份進行記錄。由於全部的操做都是徹底記錄,日誌文件會變得很大,很快,在繁忙的系統。sqlserver
所以,當工做在所有
恢復模式,它是 相當重要的你作的常規事務日誌備份,除了完整備份和差別備份,可選。不少新手或兼職DBA執行徹底備份對數據庫,但他們不執行事務日誌備份。所以,事務日誌不會被截斷,它成長直到它的驅動器上的磁盤空間耗盡,致使SQL服務器中止工做。性能
該日誌截斷將盡快日誌備份是發生,假設從之前的備份,沒有其餘因素推遲截斷髮生了一個檢查站,如數據備份或還原操做。對於一個完整的,可能會延遲恢復體截斷因子列表,以及因素,保持大量的日誌活動,不然就不須要,如一個流氓,長期未提交的事務或數據庫鏡像或複製的過程當中,看到:http://msdn.microsoft.com/en-gb/library/ms345414.aspx。測試
copy_only
備份事務日誌copy_only
備份事務日誌不截斷事務日誌。一copy_only
日誌備份存在「獨立」的正常日誌備份方案;它不破的日誌備份鏈。ui
總之,事務日誌備份執行容許還原和恢復到以前的某個時間點的雙重目的,以及控制事務日誌的大小。可能交易的最多見的緣由是工做日誌的相關問題所有
恢復模式和不帶日誌備份,日誌備份或沒有足夠頻繁的大小來控制事務日誌文件。
若是你不肯定是否事務日誌備份正在採起在一個給定的數據庫,那麼你能夠簡單地詢問備份集表中msdb
數據庫,使用查詢相似於清單5.1所示。
使用msdb; 選擇backup_set_id, backup_start_date, backup_finish_date, backup_size, recovery_model, [型]
清單5.1:是日誌備份了嗎?
在類型
柱,一個D
表明一個數據庫備份,l
一個日誌備份I
差別備份。
注意,由於在這種數據備份集表能夠被操縱而不影響備份和恢復性能,你可能想驗證你的結果從這個查詢,經過查詢sys.database_recovery_status
看的價值last_log_backup_lsn
(參見清單3.5),或sys.databases
表看的價值log_reuse_wait_desc
(將返回log_backup
若是備份是必需的)。
正如前面所討論的,這是不可能執行事務日誌備份不先以致少一個完整的備份。事實上,若是你有一個數據庫,在所有
恢復模式,但歷來沒有備份,那麼它將不會工做所有
恢復模式。該數據庫將自動截斷模式直到進行第一次完整備份。
全部的數據庫備份,日誌全,或以其餘方式,進行備份
命令。命令接受無數次的選擇,這是記錄在這裏:http://msdn.microsoft.com/en-us/library/ms186865.aspx。然而,在其最基本的,這每每是如何使用,命令執行徹底備份到磁盤以下:
數據庫備份<em>數據庫</em>磁盤=「<em>filelocation \ databasename.bak</em>」;
若是這是首次進行的備份,databasename.bak
文件會在指定的目錄中建立。若是此文件已經存在,則默認行爲是,追加後續的備份文件。重寫此行爲,並規定任何現有文件將被覆蓋,咱們可使用初始化
選項,以下:
數據庫備份<em>數據庫</em>磁盤=「<em>filelocation \ databasename.bak</em>與初始化;
最多見的,然而,每一個後續的備份是一個獨特的名字;更在這即將到來的部分,<em>恢復到故障點</em>。
在每次按期(如每日)全備份,會有頻繁的日誌備份(例如每小時),其基本的命令很是類似:
備份日誌<em>數據庫</em>磁盤=「<em>filelocation \ databasename_log.bak</em>」;
顯然,備份的數據和日誌文件不能存放在同一個驅動器,主機的活檔案。若是硬盤有硬件故障而後你全部的副本都將隨着生活的文件丟失,和備份就白費了。文件要備份到一個獨立的設備,或備份到本地,鏡像驅動器。
在之前的水平,注意,你能夠將日誌備份每15分鐘,甚至更多。在這種狀況下,爲了不須要恢復大量的事務日誌文件,你能夠選擇備份方案包括全備份和差別備份的穿插,穿插的事務日誌備份。
在現實中,備份方案更多的是理想與現實之間的妥協,對損失數據的真實風險評估之間,它將使公司的成本和費用,減小風險。許多重要的商業應用程序使用較爲簡單,但嚴格的備份方案,也許涉及按期夜間全備份加上每小時的事務日誌備份。
日誌備份的頻率也可由交易數量的數據庫對象。很是繁忙的數據庫,它可能須要備份常常爲了控制日誌大小。
有沒有簡單的方法來計算常常把日誌備份。大多數數據庫管理員會在多久日誌備份應採起他們的最佳估計,而後觀察文件的生長特性,而後調整備份方案以防止過大的。
值得注意的是,這是不可能執行事務日誌備份不先以致少一個完整的備份。爲了恢復數據庫到一個時間點,或者一個特定的日誌備份或到某個時間點結束在一個特定的日誌備份,必須存在一個完整的不間斷的鏈條,日誌記錄,從後全採起的第一個日誌備份(備份或差別備份),直到失敗這一點。這是被稱爲<strong>日誌鏈</strong>。
有許多方法來打破鏈,若是你這樣作就意味着你只能將數據庫恢復到日誌備份事件發生前採起斷鏈的時間。總之,斷鏈是<strong>不是</strong>一個好主意,若是你關心的能力來恢復您的數據。兩打破鏈的最多見的方式包括:
簡約
恢復模式若是你從–所有
到簡約
恢復模式,這將打破鏈做爲一個檢查點會煽動和事務日誌能夠當即截斷。當你回到所有
模式,你將須要一個完整備份恢復日誌鏈。事實上,直到你徹底備份,數據庫將自動截斷模式和沒法備份日誌文件。SQL Server 2008前,有一對夫婦的命令,即備份
日誌
與no_log
或備份
日誌
與
truncate_only
(他們在功能上是等價的),發的時候,會迫使一個日誌文件截斷,因此打破鏈。你不該該在任何版本的SQL Server發出這些命令,但我在這裏提到它們,他們仍然會被粗心的使用,當試圖處理一個「失控的日誌文件」,而不理解它所具備的意義爲他們恢復他們的數據庫能力。看到8級–的幫助下,個人日誌已滿,更多的細節。
只要你有一個最近的完整備份和一個完整的日誌鏈,你能夠恢復你的數據庫的一種狀態,它存在於最終的日誌備份結束以前的任何失敗。然而,假如你把事務日誌備份時,的時間,以及故障發生在下午1:45。你可能會失去45分鐘的數據;事實上,若是失敗是災難性的,因此生活事務日誌是沒法挽回的,那麼就是數據量會失去你。
然而,有時候生活事務日誌仍然能夠即便數據文件不可用,特別是若是事務日誌包含在一個單獨的、專用的驅動。若是是這種狀況,你應該備份事務日誌的生活即執行的日誌記錄最後備份自上第二天志備份後生成的。這將在日誌文件中捕獲住剩餘的日誌記錄,到故障點。這被稱爲<strong>尾日誌備份</strong>,是最後的行動開始前應進行還原和恢復操做。
若是數據文件不可用,因爲數據庫故障,和日誌的尾部含有最小日誌記錄操做,那麼就不可能作尾日誌備份,這就須要在數據文件中獲取數據的變化程度。這將包括更詳細的<em>6級,</em><em>管理</em><em>事務日誌在大容量日誌模式</em>。
若是你想恢復數據庫在線,而後備份日誌尾部是以下:
備份日誌<em>數據庫</em>磁盤=「<em>filelocation \ databasename_log.bak</em>「WITH NORECOVERY
這個使用NORECOVERY
選項使數據庫在恢復狀態,假設下一個行動,你要執行的是一個恢復
。若是數據庫處於離線狀態,啓動不了,你仍是應該嘗試備份日誌尾部如剛纔所描述的(雖然使用NORECOVERY
選項能夠省略,由於沒有交易將進步)。
若是你確信日誌文件損壞,文件顯示,做爲最後的手段,你想作一尾日誌備份:
備份日誌<em>數據庫</em>磁盤=「<em>filelocation \ databasename_log.bak</em> ' continue_after_error
若是主數據庫和數據文件被損壞,但日誌是可用的,微軟建議重建master數據庫,而後備份活動日誌。然而,這些主題在這樓梯的範圍,我是指你的文件的詳情。看到http://msdn.microsoft.com/en-us/library/ms190952.aspx。
進行尾日誌備份,若是可能的話,下一步就是要恢復上次徹底備份(其次是差別備份,若是合適的話),而後恢復日誌備份文件的完整序列,包括尾日誌備份。這個序列的基本語法恢復操做以下:
恢復數據庫日誌} { |<em>數據庫</em>從磁盤=「<em>filelocation \ filename.bak</em>「WITH NORECOVERY;
若是當你恢復你的省略與
使用NORECOVERY
選項,則默認恢復
命令將與
恢復
。換句話說,SQL Server將數據和日誌文件的調和,向前滾動完成交易而後回滾未完成事務的必要。經過指定與
使用NORECOVERY
,咱們指示SQL Server,咱們正在進入一個還原順序,更多的操做必須向前滾動,在任何能夠進行回滾。在還原順序還原最後一個備份後,數據庫就能夠恢復以下:
還原數據庫的語句
一個共同的要求是要將數據庫還原到不一樣的位置,在這種狀況下,你能夠簡單地將文件做爲恢復過程的一部分,這裏所描述的那樣:http://msdn.microsoft.com/en-us/library/ms190255.aspx。
下面的示例說明如何迴應一個故障恢復數據庫,該數據庫的數據文件沒法訪問。
假設「活」的事務日誌能夠是一個數據庫失敗後得出的,也許是由硬件故障引發的,那麼在理論上應該能夠恢復和恢復數據庫到故障點,採用如下步驟:
不少例子發如今線圖書展現恢復從「備份集」,就是一個「裝置」,全部的備份存儲。在實踐中,這意味着,當備份到磁盤備份設備是單.bak
位於某處的磁盤文件。
因此,例如,清單5.2中的例子使用一個備份集組成的一個完整備份和事務日誌備份,並說明如何執行徹底恢復。爲了運行這段代碼,你須要先建立其中
數據庫而後插入一些樣本數據行(爲方便起見,腳原本作這個,createandpopulatetestdb.sql,包含在這一等級的代碼下載)。你還須要建立在本地「備份」目錄C:
你的數據庫服務器的驅動器,或修改文件路徑適當。
-- Perform a full backup of the Test database -- The WITH FORMAT option starts a new backup set -- Be careful, as it will overwrite any existing sets -- The full backup becomes the first file in the set BACKUP DATABASE TestDB TO DISK = 'C:\Backups\TestDB.bak' WITH FORMAT; GO -- Perform a transaction log backup of the Test database -- This is the second file in the set BACKUP Log TestDB TO DISK = 'C:\Backups\TestDB.bak' GO -- ....<FAILURE OCCURS HERE>.... -- The RESTORE HEADERONLY command is optional. -- It simply confirms the files that comprise -- the current set RESTORE HEADERONLY FROM DISK = 'C:\Backups\TestDB.bak' GO -- Back up the tail of the log to prepare for restore -- This will become the third file of the bakup set BACKUP Log TestDB TO DISK = 'C:\Backups\TestDB.bak' WITH NORECOVERY; GO
清單5.2:備份,恢復,備份集;不推薦
然而,使用備份集彷佛未的時候,數據庫備份到磁帶。當備份到磁盤,這是一個壞主意,用這個方案,由於,固然,備份文件會迅速成長很是大。
在實踐中,每一個完整備份和事務日誌備份文件將被單獨命名的狀況更爲常見,並且可能加蓋,備份時的日期和時間。例如,大多數第三方備份工具,受歡迎的社區生成的腳本,加上維護計劃嚮導/ SSMS的設計師,都會建立單獨的文件如<em>adventureworks_full_20080904_000001.bak</em>郵戳日期。
所以,一個更常見的備份和恢復方案將使用惟一命名的備份,如清單5.3所示。
USE master; BACKUP DATABASE TestDB TO DISK ='C:\Backups\TestDB.bak' WITH INIT; GO -- Perform a transaction log backup of the Test database BACKUP Log TestDB TO DISK ='C:\Backups\TestDB_log.bak' WITH INIT; GO -- ....<FAILURE OCCURS HERE>.... -- Back up the tail of the log to prepare for restore BACKUP Log TestDB TO DISK ='C:\Backups\TestDB_taillog.bak' WITH NORECOVERY, INIT; GO -- Restore the full backup RESTORE DATABASE TestDB FROM DISK = 'C:\Backups\TestDB.bak' WITH NORECOVERY; -- Apply the transaction log backup RESTORE LOG TestDB FROM DISK = 'C:\Backups\TestDB_log.bak' WITH NORECOVERY; -- Apply the tail log backup RESTORE LOG TestDB FROM DISK = 'C:\Backups\TestDB_taillog.bak' WITH NORECOVERY; -- Recover the database RESTORE DATABASE TestDB WITH RECOVERY; GO
清單5.3:備份,恢復,惟一命名的備份文件
有時候,不幸的是,它可能沒法執行徹底恢復;若是活的事務日誌不可用而致使的失敗。在這種狀況下,咱們須要恢復到最近的日誌備份的結尾。這是須要準備這種可能性即失敗包含事務日誌的驅動,這決定了多少第二天志備份。若是你須要備份,每15分鐘,那麼你在15分鐘的數據丟失的風險。
想象一下,咱們完成了清單5.4中所示的備份序列。對於此演示的緣故,咱們覆蓋之前的備份文件和備份序列明顯縮短要比現實中的。
-- FULL BACKUP at 2AM USE master ; BACKUP DATABASE TestDB TO DISK = 'C:\Backups\TestDB.bak' WITH INIT ; GO -- LOG BACKUP 1 at 2.15 AM USE master ; BACKUP LOG TestDB TO DISK = 'C:\Backups\TestDB_log.bak' WITH INIT ; GO -- LOG BACKUP 2 at 2.30 AM USE master ; BACKUP LOG TestDB TO DISK = 'C:\Backups\TestDB_log2.bak' WITH INIT ; GO
清單5.4:短系列的日誌備份
若是發生災難性故障的凌晨2:30分後不久,咱們可能須要將數據庫還原到它的存在,在日誌備份2年末的狀態,在凌晨2:30分。
恢復這樣的一個例子序列,咱們前面看到的很類似,在清單5.3中,但因爲尾備份是不可能的,咱們只可以恢復到某一點,咱們須要使用在
選項,如清單5.5所示。
--RESTORE Full backup RESTORE DATABASE TestDB FROM DISK = 'C:\Backups\TestDB.bak' WITH NORECOVERY; --RESTORE Log file 1 RESTORE LOG TestDB FROM DISK = 'C:\Backups\TestDB_log.bak' WITH NORECOVERY, STOPAT = 'Jan 01, 2020 12:00 AM'; --RESTORE Log file 2 RESTORE LOG TestDB FROM DISK = 'C:\Backups\TestDB_Log2.bak' WITH NORECOVERY, STOPAT = 'Jan 01, 2020 12:00 AM'; --Recover the database RESTORE DATABASE TestDB WITH RECOVERY; GO
清單5.5:恢復到某個時間點,用在
既然咱們已經指定了一個在
在將來的時間裏,這段代碼將回滾全部完成交易到第二事務日誌的結束。
另外,指定一個可能在
時間,屬於記錄在一個特定的日誌文件的交易時間範圍。在這種狀況下,數據庫將恢復到上次提交的事務在規定時間。這是有用的當你知道你要恢復到何時,但不知道什麼是日誌備份包含時間。
它也能夠恢復到一個特定的標記的事務。這是很是有用的,例如,你須要恢復多個數據庫,經過必定的程序訪問,在邏輯上一致的點。這個話題不在這裏進一步討論,但你能夠找到更多關於圖書在線(http://msdn.microsoft.com/en-us/library/ms187014.aspx),和Mladen prajdic提供了一個很好的例子:http://weblogs.sqlteam.com/mladenp/archive/2010/10/20/sql-server-transaction-marks-restoring-multiple-databases-to-a-common.aspx。
對任何數據庫故障的狀況以外,可能須要恢復數據庫備份,加上事務日誌,以一個數據庫返回到時間就在一個錯誤的數據修改了某個特定的點,如刪除或截斷表。
你這種狀況的反應將取決於問題的性質。若是可能的話,你可能會從數據庫斷開全部用戶(在通知他們),並評估剛剛發生了什麼事的影響。在某些狀況下,您可能須要估計問題發生而後徹底恢復的數據庫和日誌的時間點恢復時間。一旦恢復了,你要通知用戶一些交易可能已經丟失,並請求原諒。
固然,你常常不可以以這種方式中斷正常的業務操做,解決一個意外的數據丟失。因爲實時數據庫仍然正常運行和訪問,你能夠嘗試恢復數據庫的備份備用物品
模式。這容許進一步的日誌備份來恢復但不像使用時使用NORECOVERY
,數據庫仍然是可讀的。還原方案可能看起來像這樣:
備用物品
模式,與實時數據庫Of course, this process is not necessarily straightforward, and can be quite time-consuming. Unless you've purchased a specialized log reading tool, and can interrogate the log backup directly, rolling the logs forward can mean a series of painstaking steps involving restoring a log, checking the data, restoring a bit further, and so on, until you've worked out exactly where the bad transaction occurred. 3步是困難的,由於你將引入數據到現場系統與數據庫的當前狀態必然是不一致的,因此能夠參照完整性問題。
讓咱們在執行步驟1和2以上,看一個例子。首先,讓咱們再從頭開始運行createandpopulatetestdb.sql腳原本建立其中
數據庫,並插入10行測試數據到一個新的logtest表在清單5.6中,咱們簡單的作一個完整的數據庫備份(覆蓋任何之前的備份文件)。您須要建立的「備份」目錄,若是你沒有這樣作,或適當調整路徑。
-- full backup of the database BACKUP DATABASE TestDB TO DISK ='C:\Backups\TestDB.bak' WITH INIT; GO
清單5.6:TestDB的徹底備份
而後,咱們將一個新的數據行插入到LogTest表中
USE TestDB GO INSERT INTO [TestDB].[dbo].[LogTest] ([SomeInt] ,[SomeLetters2]) VALUES (66666, 'ST') SELECT * FROM dbo.LogTest
清單5.7:插入一個第十一行插入其中
因此如今咱們有一個活其中
11數據庫中的行logtest表,以及備份與10行版本。如今讓咱們來捕獲日誌備份額外的修飾,如清單5.8所示。
USE master GO BACKUP Log TestDB TO DISK ='C:\Backups\TestDB_log.bak' WITH INIT; GO
清單5.8:日誌備份其中
如今,咱們要模擬一個錯誤的「糟糕的交易」,簡單地把<em>logtest</em>表,以後咱們作的最後一個日誌備份。
USE TestDB GO DROP TABLE dbo.LogTest ; USE master GO BACKUP Log TestDB TO DISK ='C:\Backups\TestDB_log2.bak' WITH INIT; GO
清單5.9:災難!
爲了試圖找回丟失的數據,在不中斷業務的正常運行,咱們將恢復的副本其中
數據庫備用物品
模式。的備用數據庫的數據文件和日誌文件,稱爲ANewTestDB,移動到「待機」目錄(你須要事先建立這個目錄)。
-- restore a copy of the TestDB database, called -- ANewTestDB, in STANDBY mode USE master ; GO RESTORE DATABASE ANewTestDB FROM DISK ='C:\Backups\TestDB.bak' WITH STANDBY='C:\Backups\ANEWTestDB.bak', MOVE 'TestDB_dat' TO 'C:\Standby\ANewTestDB.mdf', MOVE 'TestDB_log' TO 'C:\Standby\ANewTestDB.ldf' GO
清單5.10:恢復副本其中
進入備用物品
模式
咱們如今有一個新的數據庫,稱爲新的<em>庫</em>
,和它的「待機/只讀」模式,如圖5.1所示。
圖5.1:備用數據庫
一個查詢logtest
表中anewtestdb數據庫將顯示10行。然而,咱們想把表回狀態是在以前它被錯誤地降低。所以,下一步是執行還原日誌備份到備用數據庫。
USE master GO RESTORE LOG ANewTestDB FROM DISK = 'C:\Backups\TestDB_log.bak' WITH STANDBY='C:\Backups\ANewTestDB_log.bak'
清單5.11:還原日誌備份的anewtestdb數據庫,在備用物品
模式
在這一點上,查詢<em>anewtestdb</em>顯示11行,咱們如今能夠將數據從新進入實時數據庫。若是咱們更進了一步,恢復第二日誌備份,咱們意識到咱們已經走得太遠了,表會丟失在備用數據庫以及。
另外一個作備用恢復是考慮使用第三方工具如紅色的門SQL虛擬還原,這一方式來安裝備份爲生活提供全功能的數據庫,沒有身體的恢復。
不管他們喜歡與否,開發商常常訪問生產數據庫來完成特定數據負載和變化。這是DBA和開發人員的共同責任,確保順利進行,因此不會形成須要的這種行動只是描述問題。咱們回到這個話題,後來在<strong>6級處理批量操做</strong>。
固然,所需的修復做用的確切性質取決於糟糕的交易性質。若是一個表是「不當心掉了」,那麼頗有可能你會走的恢復
與
備用物品
路線。在其餘時候,你可能會去作一個簡單的腳原本「逆淘汰」的流氓的修改。
若是傷害只會影響單柱或有限數量的行,那麼它是可能的,做爲一種替代方法,使用的工具,如SQL數據的比較,能夠比較直接的備份文件,能夠作行級恢復。
或者,若是你運行SQL Server 2005企業版(或之後),和提供最近的數據庫快照,您能夠運行一個對快照查詢來檢索數據,它看了看時間數據庫快照拍攝,而後寫一個更新
或插入
命令將數據從數據庫快照到現場,源數據庫。
最後,做爲最後的手段,一個專門的日誌讀取器工具能夠幫助你扭轉了影響交易的雖然我不知道有任何可靠地工做在SQL Server 2005及之後。
在這個層面上,咱們已經備份和恢復日誌文件的數據庫操做的基本知識所有
恢復模式,這將對許多生產數據庫規範。
對於大多數數據庫管理員,須要執行時間點恢復是一種罕見的事件,但它是一個任務,若是有必要的話,它絕對是相當重要的,它是作的,作的很好;DBA的聲譽取決於它。
在腐敗案件的驅動器故障,等等,時間點恢復可能涉及,若是你幸運的話,備份尾事務日誌和恢復到故障點的權利。若是事務日誌不可用,或者若是你恢復以恢復到某個時間點,一個「壞交易」發生以前,那麼狀況就變得比較複雜,但但願一些覆蓋在這一步的技術將幫助。