본문 바로가기

MSSQL/T-SQL

손상된 페이지 복원


Database Page가 깨졌을 때의 복구 방법

 

Gravity DBA 이승연

 

오래 전에 와니군이 출장 중에 Table Page가 깨져 Select시에 에러가 나여 DBCC CHECKDB DBCC CHECKTABLE을 통하여 해당 문제를 해결한 적이 있다. 이 부분에 대하여 간략하게 정리하고자 한다.

 

먼저 해당 사용자 데이터베이스에 연결된 모든 것들을 끊고, 단일 사용자 모드로 바꾼다. WITH ROLLBACK AFTER 10 이라는 옵션은 아직 끝나지 않은 트랜잭션 처리가 있다면 10초 동안 기다렸다가 그래도 끝나지 않는다면 모든 트랜잭션을 Rollback하고 단일 사용자 모드로 바꾸라는 옵션이다. 그 후 DBCC CheckDB을 실행 시키면 된다.

 

ALTER DATABASE [데이터베이스] SET single_user WITH ROLLBACK AFTER 10;

 

DBCC CHECKDB('[사용자데이터베이스]')

 

l  Database에 대해 DBCC CHECKALLOC을 실행한다.

l  Database의 모든 Table view에 대하여 DBCC CHECKTABLE을 실행한다.

l  Databsae에 대해 DBCC CHECKCATALOC을 실행한다.

l  Database에 있는 모든 index view 에 대한 유효성을 검사한다.

l  Database에 있는 Service Broker 데이터의 유호성을 검사한다.

 

이는 DBCC CHECKDB의 명령어를 실행할 때, CHECKALLOC, CHECKTABLE, CHECKCATALOC등을 별도로 실행할 필요가 없다는 의미이다. 각각의 대한 자세한 내용은 생략하겠다. 다음은 CHECKDB와 같이 사용할 수 있는 복구 모델을 표기하였다.

 

DBCC CHECKDB('[사용자데이터베이스]', REPAIR_FAST)

DBCC CHECKDB('[사용자데이터베이스]', REPAIR_REBUILD)

DBCC CHECKDB('[사용자데이터베이스]', REPAIR_ALLOW_DATA_LOSS)

 

REPAIR_FAST

이 옵션에 대한 설명은 MSDN에 이렇게 표기가 되어있다.

(이전 버전과의 호환성을 위해서만 구문을 유지 관리합니다. 복구 작업은 수행되지 않습니다.)

개인적인 생각으론 DBMS을 업그레이드 했을 경우, 이전 버전과의 호환성 유지를 위해 실행하는 것 같습니다.

 

REPAIR_REBUILD

이 옵션은 CHECKDB 실행 중에 NonClustered Index Clustered Index가 재정렬 되는 것입니다.

 

REPAIR_REBUIDL

이 옵션은 보고된 모든 오류를 복구하는데, 주의할 점은 이 옵션을 사용하여 복구를 수행하면 해당 문제가 복구되지 않는다면, 삭제를 하게 됩니다. , 페이지가 사라질 수도 있다는 말입니다.


그리고 WITH 와 함께 사용할 수 있는 ALL_ERRORMSGS, NO_INFOMSGS, TABLOCK, ESTIMATEONLY, PHYSICAL_ONLY, DATA_PURITY 등이 있지만, 각각의 내용에 대해서는 직접 찾아보기 바란다.

 

MS-SQL 2000에서는 위와 같은 명령어로 어느 정도 해결이 가능할 것 같다. 하지만, 위와 같은 방법은 어디까지나 MS SQL 2000에서의 방법이고 MS SQL 2005부터는 Page별로 복원이 가능하기 때문에 해당 문제가 되는 Page만을 복원하여 해당 문제를 해결할 수가 있다. 그럼 MS SQL 2005에서 Page별로 복원 하는 방법을 알아보자.

 

MS-SQL 2005의 모든 버전에서 오프라인 복원이 사용 가능하지만, 온라인 복원은 특정 버전에서만 가용가능 하다.

SQL 버전

오프라인 페이지 복원

온라인 페이지 복원

SQL Server Express Edition

X

SQL Server Standard

X

SQL Server 2005 Workgroup

X

SQL Server Enterprise Edition

 

참고할 사항은 Enterprise Edition에서 온라인 페이지 복원을 수행하고 있을 경우, 온라인 복원 시도가 실패 하면 오프라인 복원으로 수행해야만 한다. 이는 메타데이터가 업데이트되는 도중에 그 메타데이터에 현재 수행중인 중요데이터가 있으면, 업데이트가 실패하기 때문에 데이터베이스를 오프라인으로 변경 후 시도해야만 하는 것이다.

 

또한, 페이지 복원에도 복원이 되지 않는 페이지들이 있다.

 

l  트랜잭션 로그

l  GAM(전역 할당 맵) 페이지

l  SGAM(공유 전역 할당 맵) 페이지

l  PFS(페이지 여유 공간) 페이지

l  모든 데이터의 부트 페이지 (파일의 0페이지)

l  1:9 페이지 (데이터베이스 부트 페이지)

l  전체 텍스트 카탈로그

 

그리고, 페이지 복원에 성공하려면 복원된 페이지가 데이터베이스와 동일한 상태로 복구되어야 한다. , 복원되는 페이지와 현재 데이터베이스의 페이지들의 정보가 같아야 하니 페이지 복원 후에 마지막 트랜잭션로그 복원을 해야 한다는 말이다.

 

페이지 복원 순서는 다음과 같다.

 

USE msdb

-- 복원하려는페이지ID 확인하기

SELECT * FROM msdb..suspect_pages

 

-- 확인된페이지복원하기

RESTORE DATABASE <database> PAGE='1:57, 1:202, 1:916, 1:1016'

FROM <file_backup_of_file_B> WITH NORECOVERY;

RESTORE LOG <database> FROM <log_backup> WITH NORECOVERY;

RESTORE LOG <database> FROM <log_backup> WITH RECOVERY;

 

일반적으로 페이지 복원은 대량 로그 복구에서 작동하지 않으며, 페이지 복원을 수행하는 최상의 방법은 데이터베이스를 전체 복구 모델로 변경한 후에, 로그 백업을 받고, 로그 백업이 성공하면 페이지 복원을 수행 할 수가 있다. 하지만, 로그 백업이 실패를 하기 된다면, REPAIR_ALLOW_DATA_LOSS 옵션을 사용하여 DBCC 명령을 실행해야 한다.

 

또한, 페이지 복원은 단순복구 모델에서는 되지 않으며, 읽기 전용 파일 그룹에서도 사용 할 수가 없으며, 현재 까지 로그 백업의 로그 체인이 끊어지지 않은 상태이어야만 페이지 복원에 성공할 수가 있다.