본문 바로가기

[DataBase]/MSSQL

[MSSQL][시점복구] DB 원하는 시점으로 복구하기(+복구시점찾기, + 복구진행현황보기)

반응형

MSSQL DB 원하는 시점으로 복구하기

😱

이 글을 읽으러 온 너... DB 날려먹었구나!😱
내가 DB 작업할 때는 꼭 트랜젝션 걸고하라했잖아!!
못들었다고? 그럼 다시 한번 보고와 https://ppoble.tistory.com/entry/mssql-%EC%A0%9C%EB%B0%9C-%EC%9E%91%EC%97%85%ED%95%A0%EB%95%8C-%ED%8A%B8%EB%9E%9C%EC%A2%80-%EA%B1%B8%EA%B3%A0%ED%95%B4

그래도 일단 지급 급하니까 빨리 방법을 설명해줄께

1. 복구하고자 하는 DB의 전체 백업본 있어없어? 빨리 말해!

전체 백업본이 뭐냐고??

image


너 백업할때 저기 백업유형 전체로 되어있으면 전체 백업이야.
이거 있어야 가능해 없으면.... 미안하다... 원하는 시점으로 돌리는건 불가능하니까 가장 최근 백업본으로 돌려 그 방법이 최선이야...
있다면 2번 읽으러가고 없다면 혹시 모를 다른방법 찾기위해 뒤로가기 눌러😭😱

2. 복원용 더미 DB 생성

원래

image


이런 테이블인데

실수해서 이런상황이겠지??

image

자 그럼 너가 실수하기 전에 갖고 있는 전체 백업파일로 더미 DB를 만들어야해

image


이렇게 아래에다가 하나 만들고 갖고있는 백업파일로 복구해야하는데 조건이있어

  • 데이터베이스 복원 창 > 옵션 > 복구상태 > RESTORE WITH NORECOVERY 선택 및 "복원 전 비상 로그 백업 수행" 체크해제
    image

3. 복원중 상태 확인

2번을 잘 따라왔으면 더미 DB이름 옆에 "복원중..." 이 떠야해
이렇게

image

4. 기존 DB에서 트랜잭션로그 파일 생성

BACKUP LOG [기존 DB명] TO DISK='트랜잭션 로그 파일 경로,이름' WITH NO_TRUNCATE

(ex. BACKUP LOG [TEST_DB] TO DISK='D:\test\test.trn' WITH NO_TRUNCATE)

이렇게해서 파일 뽑아내자

image

5. 복구 시점 찾기

자 그럼 너가 복구하고자하는 정확한 시점을 찾아야해. 귀찮으면 대충 너가 실수한 시점 전으로 해도되는데 그렇게하면 그 사이에 DB에 작업된게 날라가겠지? 안그래도 지금 큰일인데 최대한 실수하기 전으로 똑같이 돌려야할거아냐. 그러니까 정확하게 시점 찾는법 설명해줄께

SELECT TOP 1000
QS.creation_time,
--SQL
SUBSTRING(ST.text,(QS.statement_start_offset/2)+1,
((CASE QS.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)
ELSE QS.statement_end_offset END - QS.statement_start_offset)/2) + 1
) AS statement_text,
--실행한 SQL
ST.text,
--실행 계획
QS.total_worker_time,
QS.last_worker_time,
QS.max_worker_time,
QS.min_worker_time
FROM
sys.dm_exec_query_stats QS
--키워드
CROSS APPLY
sys.dm_exec_sql_text(QS.sql_handle) ST
--대충 너가 실수했다고 생각하는 근처시간
WHERE creation_time BETWEEN '2022-01-18 09:30:00' AND '2022-01-18 11:10:00'
ORDER BY
QS.creation_time DESC

이거 실행하면 정확한 시점을 찾을 수 있어

6. 트랜잭션 로그파일로 [복원용 더미DB] 에 원하는 복원시점으로 복원

여기서 복구할때는 앞에서 찾은 너가 실수한 시점 바로 전까지! 해야하니까 그 전 쿼리와의 사이 시간을 입력해주면돼

RESTORE LOG [복원용 더미DB명] FROM DISK = '트랜잭션 로그 파일 경로,이름' WITH NORECOVERY, STOPAT = '복원 시점'

2022-01-18 10:20:00 에 정상쿼리가 실행됬고
2022-01-18 10:21:00 에 너가 쿼리 실수했다면
그 사이 아무 시간대나 하면돼

(ex. RESTORE LOG [TEST_DB_복원용더미] FROM DISK = 'D:\test\test.trn' WITH NORECOVERY, STOPAT = '2022-01-18 10:20:20.603')

7. [복원용 더미DB]의 "복원 중..." 상태를 변경

RESTORE DATABASE [복원용 더미DB명] WITH RECOVERY
(ex. RESTORE DATABASE TEST_DB_복원용더미 WITH RECOVERY)

8. 😎복구완료😎

자 이제 모두 끝났어. 너가 복원용 더미를 이제 원래DB로 이름만 바꿔서 이용하든 아니면 다시 백업해서 원래 DB에 씌우든 그건 너 편한대로하며돼. 고생했어👍
앞으로 실수하지말고!!!! DB 작업할때는 트랜젝션 꼭 걸고해 ㅡㅡ
백업도 자주 자주 해놓고!!!
용량없다고 전체백업 안하면 안된다!!!


999. 보충설명(읽고싶은 사람만 읽어 이건 안중요하니까)

대충 따라오면서 이해했겠지만 그래도 설명 해보자면
이전에 너가 정상 백업해둔 파일시점에서 그 이후에 실행된 쿼리들을 순차적으로 다 실행하면서 너가 실수한 시점 바로 전에서 멈추는거야
그렇게해서 원래 DB로 만드는거!


멈춘거같다고 중간에 취소하지말고!! DB 용량 클수록 백업이나 복원 오래걸리니까 기다려!!

그냥 기다리는거 심심하니까 알고싶으면

DB백업 진행 상태

SELECT session_id as SPID, command, a.text AS Query, 
       start_time, percent_complete, 
       DATEADD(second,estimated_completion_time/1000, GETDATE()) 
       AS estimated_completion_time 
FROM sys.dm_exec_requests r 
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a 
WHERE r.command = 'BACKUP DATABASE'

DB복원 진행 상태

SELECT session_id as SPID, command, a.text AS Query, 
       start_time, percent_complete, 
       DATEADD(second,estimated_completion_time/1000, GETDATE()) 
       AS estimated_completion_time 
FROM sys.dm_exec_requests r 
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a 
WHERE r.command = 'RESTORE DATABASE'

끝~!

반응형