数据库报“可疑”的数据时候,我第一反应是解决骂娘。然后才想起该查日志。数据
那天凌晨两点,解决客户电话打过来,数据说财务系统连不上库。解决我远程一看,数据SQL Server里那个库的解决状态栏赫然写着“Suspect”。数据文件还在,数据日志文件也还在,解决但SQL Server就是数据拒绝启动它。典型的解决“可疑”状态。
多数人这时候会慌,数据直接去网上搜“数据库可疑修复”,解决然后下载一堆乱七八糟的数据工具。别急。先搞明白一件事:所谓“可疑”,其实是SQL Server在启动恢复过程中发现日志链断裂或数据页校验失败,主动把库标记为不可用,防止你读到坏数据。这是保护机制,不是判死刑。
第一步,把库设为紧急模式。在SSMS里执行:ALTER DATABASE [你的库名] SET EMERGENCY。这一步让库进入单用户只读状态,允许你查看数据但不允许写入。然后跑DBCC CHECKDB ([你的库名])。注意,这命令可能跑很久,别中途杀进程。它会告诉你损坏的严重程度,是页级小伤还是元数据大裂。
我那次遇到的情况,是磁盘坏道导致日志文件物理损坏。CHECKDB报错说“无法读取日志记录”。这时候单靠SQL Server自身恢复已经不可能,需要手动重建日志文件。做法是:先ALTER DATABASE [你的库名] SET OFFLINE,然后把那个损坏的.ldf文件改名备份,再ALTER DATABASE [你的库名] REBUILD LOG。系统会生成一个新的日志文件。这招对日志损坏特别管用,但前提是数据文件完整。
如果数据文件本身也坏了,事情就麻烦些。你得用DBCC CHECKDB ([你的库名], REPAIR_ALLOW_DATA_LOSS)。看名字就知道,这命令会丢数据。它能帮你把库恢复到可用状态,但丢失的数据通常是你最近写入、还没来得及备份的事务。执行前务必确认:你手头有最近的备份吗?如果没有,那REPAIR_ALLOW_DATA_LOSS是你最后的救命稻草,别犹豫,跑吧。跑完立刻做完整备份,然后赶紧把备份策略补上——这教训值好几万。
还有个偏方,针对那种“假可疑”。有时候库状态可疑,但日志文件其实没坏,只是SQL Server在恢复时被某些锁卡住了。先重启SQL Server服务,如果还不行,试试sp_resetstatus '你的库名'。这个存储过程能强制把状态重置为正常,但前提是你确定库本身没物理损坏。我见过有人用这招把真损坏的库强行拉起来,结果读到一半直接崩溃,数据彻底乱了。所以,这招只适合“疑似误报”的情况,用之前先跑CHECKDB验证。
最后说句实在话。修复可疑数据库,最核心的不是技术,是你有没有备份。有备份,一切好说,恢复点就行。没备份,你就是在跟磁盘上的残骸搏斗,赢了是运气,输了是常态。我那次折腾到天亮,总算把库拉起来了,但丢了当天下午三个小时的交易数据。客户没骂我,因为那三个小时的数据他们自己也拿不出记录。
事后我把那个库的日志备份间隔从每天一次改成每十五分钟一次。麻烦是麻烦点,但总比凌晨两点接电话强。