帮助中心 >  技术知识库 >  数据库 >  相关技术支持 >  SQL Server数据库启动过程(用户数据库加载过程常见问题)第二部分

SQL Server数据库启动过程(用户数据库加载过程常见问题)第二部分

2016-10-07 08:19:47 4266

<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、当然大部分情况下,我们找不到该文件,或者这个文件已经损坏,那就得采取第二种方案,通过备份还原,根据以往的经验,建议采取的措施是:

先将能访问的数据库做一次备份,然后通过文件组恢复的方式,恢复上面出问题的文件组。

 

<3>日志文件组

其实从市面上的所有数据库而言,其本身所有的机制都是通过先写日志,然后通过一个进程后写入(lazy write)方式写入到磁盘,这种方式是为了避免IO的阻塞,因为我们都知道磁盘IO这个问题一直是所有文件读写的最大瓶颈。

所以,日志文件是数据库不可分割的一部分。当数据库在启动的过程,会通过日志中的记录做一次数据的一致性校验,文章的开端有介绍。

所以说,如果日志文件不能访问,或者说出问题,那我们的SQL Server数据库出现什么问题呢?

我们先来看数据库模式为简单(SIMPLE)模式的,我将咱们的测试库设置成简单模式:

USE CnblogsTestDB
GO
ALTER DATABASE [CnblogsTestDB] SET RECOVERY SIMPLE WITH NO_WAIT
GO

然后我们停掉实例,然后删除掉该库的日志文件,然后重新启动

可以看到处于简单模式下,如果日志文件出现错误,在启动的过程是不会发生任何问题的,这里的原因我们在启动Error日志文件中能找到答案:

经过上面的日志分析,我们可以看到,当数据库处于简单模式下,数据库在启动的过程中,如果发现任何与日志相关的信息,则会重新创建一份日志文件,保证数据库的正常访问。

如果这样那我们数据库的完整性怎么保证呢,是这样,如果数据库处于简单模式,在我们数据库关闭的时候,系统会先将该提交的所有事务都写入到磁盘中去,所有该回滚的就撤销。

上面能正常创建数据库日志文件的前提条件有两条:1、数据库为简单模式;2、数据库正常关闭,保证事务都已正常写入磁盘

 

下面我们在看?如果恢复模式为“完整”模式下的,数据库上次没有正常的情况,SQL Server数据库是如何处理的,

我们先将数据库改成完整恢复模式,停掉实例,然后删除日志,然后启动

然后我们启动,可以看到这个时候,数据库不能正常访问的,该错误的Error的日志信息为:

windows平台下也为我们记录了该错误的日志信息:

其实出现上面的错误,很正常,因为有些数据库的事务性操作已经记录到事务日志中,还未写入磁盘数据页中,这时候发生了宕机,或者非正常关闭,这个对SQL Server数据库是能应付的,但是,而在启动的过程找不到相关的事务日志尽心回滚和写入操作,所以该库的数据时非一致性的,所以SQL Server是不让我们使用该库,出现此种错误,我们的解决方式有如下几种:

解决方案:

a、如果有备份,最好最快的方式就是恢复数据库备份或者找到了该日志文件拷贝到错误路径下(推荐

b、如果没有备份,我们只能通过使用CHECKDB命令修复数据库(不推荐

上述解决方案中CHECKDB命令,是一种万不得已的方式?而且,我可以明确的告诉你这命令使用的时候会可能造成数据丢失,并且在大数据库中,运行周期很长!

当然在万不得已的情况下,我们还的采取,过程如下:

我们先将数据库设置成EMERGENCY(紧急)模式,并且为单用户(SINGLE_USER)模式

 

USE CnblogsTestDB
GO
ALTER DATABASE CnblogsTestDB SET EMERGENCY
GO
ALTER DATABASE CnblogsTestDB SET SINGLE_USER
GO

 

经过我们上面的设置,将库设置成了“紧急”模式,并且只为单用户方式访问,便于我们进行数据?复

然后我们执行CHECKDB命令,进行数据库的修复

DBCC CHECKDB(CnblogsTestDB,REPAIR_ALLOW_DATA_LOSS)
GO

经过该命令的修复,数据库会为系统新建一个日志,但是不能保证事务的一致性,也就是说会因此而丢失数据,所以非常不推荐的一种方式!

并且,在这过程中,如果是大数据库的话,该修复过程会很漫长,当然我不能给出一个漫长参考值,因为这过程还有会出现其它的错误需要修复。

所以酌情考量。

当然,在恢复完成之后,不要忘记将数据库改回多用户模式

USE [master]
GO
ALTER DATABASE [CnblogsTestDB] SET  MULTI_USER WITH ROLLBACK IMMEDIATE
GO

至此,这个有问题的库就能够正常访问了。


提交成功!非常感谢您的反馈,我们会继续努力做到更好!

这条文档是否有帮助解决问题?

非常抱歉未能帮助到您。为了给您提供更好的服务,我们很需要您进一步的反馈信息:

在文档使用中是否遇到以下问题: