![[MsSQL][장애 조치] 크랙 DATABASE 복구 1 - 주의대상 데이터베이스 복구 시도](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTCLCe%2FbtsMetaRYpa%2FagMOpOj6VrRl1wHjKEPCg0%2Fimg.png)

장애 조치
사내 데이터 배치용으로 사용 중이던 MsSQL의 Database 중 하나의 Database의 장애가 발생하여 주의대상 상태가 되는 일이 발생하였다.
주의대상이 된 데이터베이스에는 접근도 할 수 없고 어떠한 작업도 불가능한 상태가 되었으며, 주의대상에서 자동으로 복구 중 무언가 문제가 발생하여, DB STARTUP 상태로 아무런 변경이 없었다.
select command, percent_complete, start_time
from SYS.DM_EXEC_REQUESTS
where command in ('db startup', 'restore database', 'recovery');
위의 Query를 통해 DB STARTUP 트랜잭션이 어느정도 진행되었는지 확인 할 수 있다 하여 확인하였으나, 몇 십분 ~ 시간 동안 변화가 없었다.
보통의 주의대상을 풀 수 있는 방법의 쿼리들을 시도해 보았지만 위에 DB STARTUP 상태와 맞물려 그런지 아무런 동작을 하지않았다.
결국 해당 데이터베이스를 포기하고, 백업 파일을 통해 새로운 데이터베이스를 생성하여 RENAME을 하고자 결정하였고,
RENAME을 하기위해서는 기존의 데이터베이스의 연결을 어떻게든 끊어야 하는 상황이 발생하였다.
DATABASE DROP은 가능할거라 생각했지만, 추후 분석을 위해 어떻게든 데이터파일을 남기고 싶었다.
어떻게든 연결을 끊고 새로 복구한 데이터베이스를 연결하는데 성공하였으나, 복구 된 데이터베이스에 대용량 테이블 (약 24억 row)의 데이터가 이미 깨져있는 것을 확인하였고, 깨져있는 데이터에 대한 조치 작업을 추가로 하였다.
먼저 해당 데이터베이스를 어떻게 주의대상 상태를 풀 수 있는지 노력해본 것에 대해 간략히 남겨보고,
복구한 데이터베이스의 대용량 테이블에 크랙이 발생되어 있던 것을 어떻게 조치하였는지 남겨보도록 하겠다.
주의대상 데이터베이스
사실 주의대상 데이터베이스를 풀어내는 이야기는 크게 할 말이 없다.
우선 해당 데이터베이스의 오너가 아니여서 직접적으로 명령어를 날리기 부담스러웠기에 대부분의 작업에 있어서 의견 공유만 하였다.
어떠한 명령어를 사용하였고 실패하였는지, 무엇을 목표로 하였는지만 간략하게만 내용을 남기도록 하겠다.
주의대상 해제하는 일반적인 쿼리
해당 데이터베이스가 간혹 주의대상 상태가 되는 문제가 있었다고 한다.
항상 이 쿼리들을 통해 해제 하였다고 하는데, 직접 사용해 본 쿼리는 아니다.
-- db 상태 확인
select databasepropertyex('[DB 명]', 'status')
-- db status reset
exec sp_resetstatus '[DB 명]'
-- 응급 상태로 전환
alter database [DB 명] set emergency
--dbcc 수행
dbcc checkdb('[DB 명]')
--싱글 유저로 바꿔서 접근 제한
alter database [DB 명] set single_user with rollback immediate
-- db repair
dbcc checkdb('[DB 명]', 옵션)
-- repair 옵션
--1) repair_fast : 시간이 많이 소요되지않고, 데이터의 손실이 없는 사소한 오류를 수정 (클러스터되지 않은 인덱스 복구 가능)
--2) repair_rebuild : repair_fast이 하는 모든 작업, 인덱스 재생성과 같이 시간이 소요되는 작업이 복구 과정에서 진행됨. 역시 데이터의 손실 위험은 없다.
--3) repair_allow_data_loss : repair_rebuild이 하는 모든 작업, 할당 오류, 구조적 행 오류나 페이지 오류, 손상된 텍스트 개체 삭제를 수정하기 위한 행과 페이징의 할당 및 할당 취소 등의 작업이 행해진다.
-- 멀티 유저로 바꾸기
alter database [DB 명] set multi_user
하지만 요번에는 데이터베이스의 상태가 DB STARTUP 상태여서 그런가? 해당 명령어들을 하나도 실행 할 수 없는 상태가 되었다고 한다.
해당 데이터베이스를 Offline 상태로 변경하려고 쿼리를 시도하였으나 해당 쿼리도 동작하지 않았다.
ALTER DATABASE [DB 명] SET OFFLINE WITH ROLLBACK IMMEDIATE
메시지 5011, 수준 14, 상태 7, 줄 5
사용자에게 데이터베이스 'DB 명'을(를) 변경할 권한이 없거나, 데이터베이스가 없거나, 데이터베이스가 액세스 검사를 허용하지 않는 상태입니다.
메시지 5069, 수준 16, 상태 1, 줄 5
ALTER DATABASE 문이 실패했습니다.
마지막 방법으로 SQL Server 서비스를 재기동해보기로 결정하여 재기동을 하게되었다.
우선 팀장님은 해당 결정을 하기에 혹시나 데이터베이스가 다시 올라오지 않을 경우 어떻게 해야하지 많이 걱정하셨으며,
그럴 경우 SQL Server 재설치 후 Attach를 통해 데이터 파일을 재연결하자는 결론에 도달하였다.
우선 어떻게든 저 문제가 있는 데이터베이스를 처리해야 하기에
일반적인 SQL Server 서비스 종료를 위해 구성관리자에서 해당 서비스를 중지 시켰으나 서비스가 종료되지 않아서 결국 강제 종료 명령어를 통해 종료하였다.
SHUTDOWN WITH NOWAIT
재기동 되어도 주의대상 상태는 그대로 였으며, 이렇게 데이터베이스의 상태변경은 실패하였다.
결국 해당 데이터베이스를 포기하기로 결정하였다.
해당 데이터베이스의 백업파일로 데이터베이스_NEW로 새롭게 복구하였다.
데이터베이스 연결 끊기
모든 배치 및 쿼리들에 문제가 되는 데이터베이스 명이 들어가있기에...
해당 데이터베이스를 drop하든 어떻게든 연결을 끊어 이름을 반환해야 했었다.
그래야 데이터베이스_NEW로 복구한 것을 RENAME하여 사용 할 수 있으니
하지만 또 욕심으로는 해당 데이터베이스의 데이터 파일을 보관하여 추후 분석하고 싶었기에 DROP은 최후의 수단으로 잠시 보류하고 어떻게든 데이터베이스 연결을 끊을 수 있도록 하였다.
데이터베이스의 상태가 어떤 방법으로도 바뀌지 않았기에 편법을 사용하여 데이터베이스 연결을 끊었다.
1. SQL Server 를 중지시킨다.
2. 문제가 되는 데이터베이스의 MDF 파일의 이름을 변경한다.
3. SQL Server 를 재기동한다.
4. 해당 데이터베이스가 주의대상 -> 복구 보류로 바뀌었다.
5. 해당 데이터베이스를 OFFLINE 한다.
6. 해당 데이터베이스를 DETACH 한다.
위의 순서를 통해 데이터베이스의 연결을 끊고 해당 MDF/NDF파일을 지켜낼 수 있었다.
데이터베이스 복구하기
결과적으로 크랙이 발생한 데이터베이스는 회복하지 못하였다.
해당 데이터베이스는 심플 복구 모델이며, 전체 백업파일은 2일전의 백업파일을 가지고 있었다.
해당 백업파일을 데이터베이스_NEW로 복구한 데이터는 멀정한지 여러 테스트를 거치게 되었다.
예전에도 데이터베이스의 페이지가 깨진적이 있어서 여러 방법을 통해 데이터 확인을 해보아서 많은 도움이 되었다.
MsSQL의 백업파일은... checksum옵션을 주지 않을 경우 데이터가 깨진 그대로 백업을 하기에 이렇게 대용량 데이터의 경우 깨져있는 그대로의 파일 일 수 있다.
해당 데이터베이스의 24억 row 테이블이 역시나 깨져있었고, 깨져있는 데이터를 어떻게 확인하였는지는 다음 포스팅에 남겨보도록 하겠다.
'DATABASE > MsSQL' 카테고리의 다른 글
[MsSQL] 쿼리튜닝 - Join Hint와 Leading Table (1) | 2024.12.28 |
---|---|
[MsSQL] SET STATISTICS 옵션을 활용 - 실제 실행 계획 상세보기 (0) | 2024.11.20 |
[MsSQL] 프로시저 내용 찾기 - 특정 테이블이 사용되는 프로시저 찾기 (1) | 2024.11.16 |
[MsSQL] 백업 파일 관리 - 최근 전체 백업과 하위 로그 백업 확인하기 (2) | 2024.11.14 |
[MsSQL] 마지막 페이지 Latch 경합 (Insert 지연 튜닝) - 2. 테스트 및 적용 (0) | 2024.11.13 |
[MsSQL] 현재 세션에 대한 정보들 조회하기 (0) | 2024.11.10 |
[MsSQL] 마지막 페이지 Latch 경합 (Insert 지연 튜닝) - 1. 원인 찾기 (1) | 2024.11.08 |
[MsSQL] 실행 했던 쿼리 실행 계획 찾기 (0) | 2024.11.07 |

초보 DBA 이야기입니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!