技术开发 频道

SQL问题与解答:损坏恢复提示、压缩建议

    【IT168 评论】问题:我使用的备份策略是在每天的凌晨 1 点钟进行一次完整备份,每一小时进行一次日志备份,同时,在每天的凌晨 4 点钟会运行一次 DBCC CHECKDB。如果我在上午 8 点开始工作时发现,夜间运行的一致性检查报告了大量损坏的情况,我该如何进行恢复才不会丢失太多数据?

  解答:这取决于损坏发生的时间、损坏的内容以及您所采取的备份措施。理想情况是您事先已制定了灾难恢复计划,因而知道接下来应该怎么操作。不过,我会将您的问题当作假设性问题进行回答。

  根据您的描述,损坏的情况是在完整数据库备份完成后通过运行 DBCC CHECKDB 发现的,据此很难判断是在数据库备份之前还是之后出现的损坏。如果是在数据库备份之前的某段时间出现了损坏的情况,则备份中包含已损坏的数据库版本,因此恢复过程将更加复杂。

  首先要做的是在其他位置还原最近的数据库备份,并对其运行 DBCC CHECKDB。如果未发现损坏情况,请按以下步骤进行还原,这样应该不会丢失任何数据:

  · 运行损坏数据库的日志尾部备份(以捕获最近的事务)。

  · 还原最近的完整数据库备份,指定 WITH NORECOVERY。

  · 使用 WITH NORECOVERY 依次还原自完整数据库备份以来的所有事务日志备份以及日志尾部备份。

  · 使用命令 RESTORE databasename WITH RECOVERY 完成还原过程。

  最后,您应该再运行一次 DBCC CHECKDB 以确保不再存在损坏的内容,然后在第一时间执行根源分析以找出导致损坏的原因,并采取措施解决此问题。

  如果在执行了上述还原步骤后仍存在损坏的内容,则说明某个事务日志备份中可能包含损坏的内容,也可能是内存中包含损坏的内容,随后这些内容被记录到了事务日志中。如果是这种情况,您可能需要执行时间点还原,以确定损坏出现的时间并在此时间之前停止还原。此步骤超出了本专栏的讨论范围,但在联机丛书中对此有详细介绍。

  如果最近的数据库备份确实包含损坏的内容,您可能需要按照上述步骤进行操作,但要从下一个最近的完整数据库备份开始。此操作假定您仍保有此完整数据库备份和所有干预日志备份。

  另一种可用策略(您可能必须采用以适应允许的最长停机时间或恢复时间目标的限制)是手动或使用 DBCC CHECKDB 中的修复功能删除损坏的数据,然后尝试从较早的一系列备份中恢复一些数据。

  从损坏中进行恢复可能非常容易,也可能非常困难,具体取决于错误的根源以及您可以采取的措施。在接下来的几个月内,我将会在几篇文章中对此进行阐述。

  问题:我们的开发团队打算构建一个采用 SQL Server 2008 的更改跟踪功能的解决方案。根据相关文档的说明,我们可能需要针对相关的数据库启用快照隔离,但我担心这样会影响数据库的性能。您对此有何评论?

  解答:我在 2008 年 11 月这一期的杂志(“跟踪企业数据库中的更改”)中对更改跟踪进行了说明,对于您的问题,答案是肯定的,您需要启用行版本控制。这是因为检索已更改数据的机制通常如下:

  查询更改跟踪系统以找出更改的表格行。

  查询表格以检索已更改的行。

  在没有任何行版本控制机制的情况下,如果在执行查询的过程中运行更改跟踪清理任务,则首次查询可能会返回无效结果。而在执行第二次查询前,如果首次查询的结果中引用的一些表格行被删除,则第二次查询可能会失败。

  保持稳定性的一种做法是锁定更改跟踪数据和必需的用户表,但这样会导致并发性能变差(因为阻止的原因)和工作负载吞吐量降低。另一种保持稳定性的做法是使用快照隔离。

  快照隔离有两种,一种是在事务级别提供一致性(数据库选项:allow_snapshot_isolation),另一种是在 T-SQL 语句级别(数据库选项:read_committed_snapshot)提供一致性。事务级别的选项要求正确使用更改跟踪,这种选项简称为快照隔离。

  快照隔离可保持表格记录的版本,举例来说,某个显式事务启动后,从其启动的时间点开始,该事务肯定可以看到数据库的一致的时间点视图。要使用更改跟踪,上述两次查询都应纳入单个显式事务中,隔离级别应设为快照;这样就可以保证一致性。

  我的妻子 Kimberly 在其白皮书“SQL Server 2005 快照隔离”中对快照隔离作了详细的介绍。

  使用快照隔离时,可能会出现两种性能问题。第一种性能问题是,对数据库中的所有表格进行的所有更新都必须生成更改记录版本,即使版本从未使用过也是如此。记录的预更改版本必须被复制到版本存储区中,同时新的记录包含指向较早记录的链接,这是为了应对在此事务完成之前,另一事务启动并需要正确的记录版本的情况。这为所有更新操作都增加了一些处理开销。

  第二种性能问题是,版本存储区位于 tempdb 数据库内。对某些 SQL Server 实例而言,Tempdb 可能是最繁忙的数据库,因为它供所有连接和数据库共享。一般而言,tempdb 可能是一个性能瓶颈,即使不使用行版本控制也是如此。添加行版本控制意味着向 tempdb 增加更多压力(体现在使用的空间和 I/O 操作上),从而可能导致常规的工作负载吞吐量下降。

  您可以阅读白皮书“使用 SQL Server 2005 中的 tempdb”了解更多相关内容。虽然这里提到的两本白皮书都是针对 SQL Server 2005 撰写的,但它们同样适用于 SQL Server 2008。  

点击查看更多TechNet精彩文章

0
相关文章