2019년 1월 13일 일요일

MSSQL 복원에 대하여

저번 편 MSSQL 백업에 대하여에 이어 이번편은 MSSQL 복원편을 다뤄보기로 한다.

MSSQL 복원 시에는 옵션이 3가지가 있다.

데이터베이스 복원 시 옵션은 3가지가 있다.
(새로운 서버에 복원할 때는 모든 옵션이 의미가 없다.)

1. 기존 데이터베이스 덮어쓰기(WITH REPLACE)
복원 대상 데이터베이스가 이미 존재한다면 강제로 덮어쓰므로 신중해야한다.

2. 복제 설정 유지(WITH KEEP_REPLICATION)
복제와 연관된 데이터베이스는 관련 설정을 그대로 유지하고 복제와 연관되지 않은 경우 무의미하다.

3. 복원된 데이터베이스에 대한 액세스 제한(WITH RESTRICTED_USER)
복원 후 일반 사용자가 접근할 수 없도록 제한한다.
관리자 권한의 계정만 접근 허용한다.
데이터베이스 속성에서 모든 사용자가 사용하게 설정할 수 있다.


데이터베이스 복원 시 복구 상태에는 3가지가 있다.
1. RESTORE WITH RECOVERY
커밋되지 않은 트랜잭션을 롤백하여 데이터베이스를 사용할 수 있는 상태로 유지한다.
추가 트랜잭션 로그를 복원할 수 없다.

2. RESOTRE WITH NORECOVERY
데이터베이스를 비작동 상태(복원 중 상태-OFFLINE)로 유지하고 커밋되지 않은 트랜잭션을 롤백하지 않는다. 추가 트랜잭션 로그를 복원할 수 있다.

3. RESOTRE WITH STANDBY
우선 데이터베이스를 읽기 전용 모드로 유지한다.
커밋되지 않은 트랜잭션은 롤백.
롤백된 트랜잭션의 내용을 별도의 대기 파일에 기록함.
추가 트랜잭션 로그를 복원할 수 있다.



1. 전체 백업만 하는 경우
데이터베이스에 문제가 발생했하면 바로 tail-log backup을 받고 전체백업복원(NORECOVERY) 후 로그백업복원(RECOVERY)을 한다. 하지만 데이터베이스가 단순 복구 모델인 경우 tail-log backup을 받을 수 없어 가장 마지막 전체 백업만 복원할 수 있다.

2. 전체 백업 + 로그 백업을 하는 경우
우선 tail-log backup를 받는다. 이후 가장 마지막 전체 백업복원(NORECOVERY)을 하고 이 전체 백업 이후의 모든 트랜잭션 로그 백업을 복원(NORECOVERY)한다. 마지막으로 로그백업복원(RECOVERY)을 하면 데이터베이스를 완벽하게 복원할 수 있다.

3. 전체백업 + 차등백업 + 로그 백업
일단 tail-log backup을 받는다. 그리고 가장 마지막 전체 백업을 복원(NORECOVERY)하고, 이 전체 백업 이후의 가장 마지막 차등 백업을 복원(NORECOVERY)한다. 이어서 이 차등 백업 이후의 모든 로그 백업을 복원(NORECOVERY)하고 마지막으로 로그백업복원(RECOVERY)을 한다.

계속해서 복원할 백업 파일이 있으면 NORECOVERY로 복원하고 마지막 복원에는 RECOVERY로 복원한다. NORECOVERY상태인 경우 복원 중인 DB이므로 사용자는 접근할 수 없다.


USE master
GO
ALTER DATABASE TESTDB01
   SET SINGLE_USER WITH ROLLBACK IMMEDIATE
-- 웬만하면 사용하지 말도록 하자. 너무 위험하다. 쿼리창을 실수로 닫아버린다면.. 모르겠다.
GO


RESTORE DATABASE TESTDB01
    FROM DISK = 'F:\SQLBackup\TESTDB01_20170703_FULL.bak'
    WITH REPLACE, NORECOVERY, STATS = 10
GO

RESTORE LOG TESTDB01
    FROM DISK = 'F:\SQLBackup\TESTDB01_20170703_LOG.trn'
    WITH REPLACE, RECOVERY, STATS = 10
GO


ALTER DATABASE  TESTDB01
   SET MULTI_USER
GO


※ 꼭 기억하고 있자.
백업 파일의 위치, 복원에 소요되는 시간 예측, 복원 완료 여부 확인. 참고로 복원에 대한 시간도 중요하지만 백업 파일을 가져오는데 소요되는 시간도 복원 시간에 포함하여야 하므로 특히 파일이 큰 경우 수시간이 걸릴 수 있다는 점을 알고있어야 한다.

비상 로그 백업
'복원 전 비상 로그 백업 수행' 옵션은 복원 대상 데이터베이스에 백업되지 않은 트랜잭션 로그가 있을 경우 자동으로 로그를 백업받는 옵션이고 자동으로 선택된다.
SQL SERVER는 전체 복구 모델이나 대량 로그 복구 모델인 데이터베이스에 대해서는 MDF, NDF 파일이 손상됐더라도 트랜잭션 로그 파일이 물리적으로 손상되지만 않았다면 이를 백업받을 수 있다.


USE master
GO
BACKUP LOG TESTDB01
       TO DISK = 'F:\SQLBackup\TESTDB01_LOG_tail.trn'
       WITH CONTINUE_ALTER_ERROR
GO


--특정 시점으로 복원하기
USE master
GO
-- 전체 백업으로 복원
RESTORE DATABASE TESTDB01
    FROM DISK = 'F:\SQLBackup\TESTDB01_20170703_FULL.bak'
    WITH NORECOVERY, STATS = 10
GO

-- 마지막 차등 백업(있으면) 복원
RESTORE DATABASE TESTDB01
    FROM DISK = 'F:\SQLBackup\TESTDB01_20170703_DIFF.bak'
    WITH NORECOVERY, STATS = 10
GO


-- 이후 로그 백업(있으면) 복원
RESTORE LOG TESTDB01
    FROM DISK = 'F:\SQLBackup\TESTDB01_20170703_LOG.trn'
    WITH NORECOVERY, STATS = 10
GO

-- 특정 시점에서 복원 완료
RESTORE LOG TESTDB01
    FROM DISK = 'F:\SQLBackup\TESTDB01_LOG_tail.trn'
    WITH STOPAT = '2017-11-11 03:03:03'
GO

응급모드
데이터베이스가 손상되어 백업받을 수 없고 이전 백업도 없는 상황에서 현재 데이터를 급히 보고자할 때 응급 모드를 사용할 수 있다. 중요한 데이터를 이때 빠르게 다른데로 복사하자. 이전으로 돌아가려면 ONLINE 모드로 변경하면 된다.

USE master
GO
ALTER DATABASE TESTDB01
   SET EMERGENCY
GO

ALTER DATABASE TESTDB01
   SET ONLINE
GO


--백업 내역 조회하는 쿼리
USE msdb
GO
SELECT
        B.DATABASE_NAME AS 'DB'
      , CASE B.TYPE
          WHEN 'D' THEN N'FULL'
          WHEN 'L' THEN N'LOG'
          WHEN 'I' THEN N'DIF' END AS 'TYPE'
   , CONVERT(VARCHAR(20), B.BACKUP_START_DATE, 120) AS 'START'
   , CONVERT(VARCHAR(20), B.BACKUP_FINISH_DATE, 120) AS 'END'
   , CONVERT(DECIMAL(10,2), B.BACKUP_SIZE / 1024 / 1024) AS 'SIZE(MB)'
   , A.PHYSICAL_DEVICE_NAME AS 'FILE'
   , B.NAME AS 'NAME'
   , B.DESCRIPTION AS 'DESCRIPTION'
FROM BACKUPMEDIAFAMILY A
JOIN BACKUPSET                 B
                                       ON A.MEDIA_SET_ID = B.MEDIA_SET_ID
ORDER BY CONVERT(VARCHAR(20), B.BACKUP_START_DATE, 120) DESC


댓글 없음:

댓글 쓰기

2022년 회고

 올해는 블로그 포스팅을 열심히 못했다. 개인적으로 지금까지 경험했던 내용들을 리마인드하자는 마인드로 한해를 보낸 것 같다.  대부분의 시간을 MLOps pipeline 구축하고 대부분을 최적화 하는데 시간을 많이 할애했다. 결국에는 MLops도 데이...