2012年11月21日星期三

SQL 2005日志文件损坏后应当如何恢复

假设数据库名称是 ds_shop

alter database ds_shop set emergency
use master
exec sp_dboption ds_shop, N'single', N'true'
dbcc checkdb('ds_shop',REPAIR_ALLOW_DATA_LOSS)
dbcc checkdb('ds_shop',REPAIR_REBUILD)
exec sp_dboption 'ds_shop', N'single', N'false'
exec sp_resetstatus 'ds_shop'
exec sp_dboption 'ds_shop','single user','false'



***************************

在实际的工作和学习中,许多人的SQL Server 2005数据库日志文件可能会发生损坏,例如硬件故障、计算机非正常重启或关机等等。 在SQL Server 2005的日志文件损坏时,你会发现以下的情况:
◆1、在SQL Server Management Studio中显示数据库处于置疑(suspect)状态。
◆2、事件日志可能会出现如下错误信息: Could not redo log record (217376869), for transaction ID (02334886), on page (137527), database 'Test' (database ID 15). Page LSN = (217352995), type = 2. Log OpCode = 3, context 19, PrevPageLSN (217376151). Restore from a backup of the database, or repair the database. During redoing of a logged operation in database 'Test', an error occurred at log record ID (761162862). Typically, the specific failure is previously logged as an error in the Windows Event Log service. Restore the database from a full backup, or repair the database.
◆3、无法分离数据库
◆4、用CREATE DATABASE DBName ON ( FILENAME = N'DBFile' ) FOR ATTACH_REBUILD_LOG附加数据库时出现提示:The log cannot be rebuilt because the database was not cleanly shut down.
 详细的恢复方法:
  1、停止数据库服务。
  2、将需要恢复的数据库文件复制到另外的位置。
  3、启动数据库服务。
  4、确认要恢复的数据库文件已经成功复制到另外的位置,然后在SQL Server Management Studio中删除要恢复的数据库。
  5、新建同名的数据库(数据库文件名也要相同)。
  6、停止数据库服务。
  7、用第2步中备份的.mdf文件覆盖新数据库的同名文件。
  8、启动数据库服务。
  9、运行alter database dbname set emergency,将数据库设置为emergency mode
  10、运行下面的命令就可以恢复数据库:
  use master
  declare @databasename varchar(255)
  set @databasename='要恢复的数据库名称'
  exec sp_dboption @databasename, N'single', N'true' --将目标数据库置为单用户状态
  dbcc checkdb(@databasename,REPAIR_ALLOW_DATA_LOSS)
  dbcc checkdb(@databasename,REPAIR_REBUILD)
  exec sp_dboption @databasename, N'single', N'false'--将目标数据库置为多用户状态
  注:这个方法是通过.mdf文件恢复数据库,即使大家的log文件丢失也可以进行恢复。


9. 如果DBCC CHECKDB('ds_shop', REPAIR_ALLOW_DATA_LOSS)命令失败,请转至第10步,否则若成功修复了数据库中的错误:
重新执行DBCC CHECKDB('ds_shop')命令,确认数据库中已没有错误存在。
清除数据库的置疑状态:sp_resetstatus 'ds_shop'
清除数据库的单用户模式状态:sp_dboption 'ds_shop',’single user’,’false’
重新启动SQL Server服务,如果一切正常的话,则数据库已经成功恢复。
10. 如果以上步骤都不能解决问题的话,请参考附件中的文档尝试通过重建事务日志来恢复数据库中的数据。
如果您只有MDF文件,问题就更加复杂一些,我们需要直接重建事务日志了:
1. 在SQL Server中新建一个同名的数据库,然后停止SQL Server服务。
2. 用原有的ldf文件覆盖新建数据库对应的.mdf文件,将其日志文件(.ldf)删除。
3. 启动SQL Server服务,并将数据库置为紧急模式(同上: 步骤5和步骤6)。
4. 停止并重新启动SQL Server服务。
5. 执行以下命令重建数据库日志文件:(下面是个示例,您要用您实际的数据库名)
DBCC REBUILD_LOG('ds_shop', 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\ds_shop_Log.LDF')
6. 重新将该数据库置为单用户模式。(http://support.microsoft.com/?id=264154)
7. 再次尝试使用DBCC CHECKTABLE或DBCC CHECKDB命令检查并修复数据库中的错误

正确执行完成的提示应该类似于:
  警告: 数据库 'test' 的日志已重建。已失去事务的一致性。应运行 DBCC CHECKDB 以验证物理一致性。将必须重置数据库选项,并且可能需要删除多余的日志文件。
  DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
  此时打开在SQL Server Enterprise Manager里面会看到数据库的状态为“只供DBO使用”。此时可以访问数据库里面的用户表了。
  H.验证数据库一致性(可省略)
  dbcc checkdb('test')
一般执行结果如下:
  CHECKDB 发现了 0 个分配错误和 0 个一致性错误(在数据库 'test' 中)。
  DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
  I.设置数据库为正常状态
  sp_dboption 'test','dbo use only','false'
  如果没有出错,那么恭喜,现在就可以正常的使用恢复后的数据库啦。
  J.最后一步,我们要将步骤E中设置的“允许对系统目录直接修改”一项恢复。因为平时直接操作系统表是一件比较危险的事情。当然,我们可以在SQL Server Enterprise Manager里面恢复,也可以使用如下语句完成 [table=95%][tr][td]以下是引用片段:
  sp_configure 'allow updates',0
  go
  reconfigure with override
  go