AWS
SQLServer
S3
RDS
運用

S3 にある SQLServer のバックアップ (.bak) から RDS へバッチを使ってリストアしてみる

0.はじめに

以前、
こちらの対応をし、

その後、
こちらの対応をし、

最後に、
S3 に保存した SQLServer のバックアップ (.bak) から RDS へリストアしてみようと思います。

出来れば、
ジョブで定期実行して、何ちゃってミラーリングしようかと思っています。

1.まずは、SQL Server Management Studio を使って、RDS へリストア

  1. SQL Server Management Studio で RDS へ接続します。以下の項目を設定し、「接続」ボタンを押下。
    • データベースの種類 : 「データベース エンジン」
    • サーバー名 : [RDS インスタンスのエンドポイント],[ポート番号]
      • 例 : xxxxxxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com,1433
    • 認証 : 「SQL Server 認証」
    • ログイン : [ユーザーID]
    • パスワード : [パスワード]

    • スクリーンショット 2017-11-10 15.23.41.png

  2. RDS インスタンスの情報が表示されるので、リストアするデータベースが存在するか確認し、存在する場合は削除します。
  3. 「新しいクエリ」から、以下のコマンドをクエリデザイナーにコピペし、「実行」します。

    • スクリーンショット 2017-11-10 15.24.42.png
    exec msdb.dbo.rds_restore_database 
        @restore_db_name='[データベース名]', 
        @s3_arn_to_restore_from='arn:aws:s3:::[S3 バケットの .bak ファイルパス]';
    

2.バッチ (sqlcmd) を使って、RDS へリストア

  1. sqlcmd を使える様にしておきます。
  2. 以下のバッチプログラムを実行します。
MSSQL_RestoreDB_toRDS_fromS3bak.bat
@echo off
setlocal ENABLEDELAYEDEXPANSION

rem # ==========================================================================
rem # S3 の .bak ファイルから RDS(MSSQL) への DB のリストアを行う。
rem # 
rem # ※以下の項目を設定し直すこと!!
rem #   ・Common : 各種設定
rem #   ・AWS : AWS関連情報
rem #   ・DataBase : データベース関連情報
rem # ==========================================================================

pushd %0¥..
cls

rem # --------------------------------------------------------------------------
rem # Set
rem # --------------------------------------------------------------------------

rem # ----------------------------------
rem # Common
rem # ----------------------------------
title %0
set mypath=%‾dp0
set mypath=%mypath:‾0,-1%
set dt=%date:‾-10%
set tm=%time: =0%
set yyyymmdd=%dt:‾0,4%%dt:‾5,2%%dt:‾8,2%%tm:‾0,2%%tm:‾3,2%%tm:‾6,2%
set USR_INPUT_STR=
set logfile=%‾n0.log
set logfilepath=%mypath%¥%logfile%
set tmpfile=%‾n0.tmp
set tmpfilepath=%mypath%¥%tmpfile%

rem # ----------------------------------
rem # AWS
rem # ----------------------------------
set rds_endpoint=[RDSインスタンスのエンドポイント] ※例 : xxxxxxxx.xxxxxxxx.ap-northeast-1.rds.amazonaws.com,1433
set rds_dbuser=[ユーザーID]
set rds_dbpassword=[パスワード]
set s3_arn_to_restore_from=arn:aws:s3:::[S3 バケットの .bak ファイルパス] ※例 : s3-backet/xxxx.bak

rem # ----------------------------------
rem # DataBase
rem # ----------------------------------
set db_cmd_sqlcmd=sqlcmd -S "%rds_endpoint%" -U %rds_dbuser% -P %rds_dbpassword% -W -h -1 -s "  "
set db_name=[データベース名]

rem # --------------------------------------------------------------------------
rem # Program Start
rem # --------------------------------------------------------------------------
echo.
echo.>> "%logfilepath%"
echo ==========================================================================
echo ==========================================================================>> "%logfilepath%"
echo [%DATE% %TIME%] Program Start - Start
echo [%DATE% %TIME%] Program Start - Start>> "%logfilepath%"

echo [%DATE% %TIME%] rds_endpoint : [%rds_endpoint%]
echo [%DATE% %TIME%] rds_endpoint : [%rds_endpoint%]>> "%logfilepath%"
echo [%DATE% %TIME%] s3_arn_to_restore_from : [%s3_arn_to_restore_from%]
echo [%DATE% %TIME%] s3_arn_to_restore_from : [%s3_arn_to_restore_from%]>> "%logfilepath%"
echo [%DATE% %TIME%] db_name : [%db_name%]
echo [%DATE% %TIME%] db_name : [%db_name%]>> "%logfilepath%"

:do_1
rem # ----------------------------------
rem # Database Check Task Status
rem # ----------------------------------
set rtn_db_check_task_status=
set /a i=0
for /f "delims=" %%A in ('%db_cmd_sqlcmd% -Q "EXIT( exec msdb.dbo.rds_task_status @db_name='%db_name%' )"') do (
  set /a i=i+1
  set A=%%A
  rem secho ==!i!==
  rem echo A:!A!
  set /a ii=0
  for /f "usebackq tokens=1,2,3,4,5,6,7,8,9,10 delims=  " %%A in ('!A!') do (
    set /a ii=ii+1
    rem echo --!ii!--
    rem echo task_id : %%A
    rem echo task_type : %%B
    rem echo database_name : %%C
    rem echo complete : %%D
    rem echo duration mins : %%E
    rem echo lifecycle : %%F
    rem echo task_info : %%G
    rem echo last_updated : %%H
    rem echo created_at : %%I
    rem echo overwrite_S3_backup_file : %%J
    if "%%B"=="RESTORE_DB" (
      if "%%F"=="CREATED" (
        set rtn_db_check_task_status=%rtn_db_check_task_status%,%%F
      ) else if "%%F"=="IN_PROGRESS" (
        set rtn_db_check_task_status=%rtn_db_check_task_status%,%%F
      ) else if "%%F"=="CANCEL_REQUESTED" (
        set rtn_db_check_task_status=%rtn_db_check_task_status%,%%F
      )
    )
  )
)
echo [%DATE% %TIME%] Database Check Task Status : [%rtn_db_check_task_status%]
echo [%DATE% %TIME%] Database Check Task Status : [%rtn_db_check_task_status%]>> "%logfilepath%"

:do_2
rem # ----------------------------------
rem # Database Check Exist
rem # ----------------------------------
if not "%rtn_db_check_task_status%"=="" (
  timeout 5 /nobreak >nul
  goto do_1
)
set rtn_db_check_exist=
set /a i=0
for /f "delims=" %%A in ('%db_cmd_sqlcmd% -Q "set nocount on; select count(*) from sysdatabases where name = '%db_name%'"') do (
  set /a i=i+1
  set A=%%A
  rem echo !i!:!A!
  if !i! equ 1 (
    rem set rtn_db_check_exist=!A:/=!
    set rtn_db_check_exist=!A!
  )
)
echo [%DATE% %TIME%] Database Check Exist : [%rtn_db_check_exist%]
echo [%DATE% %TIME%] Database Check Exist : [%rtn_db_check_exist%]>> "%logfilepath%"

:do_3
rem # ----------------------------------
rem # Database Drop
rem # ----------------------------------
if "%rtn_db_check_exist%"=="0" (
  goto do_4
)
set rtn_db_drop=
set /a i=0
for /f "delims=" %%A in ('%db_cmd_sqlcmd% -Q "set nocount on; drop database %db_name%"') do (
  set /a i=i+1
  set A=%%A
  echo !i!:!A!
  echo [%DATE% %TIME%] Database Drop
  echo [%DATE% %TIME%] Database Drop>> "%logfilepath%"
)
timeout 5 /nobreak >nul
goto do_2

:do_4
rem # ----------------------------------
rem # Database Restore
rem # ----------------------------------
set rtn_db_restore_task_id=
set /a i=0
for /f "delims=" %%A in ('%db_cmd_sqlcmd% -Q "EXIT(exec msdb.dbo.rds_restore_database @restore_db_name='%db_name%', @s3_arn_to_restore_from='%s3_arn_to_restore_from%';)"') do (
  set /a i=i+1
  set A=%%A
  rem echo ==!i!==
  rem echo A:!A!
  echo [%DATE% %TIME%] Database Restore : result:[!A!]
  echo [%DATE% %TIME%] Database Restore : result:[!A!]>> "%logfilepath%"
  set /a ii=0
  for /f "usebackq tokens=1,2,3,4,5,6,7,8,9,10 delims=  " %%A in ('!A!') do (
    set /a ii=ii+1
    if !i! equ 1 (
      set rtn_db_restore_task_id=%%A
    )
  )
)
echo [%DATE% %TIME%] Database Restore : task_id:[%rtn_db_restore_task_id%]
echo [%DATE% %TIME%] Database Restore : task_id:[%rtn_db_restore_task_id%]>> "%logfilepath%"

:do_5
rem # ----------------------------------
rem # Database Check Task Status Restore
rem # ----------------------------------
set rtn_db_check_task_status_restore=
set /a i=0
for /f "delims=" %%A in ('%db_cmd_sqlcmd% -Q "EXIT(exec msdb.dbo.rds_task_status @task_id=%rtn_db_restore_task_id%)"') do (
  set /a i=i+1
  set A=%%A
  rem echo ==!i!==
  rem echo A:!A!
  set /a ii=0
  for /f "usebackq tokens=1,2,3,4,5,6,7,8,9,10 delims=  " %%A in ('!A!') do (
    set /a ii=ii+1
    echo [%DATE% %TIME%] %%A %%B %%C %%D %%E %%F %%J
    echo [%DATE% %TIME%] %%A %%B %%C %%D %%E %%F %%J>> "%logfilepath%"
    if "%%F"=="SUCCESS" (
      set rtn_db_check_task_status_restore=%%F
    ) else if "%%F"=="ERROR" (
      set rtn_db_check_task_status_restore=%%F
    ) else if "%%F"=="CANCELLED" (
      set rtn_db_check_task_status_restore=%%F
    )
  )
)
if "%rtn_db_check_task_status_restore%"=="" (
  timeout 5 /nobreak >nul
  goto do_5
)
echo [%DATE% %TIME%] Database Check Task Status Restore : [%rtn_db_check_task_status_restore%]
echo [%DATE% %TIME%] Database Check Task Status Restore : [%rtn_db_check_task_status_restore%]>> "%logfilepath%"

echo.
echo.>> "%logfilepath%"
echo [%DATE% %TIME%] Database Restore - End
echo [%DATE% %TIME%] Database Restore - End>> "%logfilepath%"
echo ==========================================================================
echo ==========================================================================>> "%logfilepath%"
rem # --------------------------------------------------------------------------
rem # Program End
rem # --------------------------------------------------------------------------

:end
rem pause

exit /b

99.ハマりポイント

XX.まとめ

色々と突っ込みどころのあるプログラムかも知れませんが、
その際は、コメント下さい。

よろしくお願いしますします。