SQL Server数据库启动过程及用户数据库加载过程的疑难杂症
前言
本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的一些问题和解决方法,可点击查看,我们此篇主要介绍的是SQL Server启动过程中关于用户数据库加载的流程,并且根据加载过程中所遇到的一系列问题提供解决方案。
其实SQL Server作为微软的一款优秀RDBMS,它启动的过程中,本身所带的那些系统库发生问题的情况相对还是很少的,我们在平常使用中,出问题的大部分集中于我们自己建立的用户数据库。
而且,相对于侧重面而言,其实我们更关注的是我们自己建立的用户数据库,假如系统数据库出现问题,甚至实例出现问题,最坏的情况我们重搭环境,但是如果我们应用的用户数据库坏掉了,那可不是重搭环境就能解决的。这牵扯到公司利益问题,问题严重性不言而喻!
闲言少叙,我们速度进入本篇的正题。
上一篇我们介绍了SQL Server实例启动的过程,并且分析了其详细的过程,而在这一流程中,有一个步骤非常关键,就是加载恢复用户数据库的过程,我们来截取这段日志信息:
上面是一个正常启动各个用户库的流程,SQL Server会采用多线程的进行数据库启动,并且在这个过程中进行一致性校验,确保启动的数据库能够正常使用。
而这过程中会发生很多问题,在分析问题之前,我先要介绍SQL Server数据库的几个常见状态:
RECOVERING(恢复中):
这个状态表示数据在启动完成后,正在发生恢复,也就是上面日志中的 Recovery过程,和其它的关系型数据库一样,SQL Server对所有的数据库行为都是先写事务日志,然后在修改内存中的数据,然后通过后台的一个进程在适当的时候进行写入硬盘(Lazy write),所以在数据库运行过程中,磁盘中的数据并不是最新的,如果这个时候关闭了,在下一次启动过程中SQL Server就要根据事务日志中的记录,将磁盘中的旧的数据改写,改写过程为:
1、重做redo
2、回滚和撤销 undo/rollback
上面的目的就是为了保证数据库一致性。
如果上面的流程发生了问题,就会进去到下面这个状态:
RECOVERY PENDING(挂起还原):
这个过程就是将恢复数据的过程挂起,挂起的原因基本就是不能正常打开所用的数据库文件。这里先记住这个状态就行,我在后面的内容会再现这个问题,以及给出解决方案。
如果能找到文件或者能打开文件,但是文件有问题,机会出现下面这个状态:
SUSPECT(质疑):
这个状态,我相信很多用户如果在玩数据库久了的时候,会偶尔遇到,相对于其它状态,这个状态是出现最高的。
原因很简单:数据库文件坏掉了。
当经历了上面的这个几个状态都不出现问题,上面的这几个状态下,数据库都是不能使用的,会进入到下面这个状态:
ONLINE(在线):
这个状态应该是最期待的了,数据库在线,正常使用,默认都是正常的在线状态。
当然,除了上面几个数据库自己形成的数据库状态,在我们管理员处理数据库的时候也会更改状态,这里我们顺便提一下:
OFFLINE(离线):有在线状态就有离线状态,很简单,让数据库离线,用户不能使用
RESTORING(还原中):这个状态很简单,管理员正在还原该数据库,不解释
EMERGENCY(紧急):这个状态也是管理员用的,就是说明数据库有问题了,它正在尽量解决
以上几个状态中,发生在启动过程中,并且会发生问题就是上面的RECOVERY PENDING(挂起还原)、SUSPECT(质疑)、RECOVERING(恢复中):
我们依次来看:
RECOVERY PENDING(挂起还原):
出现这个状态通常的原因是数据库文件找不到,或者文件找到权限访问不到,我们来看该问题报错信息:
在数据库中存储方式中,分为主文件组和辅助文件组和日志文件,为了展示方便我们特意建立了个测试库,来重现该部分问题:
<1>主文件组问题
当不能访问主文件组文件的时候,也就是上面的CnblogsTestDB.mdf文件,会报如下错误:
我们先来看数据库:
在实例启动的过程,恰巧有一个库显示了上面我们提到的一个状态:RECOVERING(恢复中),我顺便把图给截图了,当然出现这个情况很正常,有时候刷新一下就正常,其它用户库没有显示是因为库太小,恢复时间太短,我们捕捉不到。
我们来看,上面我们建立的测试库CnblogsTestDB已经不能访问了,我们来看一下Error中的错误信息:
错误信息很明显,说这个该文件不能访问,并且确切的说出了这个为操作系统错误,那我们看操作系统的错误记录:
可以看到在Windows系统日志中也能看到该部分错误信息。
解决方案:
此问题的解决方法还是很简单的,一般主要是因为权限问题,只需要将数据库管理员账户组,提权到可读写权限就可以,然后重启服务:
上面的情况是找到数据库文件,但是不能打开数据库文件,当然还有可能是直接找不到数据库文件,系统会报出如下错误:
会给出17204错误,报找不到文件错误
解决方案:
a、如果能找到数据文件最好了,拷贝到错误制定的路径下既可以,然后重启实例
b、不能找到文件了,那就得只能删除该库,重新新建同名库,从备份文件中还原
一般上述问题发生在物理存储出现了故障,当然不排除某些软件操作,比如杀毒软件、还有人为误删等原因。如果没有备份,这可能是一个很大的遭难,基本可以确定的完全还原的可能性不高!所以记住:备份数据库的重要性!
<2>辅助文件组问题
上面的出现问题的文件为数据库的主文件组,当我们数据库在承载到一定数据量的情况下,我么采取多个辅助文件组来容纳数据,下面我们来看一下辅助文件组的问题:
同样的提示的辅助文件组不能正常打开,或者找不到相关的辅助文件组,遇到这样的问题我们怎么解决呢?
其实SQL Server数据库辅助文件存储的主要为数据库的数据内容信息,关于本库的一些架构信息是放在主(primary)文件组中,所以我们可以先这样
解决方案:
a、我们将打不开或者不能访问的数据库文件(辅助文件)设置成离线,然后先将能够正常的数据文件上线,确保除了损坏的那部分文件的其它库信息能正常访问,我们通过以下代码更改:
ALTER DATABASE CnblogsTestDB MODIFY FILE(NAME=CnblogsTestDB2,OFFLINE) GO ALTER DATABASE CnblogsTestDB set ONLINE GO
这样,我们刷新下数据库,既可以正常访问正确的数据信息:
当我们处于生产环境中,生产库不能正常启动的时候,此刻的火烧眉毛的时刻,采取上面的方法先确保一部分数据能正常访问也不失为一种缓议之计。
下面的步骤就是找到该辅助文件,并且确保有正常的权限访问,更重要的是找到的辅助文件不能是损坏的,然后拷贝至错误文件中给出的路径,然后重启实例,上线该库。
b、当然大部分情况下,我们找不到该文件,或者这个文件已经损坏,那就得采取第二种方案,通过备份还原,根据以往的经验,建议采取的措施是:
先将能访问的数据库做一次备份,然后通过文件组恢复的方式,恢复上面出问题的文件组。