由汤尼戴维斯,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的声誉取决于它。
在腐败案件的驱动器故障,等等,时间点恢复可能涉及,若是你幸运的话,备份尾事务日志和恢复到故障点的权利。若是事务日志不可用,或者若是你恢复以恢复到某个时间点,一个“坏交易”发生以前,那么状况就变得比较复杂,但但愿一些覆盖在这一步的技术将帮助。