web-dev-qa-db-ja.com

別のサーバーのファイルからSQL Serverデータベースを自動的に復元する

私たちは、関連する本番データベースのバックアップを使用して、多数の開発データベースを上書きするという毎日のタスクを持っています。バックアップは、運用サーバーのメンテナンスプランによって作成され、FTPによって開発サーバーに転送されます。毎日、次のようなSQLステートメントを実行して、各データベースを上書きします。

RESTORE DATABASE [Database1] 
FROM DISK = N'D:\path\to\Database1_backup_2015_02_05_190004_7401803.bak'
WITH FILE = 1,  NOUNLOAD,  REPLACE,  STATS = 10
GO

これを実行するたびに、ファイル名を正しい最新のファイルに置き換える必要があります。これをどうにかして自動化して、オペレーターのエラーの可能性を最小化したいと思います。問題は、.bakファイルの名前を制御できないことです(形式は一貫していますが、データベース名、日付、時刻など、7桁の数字であれば何でもかまいません)。通常、フォルダーには数日分が含まれます。バックアップの。

5
toryan

バックアップに関するすべての詳細はmsdbデータベースに保持されるため、ソースサーバーからバックアップファイル名を抽出するだけで済みます。

開発サーバーからリンクサーバーを作成して、運用サーバーのmsdbデータベースにアクセスできます。または、OPENQUERYを使用して同じデータをクエリすることもできます。 (クエリは実際に運用サーバーで実行されているため、OPENQUERYの方が高速です。)

例えば:

SELECT * from OPENQUERY([LinkToPRD], 
     'EXEC database.dbo.ExecDailyRestore');

これは、パラメーターなしでストアード・プロシージャーを実行することを示しています。これは、毎日の復元計画に適している可能性があります。

「SQLサーバーデータベースの復元スクリプトの自動生成」を検索すると、多くのスクリプトが見つかります。 Paul Brewerの例はsp_RestoreGeneです。これをそのまま、または独自のExecDailyRestoreストアドプロシージャを作成するための基礎として使用できます。

https://paulbrewer.wordpress.com/sp_restoregene/

次に、sp_restoregeneがサポートするパラメータを示します。

    @Database SYSNAME = NULL,
    @TargetDatabase SYSNAME = NULL,
    @WithMoveDataFiles VARCHAR(2000) = NULL,
    @WithMoveLogFile  VARCHAR(2000) = NULL,
    @FromFileFullUNC VARCHAR(2000) = NULL,
    @FromFileDiffUNC VARCHAR(2000) = NULL,
    @FromFileLogUNC VARCHAR(2000) = NULL,
    @StopAt DATETIME = NULL,
    @StandbyMode BIT = 0,
    @IncludeSystemDBs BIT = 0,
    @WithRecovery BIT = 0,
    @WithCHECKDB BIT = 0,
    @WithReplace BIT = 0,
    @UseDefaultDatabaseBackupPath BIT = 0,
    @Log_Reference VARCHAR (250) = NULL,
    @LogShippingVariableDeclare BIT = 1,
    @LogShippingStartTime DATETIME = NULL,
    @LogShippingLastLSN VARCHAR(25) = NULL

そして、ここにサンプルスクリプトがあります:

RESTORE DATABASE db_workspace 
FROM DISK = 'X:\Backups\Temp\db_workspace.bak' WITH REPLACE, 
FILE = 1,CHECKSUM,NORECOVERY, STATS=10
, MOVE 'db_workspace' TO 'x:\data\db_workspace.mdf'
, MOVE 'db_workspace_log' TO 'x:\data\db_workspace_log.ldf'
, MOVE 'db_workspace_FG2' TO 'x:\data\db_workspace_FG2.ndf'
, MOVE 'db_workspace_FG1' TO 'x:\data\db_workspace_FG1.ndf'
10
RLF

ここのDBAはおそらく私に卵とトマトを投げるでしょうが、とにかくこれをそこに捨てます。

統合サービスジョブを使用してこれを実行できます。最初にfor Eachファイルループを作成し、その場所の各ファイルに対して実行するように設定します。 BackUp

結果を変数にマッピングします。 Variable

次に、コンテナ内でSQLタスクを作成して実行します。 EST

Map Query

これが完了すると、SQLジョブを作成して適切にスケジュールできるようになります。これが最良の解決策であると言っているわけではありませんが、うまくいくはずです。

FreeHand

8
Zane

これはあなたのために問題を正確に解決するはずです。明らかに、mdf/ldfの名前が異なるデータベースに復元する場合は、最後の復元コマンドを少し調整する必要があるかもしれません。これは、ディレクトリ内のバックアップをリストし、パターンに基づいて選択することで機能します。私もパターンを変数にすることができたと思いますが、あなたは要点を得ます。

     DECLARE @FileName varchar(255), @PathToBackup varchar(255), @RestoreFilePath varchar(1000)

     DECLARE @Files TABLE (subdirectory varchar(255), depth int, [file] int)

     SET NOCOUNT ON

     SET @PathToBackup = 'D:\path\to'

     -- insert into our memory table using dirtree and a single file level
     INSERT INTO @Files
     EXEC master.dbo.xp_DirTree @PathToBackup,1,1

     SELECT TOP 1 
        @FileName = [subdirectory]
     FROM 
        @Files
     WHERE
        -- get where it is a file
        [file] = 1
     AND    
        subdirectory LIKE 'Database1_backup%.bak'
     ORDER BY
        -- order descending so newest file will be first by naming convention
        subdirectory DESC

    IF LEFT(REVERSE(@PathToBackup), 1) != '\'
    BEGIN
        SET @PathToBackup = @PathToBackup + '\'
    END

    SET @RestoreFilePath = @PathToBackup + @FileName

    SELECT @RestoreFilePath

    RESTORE DATABASE [Database1] 
    FROM DISK = @RestoreFilePath
    WITH FILE = 1,  NOUNLOAD,  REPLACE,  STATS = 10
5
cberthold