代码改变世界

如何修复处于recovery挂起状态的数据库

2022-11-12 13:13  abce  阅读(1103)  评论(0编辑  收藏  举报

检查数据库的状态
数据库的状态有:online、offline、restoring、recovering、suspect、emergency、recovery pending

SELECT name, state_desc from sys.databases

 

可能导致恢复挂起的原因
如果处于recovery pending状态了,就表示恢复过程失败了。但数据库未必已经损坏。
原因会有很多种,比如:
1.由于硬件、电池等故障,sqlserver宕机了。当数据库非正常关闭时,一个或多个活跃事务还未完成,但是事务日志被删除了
2.磁盘空间、内存不足了,这种情况下,数据库无法启动恢复过程
3.日志文件损坏了
4.数据文件损坏了

 

如何修复?
在修复之前,要确保你有备份存在。
最好的方式就就是先查看错误日志。


方法1:将数据库状态设置为online
·要保证有足够的磁盘空间用户恢复
·将数据库状态设置为online
·执行CheckDB(不加repair选项)

ALTER DATABASE [DATABASENAME] SET ONLINE;
 
DBCC CHECKDB('DATABASENAME') WITH NO_INFOMSGS;

如果上面的命令成功运行,没有任何警告,数据库就不需要做任何修复

 

方法2:重建日志文件(紧急模式)
如果错误日志显示是由于日志文件丢失而导致的,比如删除、重命名或损坏:
·将数据库置于紧急模式下
·分离数据库(将其offline)
·重新附加(将其online)

ALTER DATABASE [DATABASENAME] SET EMERGENCY;
 
ALTER DATABASE [DATABASENAME] set multi_user;
 
EXEC sp_detach_db '[DATABASENAME]';
 
EXEC sp_attach_single_file_db @DBName = '[DATABASENAME]', @physname = N'MDF_FILE_FULL_PATCH';

系统会自动移除损坏的日志并重建一个。

 

方法3:使用DBCC CHECKDB初始化(加上repair选项)
repair选项,一般不建议使用,只是作为实在没有办法时的选择。有多个repair级别,先从repair_rebuild级别开始,这样不会丢失数据:
·将数据库置于单用户模式
·执行DBCC CHECKDB(带上repair_rebuild选项)
·将数据库设置成online和多用户模式

ALTER DATABASE [DATABASENAME] SET SINGLE_USER;
 
DBCC CHECKDB (DATABASENAME,REPAIR_REBUILD) WITH NO_INFOMSGS,ALL_ERRORMSGS;
 
ALTER DATABASE [DATABASENAME] SET ONLINE;
 
ALTER DATABASE [DATABASENAME] SET MULTI_USER;

如果修复没有成功,再将级别设置成REPAIR_ALLOW_DATA_LOSS:顾名思义,这种级别会有数据丢失
·将数据库置于紧急模式
·执行DBCC CHECKDB(带上repair_allow_data_loss选项)
·将数据库设置成online和多用户模式

ALTER DATABASE [DATABASENAME] SET EMERGENCY;
 
ALTER DATABASE [DATABASENAME] SET SINGLE_USER;
 
DBCC CHECKDB (DATABASENAME,REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS,ALL_ERRORMSGS;
 
ALTER DATABASE [DATABASENAME] SET ONLINE;
 
ALTER DATABASE [DATABASENAME] SET MULTI_USER;