SQL 서버 데이터베이스 시작 프로세스 (사용자 데이터베이스로드 프로세스 어려운 경우)는 SQL Server 데이터베이스 시작 프로세스를 알고, 문제의 분석을 시작하고 해결 능력가되지 않습니다하지 않는

머리말

이 장에서 데이터 기사에 게시 보충, 우리가 도입 발생하는 문제와 해결 방법 SQL 서버 서비스 시작 프로세스의 수 , 클릭 가능한보기, 우리 Cipian는에서 SQL Server 시작 프로세스를 소개합니다 사용자 데이터베이스로드 프로세스가 로딩하는 과정에서 발생하는 문제의 범위를 기반으로 솔루션을 제공합니다.

사실, 훌륭한 RDBMS와 같은 마이크로 소프트의 경우,이 과정 자체가 해당 라이브러리는 SQL 서버 문제가 계속 우리가 일반적으로 사용, 상대적으로 드문 일이 가져온 시스템을 시작, 문제는 우리 자신의 설립에 큰 지역입니다 사용자 데이터베이스.

또한, 초점의 측면에서 표면에 대해, 사실, 우리는 데이터베이스 시스템 문제, 심지어 문제의 예를 들어, 우리는 최악의 환경을-가지고 다시 경우, 우리 자신의 사용자 데이터베이스 설정에 대한 더 많은 관심을하지만, 우리는 나쁜 사용자 데이터베이스를 적용하는 경우 밖으로, 그것은 다시 받아 환경 것이 해결 될 수 없습니다. 이 회사의 이익을 포함, 문제의 심각성은 자명하다!

속히, 시리아, 우리는 주제 Benpian에 속도.

 

SQL Server 인스턴스가 시작, 프로세스의 상세한 분석,이 과정에서 매우 중요한 단계는 사용자 데이터베이스 복구 프로세스를로드하는 것입니다 거기에 우리는, 우리는이 로그 정보를 가로 챌 수있는 과정을 소개 :

 

위의 각 사용자 데이터베이스에 대한 SQL Server는 과정에서 일관성을 위해 멀티 스레드 데이터베이스 시작을 사용하고 확인하는 일반적인 시작 프로세스이며, 데이터베이스가 정상적으로 사용할 수 있습니다 시작해야합니다.

그리고이 과정은 많은 문제가 문제의 분석을하기 전에 발생합니다, 나는 몇 가지 일반적인 상태 SQL Server 데이터베이스를 도입해야한다 :

 (복구) 복구 :

이 상태는 시작 후 데이터를 다른 관계형 데이터베이스처럼 모든 행동 SQL Server 데이터베이스 메모리를 수정 한 후 트랜잭션 로그를 작성하는 것입니다, 완료 로그 복구 프로세스를 초과하는 일이 회복되고 있음을 의미 이 시간이 종료하면 데이터, 다음 백그라운드 프로세스에 의해 적절한 시간에 디스크 (게으른 쓰기)에 기록되므로 데이터베이스 작업의 과정, 디스크의 데이터가 최신 아니라, 다음에 당신은 SQL 서버의 프로세스를 시작 트랜잭션 로그, 이전 디스크 데이터를 재 작성하는 데 필요한 기록에 따르면, 프로세스를 재 작성 :

1 다시 재실행

2, 롤백 및 실행 취소 / 롤백을 실행 취소

위의 목적은 데이터베이스의 일관성을 보장하는 것입니다.

문제는 위의 과정을 발생하는 경우, 그것은 다음과 같은 상태로 이동합니다 :

복구 PENDING (보류 감소) :

이 과정은 제대로 사용되는 데이터베이스 파일을 열 수있는 기본적인 이유 보류 일시 중단 된 데이터를 복구하는 과정입니다. 여기에 나는이 문제의 다시, 주어진 솔루션의 내용을 재현, 라인에이 상태를 기억합니다.

파일을 찾을 수 있습니다하거나 파일을 열 수 있지만 경우 문제의 파일은, 기회는 다음과 같은 상태를 표시합니다 :

SUSPECT (질문) :

이 상태는,이 상태가 가장 높은의 출현이다, 많은 데이터베이스 사용자가 오랜 시간을 재생하는 경우, 가끔 다른 국가에 비해 발생 있다고 생각합니다.

이유는 간단하다 : 데이터베이스 파일이 손상되었습니다.

여러 국가 이상이 위의 상태에서, 데이터베이스가 사용하지 않을 때 경험하지 문제는 다음과 같은 상태를 입력 :

ONLINE (온라인) :

상태가 가장 기대하고, 온라인 데이터베이스해야 정상 사용, 기본은 정상적인 온라인 상태입니다.

 

물론, 위의 여러 데이터베이스 자체 데이터베이스의 국가 형성뿐만 아니라, 우리가 상태를 변경합니다 데이터베이스 관리자를 처리 할 때 어디까지 부수적 :

오프라인 (오프라인) : 데이터베이스가 오프라인 상태입니다, 그래서 당신은 사용할 수 없습니다, 아주 간단한 온라인 오프라인으로있다가

(복원) 포인트 : 이 상태는 매우 간단하여 데이터베이스 관리자를 복원하는 것입니다, 설명하지 않습니다

응급 (비상) : 이 상태는, 사용하는 관리자입니다 데이터베이스에 문제가 있음을 나타냅니다, 우리는 그것이 해결하려고

 

몇 가지 더 주보다 시작하는 동안 발생하고, (복구)이 일어날 복구, (질문), (출원 감소) 보류 의심 문제는 복구 이상 :

우리는 볼 수 차례 :

복구 PENDING (보류 감소) :

이 상태는 일반적으로 우리가 문제 오류 메시지를 보면, 데이터베이스 파일을 찾을 수 없기 때문에 발생하거나 파일을 찾을 수에 액세스 할 수 없습니다 :

데이터베이스에 저장, 그룹이 주 파일과 보조 파일로 나누어 파일 그룹을 기록, 우리는 의도적으로 문제의 일부를 재현하기 위해, 테스트 라이브러리 디스플레이의 설립을 용이하게하기 위해 :

 

 

<1>은 기본 파일에 기

파일이 CnblogsTestDB.mdf 파일 위에 파일의 주요 그룹에 액세스 할 수없는 경우 다음과 같은 오류가보고 될 것입니다 :

의 데이터베이스를 살펴 보자 :

프로세스 인스턴스가 시작, 우리는 위에서 언급 한 상태를 보여줍니다 라이브러리를 가지고 발생합니다, 나는 물론, 맵의 스크린 샷을 복구 (복구) 줄 수도, 이러한 상황의 출현은 때때로 일반 다른 사용자에게 새로 고침, 정상입니다 표시되지 않습니다 라이브러리가 너무 작은 도서관 때문에 복구 시간은 우리가 잡을 수없는, 너무 짧습니다.

우리는 우리가 오류 메시지 오류에서 보면, 테스트 라이브러리 CnblogsTestDB이 방문하지 않은 이상 우리가 설립 한 찾습니다

물론 파일에 액세스 할 수 없으며, 정확한이 오류는 우리가 운영 체제를 보면, 운영 체제 오류로 기록됩니다 발언 없다는 오류 메시지 :

Windows 시스템 로그에 볼 수있는 오류 메시지의이 부분에서 볼 수 있습니다.

해결 방법 :

이 문제의 해결책은, 데이터베이스 관리자 계정을 설정 읽고에 쓰기 권한을, 다음 서비스를 다시 시작 할 수있는 권리를 제공하기 때문에 주로 일반적으로 인권 문제로, 매우 간단합니다 :

 

위의 상황은 데이터베이스 파일을 찾을 수 있지만 찾을 수 없습니다 직접 데이터베이스 파일을 할 수있다, 물론, 데이터베이스 파일을 열 수 없습니다, 다음과 같은 오류를보고 할 시스템 :

17204 오류 보고서가 오류를 발견 줄 것이다

해결 방법 :

는 최상의 데이터 파일을 찾을 수 있다면, 오류 경로의 사본을 설립 한 후 인스턴스를 다시 시작 할 수있다

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

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

 

----------------------------------------------------------霸气的分割线-----------------------------------------------------------------------

在经历了上面的文件级别错误后,在数据库启动的过程,还经常出现的是数据页级别的错误,相对于上面的文件错误级别,在数据页中造成的错误粒度更小,并且基本不会反映到数据库级别,也就是说在出现数据页级别的错误时候,该数据时可以正常访问的,只是在访问有错误的数据页的时候才会报错,在我们遇到这种错误的时候该如何解决呢?

下面我们依次来分析,首先我们来制作一个经典的824错误,以下部分内容牵扯到数据库部分基础,限于篇幅,我们不做详细介绍:

<1>首先我们在我们的测试库中新建一个表,我们将该表新建成一行为一个数据页的方式,也就是说一行数据库在数据库中就能承载一个数据页

复制代码
USE CnblogsTestDB
GO
CREATE TABLE [dbo].[TestPage]
(
    [a] [int] NULL,
    [b] [nvarchar](3900) NULL
) ON [PRIMARY]
复制代码

脚本很简单,一张表,两列,一列int类型,一列nvarchar(3900),一行数据的存储空间为:3900*2(nvarchar(3900))字节+4(int)+96字节(页头)+36字节(行偏移)=7932字节,我们知道一个数据页存储的信息为8K=8192字节,包括其它消耗所以该表一行数据如果填充完,一行数据将近乎占据一个数据页。

我们来添加三行数据,然后查看页信息:

复制代码
--插入三条数据
insert [TestPage]
values(1,REPLICATE('A',3900))
insert [TestPage]
values(2,REPLICATE('B',3900))
insert [TestPage]
values(3,REPLICATE('C',3900))
go
--查看页信息
dbcc  traceon(3604)
--查看库中页集合
dbcc extentinfo(CnblogsTestDB,[TestPage])
复制代码

 

 可以看到,该表中现在有三个数据页,我们来看看数据页应该也是近乎沾满的。

 

 上图显示了,通过扫描表信息,共含有3个数据页,每个数据页中的数据量存储占比到了96.55%,也就是说基本上是填充满了。

 当然,我们还可以通过DBCC PAGE命令,来查看每个页中的具体内容,我们简单的看一个页面编号为90的数据页:

通过上面的命令可以看到,该数据页中存储的为表中的第一行的数据,并且在数据库存储文件中是以十六进制方式编码存储。

当然,如果感觉此方式不直观,可以利用一个小工具进行数据页的查看,这里我推荐使用Internal Views(此工具在桦仔的博文中有详细介绍),可更直观的展示数据存储页信息:

这里我们可以点击我上面上面查看的第一行的数据内容页进行查看

 

经过上面的分析步骤,其实我的目的是想重现在SQL Server启动过程中,或者在线上的数据库经常遇到的经典错误824错误

上述过程是原理篇,因为我们必须知道数据存储的底层原理,才能理解好这个错误的原因,以及找到正确的处理方法。

 

下一步,我们来重现这个错误的原因,我们知道在我新建的测试表中含有两个字段:a和b,并且a为int类型、b为nvarchar类型

然后我们介绍了底层的存储机制,我现在将第一列a字段的整形数据内容存储改成字符串类型,依次来损坏掉该数据页内容

我先将服务停掉,然后用文件编辑工具,修改此数据页内容,该数据页内容为十六进制内容,当然在我搞坏这部分数据页之前我先做一个完整备份

 

然后修改该数据页信息,这里我使用UltraEdit文本编辑工具,打开文件,找到该数据页内容

我们将上面的源数据更该一下,来把这个数据页损坏掉

 我们保存,然后重新启动该数据库看看

 这就是我们平常比较常见的824错误的过程,而此过程有可能是磁盘坏道造成,或者误修改文件等诸多原因,但是此问题还是比较常见的

当然,这种数据页面的损坏可能造成的影响不是库级别的,也就说不会造成数据库不能访问,其它表是能正常访问的,但是只是在操作此损坏的数据页的时候才会报错,但有时候这几个数据页的损坏对业务产生的影响有可能就是致命的,所以我们要解决掉。

郑重提示:上面过程也可以正确的更改数据页中的数据,但是如果没有确切的把握,基本上能把数据库搞瘫痪掉,我是为了重现问题才修改底层元数据,所以在自己的生产库中千万不要乱搞!

在数据库启动的过程中,会发生一致性校验,所以该错误应该会记录到Error的错误日志文件中,我们来看:

windows平台下的错误日志:

当然,在启动的过程中该问题有可能发生很多,比如磁盘坏道等原因,一系列的数据页可能就没法访问了。所以SQL Server会将这些损坏的页面记录到msdb系统库中,这我们在这个库中查找到损坏的页面集合:

至此,我们已经重现了经典的824错误,那我们该如何解决此问题呢? 

解决方法:

a、如果此问题出现的页面为数据承载页,也就说该页存储的为内容数据或者为聚集索引的叶子节点数据,并且存在镜像,版本在SQL Server2005以上,那么这个错误基本可以忽略,SQL Server能够自动帮你修复此错误。

b、如果此问题出现在没有镜像的环境中,那就要区分是损坏页面是否为聚集索引叶子节点数据,如果是,那就简单了,直接重建索引就好了,如果不是,那此种方案还是不能解决,判断方法如下:

利用DBCC PAGE命令查看当前数据页内容,根据ObjectId跟踪该页位于哪个对象上,Metdata:IndexID的值判断是否为索引树中的节点值,如果大于0则表示为索引值,此时,重建该索引既可以。比如:

我们根据该页的ObjectID,从数据库中查找该页所属对象。

 c、如果上述方案都不能满足,那只有采取此种方案,我们可以利用数据库备份进行还原,当然为了最大限度的避免数据库离线,我们最好采取数据页还原的方式,此种方式最为简单,还原速度也最快,能够最大限度的缩短数据库离线时间,并且保证数据完整性。

这里提示下:在SQL Server2012版本一下,SSMS不提供图像化数据页还原方式,在SQL Sever以后的版本中,有图像化界面操作。

所以,我们只能通过如下脚本进行还原:

RESTORE DATABASE CnblogsTestDB
PAGE='1:90'
FROM DISK = N'F:\SQLTest\CnlogsTestDB.bak'
WITH NORECOVERY

当然有事务日志、更新备份的,需要依次恢复这过程的所有的备份,不要忘记备份尾部日志。

但是此方法也有局限性:

如果损坏的数据页为

  1、分配页:GAM、SGAM和PFS页

  2、所有数据文件的启动页

如果发生损坏的是以上两种,则无法通过该备份恢复页方式进行恢复。如果这种情况下,建议考虑找合适的时间段进行全库的恢复操作。(推荐)

d、上述情况是在存在有备份的情况下,如果没有数据库备份,那我们只能选择最后的一招了,那就是DBCC CHECKDB命令,同样和上面一样,此种方式可能会造成数据丢失,所以不建议采用,如果能容忍数据丢失,采用的过程参照文中的上半部分。(不推荐)

 

至此,我们已经完成了一个SQL Server启动过程或者平常最经常遇到的一个经典错误824错误,我们来总结下:

824错误原因:大部分是由于磁盘存储导致的数据页损坏,导致的SQL Server在读取的时候发生了错误。

导致错误场景:磁盘坏道、突然断电等情况下经常会出现此错误。

 

----------------------------------------------------------霸气的分割线-----------------------------------------------------------------------

和824错误相关的还有一种是823错误,我们来介绍下该错误信息
由于场景所限,我就不重现该错误了,在这里我详细的介绍下这两种错误的原因和原理,就可以了,如果遇到了,解决的方式基本都是一致的,可参照上面的824错误解决方法。

SQL Server在每次写入页面的时候,会根据页面里的数据算出一个校验值,一同存储到页面中去。当下次读取页面的时候,再根据这次读到的页面数据,算出一个新的校验值。如果写入和读出的数据一模一样,那么两个校验值就是相等的。如果两个校验值不相等,就意味着上次SQL Server写入的数据和这次读取出来的一定不同,现在读取出来的数据就有问题了。

823错误就代表着SQL Server在向操作系统申请某个页面读写的时候遇到了Windows读取或写入请求失败。所以该问题的原因大部分是源自于操作系统层面,更确切的说是物理文件损坏而导致此错误,比如设备驱动程序导致等。

824错误则是在读取数据页面时候,发现数据页面有问题,比如读取出来的校验值不对等。 

当上面描述的823和824错误出现大面积的时候,或者直接部分数据文件完全坏掉的情况下,在SQL Server启动过程中就会出现数据库SUSPECT“质疑”状态。

经过我的多次数据页的破坏和摧残,我已经顺利的将我们的这个测试库给搞成了质疑状态,我们来看SUSPECT(质疑)的状态库:

这里我直接DBCC CHECKDB命令尝试着恢复下看看

 

所以到此,我们要做的就是避免上述错误的发生。如果在生产库中发生了我上面的情况,然后没有数据库备份,那么剩下来你要做的事情:我估计就是准备简历了..... 

结语

本篇文章到此结束了......文章主要还是分析SQL Server启动过程中,加载用户数据库的时候,所遇到的一系列问题,文中部分内容需要有一定数据库基础知识才能读懂,篇幅有限,我们没有做深入的讲解分析,比如上面的几个重要的命令DBCC PAGE....DBCC CHECKDB..等等,随便一个都能写出一系列的内容,我们侧重的还是问题的解决,和问题原因分析,后续文章中会介绍这一系列的命令作用,以及正确的使用技巧。

....此篇耗时四天完成....文中部分数据库错误都是我耗费精力一步一步调整出来,目的是真实的展现错误明细,其实问题解决容易,问题重现的过程复杂。

如果经常使用SQL Server,其实这些问题都是我们会经常遇到的,所以我们要记住相应的解决方案,做的有备无患!

当然个人能力有限,部分不当之处,还望指出不吝赐教。

文章最后给出本篇的关联篇:

你所不知道的SQL Server数据库启动过程,以及启动不起来的各种问题的分析及解决技巧

 

转:https://www.cnblogs.com/zhijianliutang/p/4100103.html

추천

출처www.cnblogs.com/VicLiu/p/11577028.html