[SQL Server] CMD 스크립트로 DB 복원하기

개발 프로세스가 라이브 서버에서 백업한 DB 파일을 다음날 개발 서버에 올려서 최근 데이터를 분석하고 추가 개발 패치를 해야 할 때가 있습니다.

원격 라이브 서버에서 날짜별, 시간대별로 백업한 DB 파일은 백업 폴더 안에 차곡 차곡 쌓여있기 때문에 가장 최근의 백업 파일을 찾아서 개발 서버에 복원을 해야 합니다.

먼저 특정 폴더 안에 있는 백업 파일 목록에서 파일 날짜가 가장 최근인 백업 파일을 찾아야 합니다.

DB백업 파일과 트랜잭션 로그 백업 2개를 파일 목록에서 찾아야 합니다. "NewestBackup", "NewestLog" 변수에 각각 할당합니다.

ECHO OFF
REM 가장 최근 파일 찾기
FOR /F "eol=| delims=" %%I IN ('DIR "*.bak" /A-D /B /O-D /TW 2^>nul') DO (
    SET NewestBackup=%%I
    GOTO FOUNDBACKUP
)
:FOUNDBACKUP
ECHO backup file is: %NewestBackup%

FOR /F "eol=| delims=" %%I IN ('DIR "*.trn" /A-D /B /O-D /TW 2^>nul') DO (
    SET NewestLog=%%I
    GOTO FOUNDLOG
)    
:FOUNDLOG
ECHO log file is: %NewestLog%

조금 더 세련되게 백업 파일을 못찾고 루프를 빠져나오면 CMD 스크립트가 종료되도록 GOTO 문을 추가합니다. 백업 파일을 못찾으면 스크립트 마지막 위치인 "END"로 이동하고 스크립트가 종료됩니다.

ECHO OFF
REM 가장 최근 파일 찾기
FOR /F "eol=| delims=" %%I IN ('DIR "*.bak" /A-D /B /O-D /TW 2^>nul') DO (
    SET NewestBackup=%%I
    GOTO FOUNDBACKUP
)
GOTO END
:FOUNDBACKUP
ECHO backup file is: %NewestBackup%

FOR /F "eol=| delims=" %%I IN ('DIR "*.trn" /A-D /B /O-D /TW 2^>nul') DO (
    SET NewestLog=%%I
    GOTO FOUNDLOG
)
GOTO END
:FOUNDLOG
ECHO log file is: %NewestLog%

REM DB 복원 커맨드 실행 -----

:END

복원하는 DB명은 apostdev입니다. "복원 커맨드 실행" 위치에 찾은 파일을 사용해서 복원하는 커맨드라인 행을 입력합니다.

SQL Server는 DB를 복원하려면 싱글모드로 변경해야 합니다. 싱글 모드 변경 후 DB와 로그 파일을 차례로 복원하고 다시 멀티유저 모드로 되돌립니다.

sqlcmd는 SQL Server의 커맨드라인 인터페이스입니다. -Q 옵션은 뒤에 오는 쿼리문을 실행하는 옵션이며, 실제로는 하나의 쿼리문으로 다 붙여서 실행해도 되지만 하나씩 구분해서 실행했습니다.

REM 복원(싱글)모드로 변경
sqlcmd -S 192.168.0.92 -U <db_userid> -P <db_password> -Q "ALTER DATABASE [apostdev] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;"

REM DB 복원
sqlcmd -S 192.168.0.92 -U <db_userid> -P <db_password> -Q "RESTORE DATABASE [apostdev] FROM DISK = '%CD%\%NewestBackup%' WITH FILE = 1, NOUNLOAD, REPLACE, NORECOVERY, STATS = 5;"

REM 로그 복원
sqlcmd -S localhost -U <db_userid> -P <db_password> -Q "RESTORE LOG apostdev FROM DISK = '%CD%\%NewestLog%';"

REM 운영모드로 변경
sqlcmd -S localhost -U <db_userid> -P <db_password> -Q "ALTER DATABASE [apostdev] SET MULTI_USER;"