事情的起因
昨天系统管理员告诉我我们一个内部应用数据库所在的磁盘空间不足了我注意到数据库事件日志文件XXX_Dataldf文件已经增长到了GB于是我决意缩小这个日志文件经过收缩数据库等操作未果后我犯了一个自进入行业以来的最大最愚蠢的错误:竟然误删除了这个日志文件!后来我看到所有论及数据库恢复的文章上都说道:无论如何都要保证数据库日志文件存在它至关重要甚至微软甚至有一篇KB文章讲如何只靠日志文件恢复数据库的我真是不知道我那时候是怎么想的?!
这下子坏了!这个数据库连不上了企业管理器在它的旁边写着(置疑)而且最要命的这个数据库从来没有备份了我唯一找得到的是迁移半年前的另外一个数据库服务器应用倒是能用了但是少了许多记录表和存储过程真希望这只是一场噩梦!
数据库日志文件的误删或别的原因引起数据库日志的损坏
方法一
新建一个同名的数据库
再停掉sql server(注意不要分离数据库)
用原数据库的数据文件覆盖掉这个新建的数据库
再重启sql server
此时打开企业管理器时会出现置疑先不管执行下面的语句(注意修改其中的数据库名)
完成后一般就可以访问数据库中的数据了这时数据库本身一般还要问题解决办法是利用
数据库的脚本创建一个新的数据库并将数据导进去就行了
USE MASTER
GO
SP_CONFIGURE ALLOW UPDATES RECONFIGURE WITH OVERRIDE
GO
UPDATE SYSDATABASES SET STATUS = WHERE NAME=置疑的数据库名
Go
sp_dboption 置疑的数据库名 single user true
Go
DBCC CHECKDB(置疑的数据库名)
Go
update sysdatabases set status = where name=置疑的数据库名
Go
sp_configure allow updates reconfigure with override
Go
sp_dboption 置疑的数据库名 single user false
Go
方法二
事情的起因
昨天系统管理员告诉我我们一个内部应用数据库所在的磁盘空间不足了我注意到数据库事件日志文件XXX_Dataldf文件已经增长到了GB于是我决意缩小这个日志文件经过收缩数据库等操作未果后我犯了一个自进入行业以来的最大最愚蠢的错误:竟然误删除了这个日志文件!后来我看到所有论及数据库恢复的文章上都说道:无论如何都要保证数据库日志文件存在它至关重要甚至微软甚至有一篇KB文章讲如何只靠日志文件恢复数据库的我真是不知道我那时候是怎么想的?!
这下子坏了!这个数据库连不上了企业管理器在它的旁边写着(置疑)而且最要命的这个数据库从来没有备份了我唯一找得到的是迁移半年前的另外一个数据库服务器应用倒是能用了但是少了许多记录表和存储过程真希望这只是一场噩梦!
没有效果的恢复步骤
附加数据库
_Rambo讲过被删除日志文件中不存在活动日志时可以这么做来恢复:
分离被置疑的数据库可以使用sp_detach_db
附加数据库可以使用sp_attach_single_file_db
但是很遗憾执行之后SQL Server质疑数据文件和日志文件不符所以无法附加数据库数据文件
DTS数据导出
不行无法读取XXX数据库DTS Wizard报告说初始化上下文发生错误
紧急模式
怡红公子讲过没有日志用于恢复时可以这么做:
把数据库设置为emergency mode
重新建立一个log文件
把SQL Server 重新启动一下
把应用数据库设置成单用户模式
做DBCC CHECKDB
如果没有什么大问题就可以把数据库状态改回去了记得别忘了把系统表的修改选项关掉
我实践了一下把应用数据库的数据文件移走重新建立一个同名的数据库XXX然后停掉SQL服务把原来的数据文件再覆盖回来之后按照怡红公子的步骤走
但是也很遗憾除了第步之外其他步骤执行非常成功可惜重启SQL Server之后这个应用数据库仍然是置疑!
不过让我欣慰的是这么做之后倒是能够Select数据了让我大出一口气只不过组件使用数据库时报告说:发生错误:未能在数据库 XXX 中运行 BEGIN TRANSACTION因为该数据库处于回避恢复模式
最终成功恢复的全部步骤
设置数据库为紧急模式
停掉SQL Server服务;
把应用数据库的数据文件XXX_Datamdf移走;
重新建立一个同名的数据库XXX;
停掉SQL服务;
把原来的数据文件再覆盖回来;
运行以下语句把该数据库设置为紧急模式;
运行Use Master
Go
sp_configure allow updates
reconfigure with override
Go
执行结果:
DBCC 执行完毕如果 DBCC 输出了错误信息请与系统管理员联系
已将配置选项 allow updates 从 改为 请运行 RECONFIGURE 语句以安装
接着运行update sysdatabases set status = where name = XXX
执行结果:
(所影响的行数为 行)
重启SQL Server服务;
运行以下语句把应用数据库设置为Single User模式;
运行sp_dboption XXX single user true
执行结果:
命令已成功完成
ü 做DBCC CHECKDB;
运行DBCC CHECKDB(XXX)
执行结果:
XXX 的 DBCC 结果
sysobjects 的 DBCC 结果
对象 sysobjects 有 行这些行位于 页中
sysindexes 的 DBCC 结果
对象 sysindexes 有 行这些行位于 页中
syscolumns 的 DBCC 结果
………
ü 运行以下语句把系统表的修改选项关掉;
运行sp_resetstatus XXX
go
sp_configure allow updates
reconfigure with override
Go
执行结果:
在 sysdatabases 中更新数据库 XXX 的条目之前模式 = 状态 = (状态 suspect_bit = )
没有更新 sysdatabases 中的任何行因为已正确地重置了模式和状态没有错误未进行任何更改
DBCC 执行完毕如果 DBCC 输出了错误信息请与系统管理员联系
已将配置选项 allow updates 从 改为 请运行 RECONFIGURE 语句以安装
重新建立另外一个数据库XXXLost;
DTS导出向导
运行DTS导出向导;
复制源选择EmergencyMode的数据库XXX导入到XXXLost;
选择在SQL Server数据库之间复制对象和数据试了多次好像不行只是复制过来了所有表结构但是没有数据也没有视图和存储过程而且DTS向导最后报告复制失败;
所以最后选择从源数据库复制表和视图但是后来发现这样总是只能复制一部分表记录;
于是选择用一条查询指定要传输的数据缺哪个表记录就导哪个;
视图和存储过程是执行SQL语句添加的
维护Sql Server中表的索引
在使用和创建数据库索引中经常会碰到一些问题在这里可以采用一些另类的方法解决…
第一步:查看是否需要维护查看扫描密度/Scan Density是否为%
declare @table_id int
set @table_id=object_id(表名)
dbcc showcontig(@table_id)
第二步:重构表索引
dbcc dbreindex(表名pk_索引名)
重做第一步如发现扫描密度/Scan Density还是小于%则重构表的所有索引
并不一定能达%
dbcc dbreindex(表名)