适用范围:SQL Server
在 SQL Server Enterprise 中,如果在数据库启动期间,回滚(撤消)所需的数据处于脱机状态,则受损的事务可能延迟。 延后事务是指在前滚阶段结束时仍未提交,且因发生错误而无法回滚的事务。 由于事务无法回滚,因此它被延迟。
注意
只有在 SQL Server 企业版中,损坏的事务才会被延迟处理。 在其他版本的 SQL Server 中,事务损坏将导致启动失败。
一般来说,之所以会发生延迟事务,是因为在数据库前滚过程中,I/O 错误导致无法读取该事务所需的某个页面。 但是,文件级错误也会导致延后事务。 当部分还原序列在需要事务回滚的点停止,且事务需要离线数据时,也会发生延迟事务。
如果用户事务在回滚过程中遇到 I/O 错误,则会导致整个数据库脱机。 当数据库重新联机时,重做会重新获取其拥有的所有锁,并尝试回滚所有未提交的事务。 事务修改的所有数据将保持适当的锁定,直到事务可以回滚。 无法回滚的事务将在损坏修复且数据库重启后释放其锁,或者在在线还原后,当数据库保持在线时延迟事务得到解决时释放锁。 在此之前,延迟事务可能持有锁,从而阻止对整个数据库的某些操作。 例如,如果延迟事务包含指令 CREATE TABLE ,则在解析延迟事务之前,用户无法创建表。
延迟事务也可能因为分段还原将数据库恢复到某个时间点而发生,在该时间点一个或多个活动事务影响尚未还原且处于离线状态的文件组。 由于事务无法回滚,因此会处于延迟状态。
下表列出了导致数据库执行恢复的操作以及发生 I/O 问题的后果。
| 操作 | 解决方法(如果遇到 I/O 问题或所需数据处于脱机状态) |
|---|---|
| 服务器启动 | 延期事务 |
| 还原 | 延迟事务 |
| 附加 | 附加失败 |
| 自动重启 | 延迟事务 |
| 创建数据库或数据库快照 | 创建失败 |
| 数据库镜像上的重做 | 延迟的事务 |
| 文件组脱机 | 延迟事务 |
要求和限制
- 数据库必须使用 FULL 或 BULK-LOGGED 恢复模式。
- 必须为数据库完成至少一个数据库和日志备份
- 延迟事务不适用于数据库联机后事务回滚期间遇到的错误。 (例如运行时错误)
- 对于数据库附加期间的恢复失败,事务不能被延迟。
- 某些事务(如系统事务,例如页分配)不能延迟
将事务移出 DEFERRED 状态
重要
延迟的事务会使事务日志保持活动状态。 在延迟的事务脱离延迟状态之前无法截断包含这些事务的虚拟日志文件。 有关日志截断的详细信息,请参阅事务日志 (SQL Server)。
若要使事务脱离延迟状态,数据库必须在没有任何 I/O 错误的情况下顺利启动。 如果存在延迟的事务,则必须修复 I/O 错误源。 下面便是可用的解决方案,它们按照通常尝试执行的顺序列出:
重新启动数据库。 如果该问题只是暂时性的,数据库应能在没有延迟事务的情况下启动。
如果事务由于文件组脱机而延迟,请将文件组重新联机。
若要使脱机文件组恢复联机,请使用以下 Transact-SQL 语句:
RESTORE DATABASE database_name FILEGROUP=<filegroup_name>还原数据库。 进行联机还原后,将解决所有延迟的事务。
在完整恢复模式或大容量日志恢复模式下,如果延迟的事务仅仅是由少量的损坏页引起的,则可以通过联机页面还原解决这些错误(如果支持)。
如果不再需要因脱机状态而导致事务延迟的文件组,请使这样的脱机文件组失效。 由于该文件组处于脱机状态而被延迟的事务,在该文件组变为失效状态后,将移出延迟状态。
重要
已失效的文件组永远无法恢复。
有关详细信息,请参阅删除失效文件组 (SQL Server)。
如果由于页的错误而致使事务延迟,并且没有数据库的完好备份,请按照以下步骤修复数据库:
首先通过执行以下 Transact-SQL 语句将数据库置为紧急模式:
ALTER DATABASE <database_name> SET EMERGENCY有关紧急模式的信息,请参阅 Database States。
然后,通过在以下 DBCC 语句之一中使用 DBCC REPAIR_ALLOW_DATA_LOSS 选项修复数据库: DBCC CHECKDB、 DBCC CHECKALLOC或 DBCC CHECKTABLE。
当 DBCC 遇到坏页时,它会取消分配该页并修复所有相关错误。 此方法可以使数据库重新联机并处于物理上一致的状态。 但是,还可能会丢失其他数据;因此,应在不得已的情况下才使用此方法。
另请参阅
还原和恢复概述 (SQL Server)
删除失效文件组 (SQL Server)
文件还原(完整恢复模式)
文件还原(简单恢复模式)
还原页 (SQL Server)
碎片还原 (SQL Server)
ALTER DATABASE (Transact-SQL)
RESTORE (Transact-SQL)