Database
 sql >> Base de Dados >  >> RDS >> Database

Implementando backup e restauração automatizados de banco de dados com meios padrão

Introdução


Você pode encontrar muitos guias sobre como fazer backup e restaurar bancos de dados. Neste, mostraremos como isso pode ser feito usando os meios padrão do MS SQL Server.

Este exemplo cobrirá várias abordagens – desde a verificação da integridade do banco de dados antes de fazer backup até a restauração do banco de dados de uma cópia de backup criada anteriormente.


A solução


Em primeiro lugar, vamos ver o algoritmo geral que usaremos para fazer backup de um banco de dados:

1) Definir quais bancos de dados precisam de backup
2) Verificar a integridade dos bancos de dados escolhidos
3) Criar um backup (completo, diferencial ou cópia do log de transações) para cada um dos bancos de dados escolhidos
4) Verificando as cópias de backup criadas
5) Compactando os logs de transações (se necessário)

Abaixo, você pode encontrar um exemplo de implementação deste algoritmo.

Para definir quais bancos de dados precisam de backup, criaremos a seguinte tabela:
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[BackupSettings]( [DBID] [int] NOT NULL, [FullPathBackup] [nvarchar](255) NOT NULL, [DiffPathBackup] [nvarchar](255) ) NULL, [LogPathBackup] [nvarchar](255) NULL, [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_BackupSettings] PRIMARY KEY CLUSTERED ( [DBID] ASC)WITH (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY];GOALTER TABLE [srv].[BackupSettings] ADICIONAR CONSTRAINT [DF_BackupSettings_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate];GO

O identificador do banco de dados está localizado na primeira coluna, 'FullPathBackup' contém o caminho para a criação da cópia de backup completa (por exemplo, 'disk:\…\'), e o DiffPathBackup e LogPathBackup contêm caminhos completos para a criação de cópias de log de transações e diferenciais respectivamente. Se as colunas DiffPathBackup ou LogPathBackup estiverem vazias, a cópia do log diferencial e/ou de transações para esse banco de dados não será criada.

Também podemos criar uma representação com base nesta tabela:
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE view [srv].[vBackupSettings]asSELECT [DBID] ,DB_Name([DBID]) como [DBName] ,[FullPathBackup] ,[DiffPathBackup],[LogPathBackup], [InsertUTCDate] ] FROM [srv].[BackupSettings];GO

Essa representação permite verificar efetivamente quais bancos de dados estão participando do processo de backup.

Agora, vamos criar uma representação que exiba as informações do arquivo de banco de dados da representação do sistema sys.master_files:
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE view [inf].[ServerDBFileInfo] asSELECT @@Servername AS Server , File_id ,--DB file identificador. O valor base para file_id é 1 Type_desc ,--Type file description Name as [FileName] ,--DB nome do arquivo lógico LEFT(Physical_Name, 1) AS Drive ,--Drive sinalizador do local do arquivo DB Physical_Name ,--Full file name in the OS RIGHT(physical_name, 3) AS Ext ,--File extension Size as CountPage, --Tamanho do arquivo atual em páginas de 8Kb rodada((cast(Size*8 as float))/1024,3) as SizeMb, - -Tamanho do arquivo em Mb round((cast(Size*8 as float))/1024/1024,3) as SizeGb, --File size in Gb case when is_percent_growth=0 then Growth*8 else 0 end as Growth, -- Crescimento de arquivo em páginas de 8Kb caso quando is_percent_growth=0 então round((cast(Growth*8 as float))/1024,3) termine como GrowthMb, --File growth in Mb case quando is_percent_growth=0 então round((cast(Growth) *8 como float))/1024/1024,3) termina como GrowthGb, --File growth in Gb case when is_percent_growth=1 then Growth else 0 termina como GrowthPercent, --File growth in percent is_percent_growth, --Percent growth attribute database_id , DB_ Name(database_id) as [DB_Name], State,--File state state_desc as StateDesc,--File state description is_media_read_only as IsMediaReadOnly,--File está localizado na unidade como somente leitura (0 - e para gravação) is_read_only como IsReadOnly ,--arquivo é sinalizado como somente leitura (0 - e para gravação) is_sparse como IsSpace,--arquivo esparso is_name_reserved como IsNameReserved,--1 - Nome do arquivo remoto, acessível para uso. --É necessário obter um backup de log antes de usar o mesmo nome (argumentos name ou physical_name) novamente para um novo arquivo --0 - Nome do arquivo, inacessível para uso create_lsn como CreateLsn,--Número de registro da transação no log (LSN) que foi usado para criar o arquivo drop_lsn como DropLsn,--LSN que foi usado para excluir o arquivo read_only_lsn como ReadOnlyLsn,--LSN que foi usado pelo grupo de arquivos que contém o arquivo para alterar o tipo "ler e escrever" para "ler -only" (a última alteração) read_write_lsn como ReadWriteLsn,--LSN que foi usado pelo grupo de arquivos que contém o arquivo para alterar o tipo "somente leitura" para "leitura e gravação" (a última alteração) diferencial_base_lsn como DifferentialBaseLsn,- -Uma base para cópias de backup diferenciais. Extensões de dados que foram alteradas após o LSN ser incluído no backup diferencial. diferencial_base_guid as DifferentialBaseGuid,--Identificador exclusivo da cópia de backup base que será usada para criar uma cópia diferencial. diferencial_base_time as DifferentialBaseTime,--O tempo correspondente a diferencial_base_lsn redo_start_lsn como RedoStartLsn,--LSN usado para determinar o início do próximo redo --É NULL, exceto nos casos em que state =RESTORING ou state =RECOVERY_PENDING redo_start_fork_guid as RedoStartForkGuid,- -Identificador exclusivo para o ponto de bifurcação de restauração --first_fork_guid valor do argumento da próxima cópia de backup restaurada deve ser igual a este valor redo_target_lsn como RedoTargetLsn,--LSN que serve como um ponto de parada para um modo "online" refazer neste arquivo -- É NULL, exceto nos casos em que state =RESTORING ou state =RECOVERY_PENDING redo_target_fork_guid as RedoTargetForkGuid,--Fork de restauração no qual o contêiner pode ser restaurado. Usado junto com redo_target_lsn backup_lsn como BackupLsn--LSN dos dados mais recentes ou cópia de backup diferencial do arquivoFROM sys.master_files--database_files;GO

Para criar cópias de backup completas, vamos implementar o seguinte procedimento armazenado:

[expandir título ="Código “]
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunFullBackupDB] @ClearLog bit=1 --especifica se o tamanho do log de transações deve ser reduzidoASBEGIN /* Criando uma cópia de backup completa do banco de dados e verificando a integridade do banco de dados de antemão */ SET NOCOUNT ON; declare @dt datetime=getdate(); declare @ano int=ANO(@dt); declare @mês int=MÊS(@dt); declare @dia int=DAY(@dt); declare @hora int=DatePart(hora, @dt); declare @minuto int=DatePart(minuto, @dt); declare @second int=DatePart(second, @dt); declare @pathBackup nvarchar(255); declare @pathstr nvarchar(255); declare @DBName nvarchar(255); declare @backupName nvarchar(255); declare @sql nvarchar(max); declare @backupSetId como int; declare @FileNameLog nvarchar(255); declare @tbllog table( [DBName] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); declare @tbl table ( [DBName] [nvarchar](255) NOT NULL, [FullPathBackup] [nvarchar](255) NOT NULL ); --Recuperando o nome do banco de dados e os caminhos completos para a criação da cópia de backup completa, insira em @tbl ( [DBName], [FullPathBackup] ) selecione DB_NAME([DBID]) ,[FullPathBackup] de [srv].[BackupSettings]; --Recuperando o nome do banco de dados e os nomes dos logs de transação correspondentes (como um banco de dados pode ter vários logs) insira em @tbllog([DBName], [FileNameLog]) selecione t.[DBName], tt.[FileName] como [FileNameLog ] de @tbl como t junção interna [inf].[ServerDBFileInfo] como tt em t.[DBName]=DB_NAME(tt.[database_id]) onde tt.[Type_desc]='LOG'; --processando sequencialmente cada um dos bancos de dados que obtivemos anteriormente while(exists(select top(1) 1 from @tbl)) start set @backupSetId=NULL; selecione top(1) @DBName=[DBName], @pathBackup=[FullPathBackup] de @tbl; set @[email protected]+N'_Full_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))--+N'_' --+cast(@hora como nvarchar(255))+N'_'+cast(@minuto como nvarchar(255))+N'_'+cast(@ segundo como nvarchar(255)); set @[email protected]@sqldat.com+N'.bak'; --verificando a integridade do banco de dados @sql=N'DBCC CHECKDB(N'+N''''[email protected]+N''''+N') WITH NO_INFOMSGS'; exec(@sql); --executando o procedimento de criação da cópia de backup set @sql=N'BACKUP DATABASE ['[email protected]+N'] TO DISK =N'+N''''[email protected]+N''''+ N' WITH NOFORMAT, NOINIT, NAME =N'+N''''[email protected]+N''''+ N', CHECKSUM, STOP_ON_ERROR, SKIP, REWIND, COMPRESSION, STATS =10;'; exec(@sql); --verificando a cópia de backup que criamos, selecione @backupSetId =position from msdb..backupset where [email protected] e backup_set_id=(select max(backup_set_id) from msdb..backupset where [email protected]); set @sql=N'erro de verificação. As informações de cópia de backup para o banco de dados "'[email protected]+'" não foram encontradas.'; se @backupSetId for null begin raiserror(@sql, 16, 1) end else begin set @sql=N'RESTORE VERIFYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId as nvarchar(255)); exec(@sql); end --compactando os logs de transação do banco de dados if(@ClearLog=1) begin while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) begin select top(1) @FileNameLog=FileNameLog de @tbllog onde [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N' , 0 , APENAS TRUNCATE)'; exec(@sql); delete de @tbllog onde [email protected] e [email protected]; end end delete de @tbl onde [DBName][email protected]; endENDGO

[/expandir]

De acordo com o código, podemos ver que este procedimento fornece uma solução para as etapas restantes do algoritmo de criação da cópia de backup.

Os procedimentos que criam cópias diferenciais e de log de transações são implementados de maneira semelhante:

[expandir título ="Código “]
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunDiffBackupDB] @ClearLog bit=1 --especifica se o tamanho do log de transações deve ser reduzidoASBEGIN /* Criando uma cópia de backup de banco de dados diferencial */ SET NOCOUNT ON; declare @dt datetime=getdate(); declare @ano int=ANO(@dt); declare @mês int=MÊS(@dt); declare @dia int=DAY(@dt); declare @hora int=DatePart(hora, @dt); declare @minuto int=DatePart(minuto, @dt); declare @second int=DatePart(second, @dt); declare @pathBackup nvarchar(255); declare @pathstr nvarchar(255); declare @DBName nvarchar(255); declare @backupName nvarchar(255); declare @sql nvarchar(max); declare @backupSetId como int; declare @FileNameLog nvarchar(255); declare @tbl table ( [DBName] [nvarchar](255) NOT NULL, [DiffPathBackup] [nvarchar](255) NOT NULL ); declare @tbllog table( [DBName] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); --Recuperando o nome do banco de dados e os caminhos completos para criar cópias de backup diferenciais, insira em @tbl ( [DBName], [DiffPathBackup] ) selecione DB_NAME([DBID]) ,[DiffPathBackup] de [srv].[BackupSettings] onde [DiffPathBackup] não é nulo; --Recuperando o nome do banco de dados e os nomes completos dos arquivos de log de transações correspondentes (como um banco de dados pode ter vários logs) insira em @tbllog([DBName], [FileNameLog]) selecione t.[DBName], tt.[FileName] como [FileNameLog] de @tbl como t inner join [inf].[ServerDBFileInfo] como tt em t.[DBName]=DB_NAME(tt.[database_id]) onde tt.[Type_desc]='LOG'; --processando sequencialmente cada um dos bancos de dados que obtivemos anteriormente while(exists(select top(1) 1 from @tbl)) start set @backupSetId=NULL; selecione top(1) @DBName=[DBName], @pathBackup=[DiffPathBackup] de @tbl; set @[email protected]+N'_Diff_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))+N'_' +cast(@hora como nvarchar(255))+N'_'+cast(@minuto como nvarchar(255))+N'_'+cast(@second as nvarchar( 255)); set @[email protected]@sqldat.com+N'.bak'; --verificando a integridade do banco de dados @sql=N'DBCC CHECKDB(N'+N''''[email protected]+N''''+N') WITH NO_INFOMSGS'; exec(@sql); --executando o procedimento de backup set @sql=N'BACKUP DATABASE ['[email protected]+N'] TO DISK =N'+N''''[email protected]+N''''+ N' COM DIFERENCIAL, NOFORMAT, NOINIT, NOME =N'+N''''[email protected]+N''''+ N', CHECKSUM, STOP_ON_ERROR, SKIP, REWIND, COMPRESSION, STATS =10;'; exec(@sql); --verificando a cópia de backup que acabamos de criar selecione @backupSetId =position from msdb..backupset where [email protected] e backup_set_id=(select max(backup_set_id) from msdb..backupset where [email protected]); set @sql=N'erro de verificação. As informações de cópia de backup para o banco de dados "'[email protected]+'" não foram encontradas.'; se @backupSetId for null begin raiserror(@sql, 16, 1) end else begin set @sql=N'RESTORE VERIFYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId as nvarchar(255)); exec(@sql); end --compactando os logs de transação do banco de dados if(@ClearLog=1) begin while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) begin select top(1) @FileNameLog=FileNameLog de @tbllog onde [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N' , 0 , APENAS TRUNCATE)'; exec(@sql); delete de @tbllog onde [email protected] e [email protected]; end end delete de @tbl onde [DBName][email protected]; endENDGO

[/expandir]

Como verificar a integridade dos bancos de dados consome muitos recursos, podemos omiti-la ao criar uma cópia de backup diferencial.

[expandir título ="Código “]
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunLogBackupDB] @ClearLog bit=1 --especifica se o tamanho do log de transações deve ser reduzidoASBEGIN /* Fazendo backup do log de transações do banco de dados */ SET NOCOUNT ON; declare @dt datetime=getdate(); declare @ano int=ANO(@dt); declare @mês int=MÊS(@dt); declare @dia int=DAY(@dt); declare @hora int=DatePart(hora, @dt); declare @minuto int=DatePart(minuto, @dt); declare @second int=DatePart(second, @dt); declare @pathBackup nvarchar(255); declare @pathstr nvarchar(255); declare @DBName nvarchar(255); declare @backupName nvarchar(255); declare @sql nvarchar(max); declare @backupSetId como int; declare @FileNameLog nvarchar(255); declare @tbl table ( [DBName] [nvarchar](255) NOT NULL, [LogPathBackup] [nvarchar](255) NOT NULL ); declare @tbllog table( [DBName] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); --Recuperando nomes de banco de dados e caminhos completos para criar cópias de backup de logs de transações com um modelo de recuperação não simples (completo ou bulk-logged). Os BDs do sistema também são excluídos e inseridos em @tbl ( [DBName], [LogPathBackup] ) selecione DB_NAME(b.[DBID]) ,b.[LogPathBackup] de [srv].[BackupSettings] as b inner join sys.databases as d em b.[DBID]=d.[database_id] onde d.recovery_model<3 e DB_NAME([DBID]) não em ( N'master', N'tempdb', N'model', N'msdb', N' ReportServer', N'ReportServerTempDB' ) e [LogPathBackup] não é nulo; --Recuperando o nome do banco de dados e os nomes completos dos arquivos de log de transações correspondentes (como um banco de dados pode ter vários logs) insira em @tbllog([DBName], [FileNameLog]) selecione t.[DBName], tt.[FileName] como [FileNameLog] de @tbl como t inner join [inf].[ServerDBFileInfo] como tt em t.[DBName]=DB_NAME(tt.[database_id]) onde tt.[Type_desc]='LOG'; --processando sequencialmente cada um dos bancos de dados que obtivemos anteriormente while(exists(select top(1) 1 from @tbl)) start set @backupSetId=NULL; selecione top(1) @DBName=[DBName], @pathBackup=[LogPathBackup] de @tbl; set @[email protected]+N'_Log_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))+N'_' +cast(@hora como nvarchar(255))+N'_'+cast(@minuto como nvarchar(255))+N'_'+cast(@second as nvarchar( 255)); set @[email protected]@sqldat.com+N'.trn'; --executando o procedimento de backup set @sql=N'BACKUP LOG ['[email protected]+N'] TO DISK =N'+N''''[email protected]+N''''+ N' COM NOFORMAT, NOINIT, NAME =N'+N''''[email protected]+N''''+ N', CHECKSUM, STOP_ON_ERROR, SKIP, REWIND, COMPRESSION, STATS =10;'; exec(@sql); --Verificando a cópia de backup do log de transações que acabamos de criar, selecione @backupSetId =position from msdb..backupset where [email protected] e backup_set_id=(select max(backup_set_id) from msdb..backupset where [email protected]); set @sql=N'erro de verificação. As informações de cópia de backup para o banco de dados "'[email protected]+'" não foram encontradas.'; se @backupSetId for null begin raiserror(@sql, 16, 1) end else begin set @sql=N'RESTORE VERIFYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId as nvarchar(255)); exec(@sql); end --compactando os logs de transação do banco de dados if(@ClearLog=1) begin while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) begin select top(1) @FileNameLog=FileNameLog de @tbllog onde [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N' , 0 , APENAS TRUNCATE)'; exec(@sql); delete de @tbllog onde [email protected] e [email protected]; end end delete de @tbl onde [DBName][email protected]; endENDGO

[/expandir]

Como dito acima, verificar a integridade dos bancos de dados é uma tarefa que consome muitos recursos. Combinado com o fato de que as cópias de backup do log de transações geralmente precisam ser criadas com bastante frequência, isso nos dá uma razão para omitir a verificação de integridade ao criar uma cópia do log de transações.

Lembre-se também de que as cópias de backup completas dos bancos de dados 'master', 'msdb' e 'model' precisam ser feitas periodicamente.

Para automatizar o processo de criação da cópia de backup, você só precisa fazer uma chamada dos procedimentos implementados anteriormente no Agendador de Tarefas do Windows, trabalhos de agente ou qualquer serviço similar disponível.

Você precisará definir a frequência de chamada para cada um desses procedimentos individualmente com base nos picos de carga, platôs de atividade etc.

A abordagem básica é a seguinte:

1) Criar uma cópia de backup completa uma vez por dia
2) Criar cópias de backup diferenciais a cada 2-4 horas
3) Criar cópias de backup do log de transações a cada 5-60 minutos

Por favor, tenha em mente que normalmente os bancos de dados participam do sistema de acesso rápido e à prova de falhas. E, se o último usar cópias de backup do log de transações, é de vital importância não interferir no procedimento. Mais especificamente, isso significa que as cópias do log de transações não devem ser criadas por vários processos diferentes – se isso acontecer, a sequência de backup dessas cópias será perdida.

Aqui, vimos exemplos de cada banco de dados sendo processado sequencialmente, um de cada vez. No entanto, podemos obter processamento paralelo em ambiente de produção – permitindo que várias cópias de backup sejam feitas simultaneamente. Isso pode ser abordado de algumas maneiras diferentes. Por exemplo, chamando o seguinte procedimento armazenado:
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [inf].[RunAsyncExecute]( @sql nvarchar(max), @jobname nvarchar(57) =null, @database nvarchar(128)=null, @owner nvarchar( 128) =null)AS BEGIN/* Execução de pacote assíncrona através dos trabalhos do Agente RunAsyncExecute - execução assíncrona de comando T-SQL ou procedimento armazenado 2012 Antonin Foller, Motobit Software, www.motobit.com http://www.motobit.com/ dicas/detpg_async-execute-sql/ */ SET NOCOUNT ON; declare @id identificador exclusivo; --Cria um nome de trabalho exclusivo se o nome não for especificado se (@jobname for nulo) set @jobname=''; set @jobname =@jobname + '_async_' + convert(varchar(64),NEWID()); if (@proprietário é nulo) set @proprietário ='sa'; --Cria um novo trabalho, obtém o ID do trabalho executa msdb..sp_add_job @jobname, @[email protected], @[email protected] OUTPUT; --Especifique um servidor de trabalho para o trabalho execute msdb..sp_add_jobserver @[email protected]; --Especifique uma primeira etapa do trabalho - o comando SQL --(@on_success_action =3 ... Vá para a próxima etapa) execute msdb..sp_add_jobstep @[email protected], @step_name='Step1', @command =@sql, @database_name =@database, @on_success_action =3; --Especifique a próxima etapa do trabalho - exclua o trabalho declare @deletecommand varchar(200); set @deletecommand ='executar msdb..sp_delete_job @job_name='''[email protected]+''''; execute msdb..sp_add_jobstep @[email protected], @step_name='Step2', @command =@deletecommand; --Iniciar o trabalho execute msdb..sp_start_job @[email protected]; FINALIZAR

Aqui, a assincronia é alcançada criando dinamicamente os trabalhos do Agente, executando-os e excluindo-os posteriormente.

Agora, vamos ver o algoritmo geral para restaurar bancos de dados de cópias de backup criadas anteriormente em um ambiente diferente/de teste:

1) Definindo quais bancos de dados devem ser restaurados e a localização de suas cópias de backup
2) Restaurando os bancos de dados
3) Verificando a integridade dos bancos de dados restaurados

Agora, veremos uma implementação de um algoritmo que restaura um banco de dados a partir de uma cópia de backup completa. Para uma cópia diferencial, o procedimento é semelhante – a única diferença é que uma cópia de backup completa precisa ser restaurada em primeira mão, seguida pela cópia diferencial.

Para definir quais bancos de dados devem ser restaurados, bem como a localização de suas cópias de backup, vamos criar duas tabelas conforme mostrado abaixo:
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[RestoreSettings]( [DBName] [nvarchar](255) NOT NULL, [FullPathRestore] [nvarchar](255) NOT NULL, [DiffPathRestore] [nvarchar ](255) NOT NULL, [LogPathRestore] [nvarchar](255) NOT NULL, [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_RestoreSettings] PRIMARY KEY CLUSTERED ( [DBName] ASC)WITH (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF , IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY];GOALTER TABLE [srv].[RestoreSettings] ADD CONSTRAINT [DF_RestoreSettings_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate];GO 
Aqui, a finalidade das colunas é análoga à da tabela [srv].[BackupSettings]. A única diferença é que o caminho completo será usado para localizar as cópias de backup para restauração e não para criar novas.

USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[RestoreSettingsDetail]( [Row_GUID] [uniqueidentifier] NOT NULL, [DBName] [nvarchar](255) NOT NULL, [SourcePathRestore] [nvarchar](255) ) NOT NULL, TargetPathRestore [nvarchar](255) NOT NULL, [Ext] [nvarchar](255) NOT NULL, [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_RestoreSettingsDetail] PRIMARY KEY CLUSTERED ( [Row_GUID] ASC)WITH ( PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY];GOALTER TABLE [srv].[RestoreSettingsDetail] ADD CONSTRAINT [DF_RestoreSettingsDetail_Row_GUID] DEFAULT (newid()) FOR [Row_GUID];GOALTER TABLE [srv].[RestoreSettingsDetail] ADICIONAR CONSTRAINT [DF_RestoreSettingsDetail_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate];GO

Esta tabela é necessária para definir os nomes de arquivo completos do banco de dados que está sendo restaurado, que são usados ​​para transferência adicional (por exemplo, [SourcePathRestore]='Logical file name' e [TargetPathRestore]='disk:\…\Physical file name ', enquanto [Ext]='Extensão do arquivo')

Na verdade, podemos definir nomes lógicos dos arquivos de banco de dados usando a seguinte consulta:
RESTORE FILELISTONLY FROM DISK ='disk:\...\backup copy.BAK';

A obtenção de informações sobre cópias de backup localizadas em um arquivo pode ser feita desta forma:

RESTORE HEADRONLYFROM DISK='disk:\...\backup copy.BAK';

Em seguida, temos uma implementação de um procedimento armazenado usado para restaurar um banco de dados de uma cópia de backup completa e verificar a integridade dos dados:

[expandir título ="Código “]
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunFullRestoreDB]ASBEGIN /* Recuperando um banco de dados de uma cópia de backup completa e verificando a integridade do banco de dados */ SET NOCOUNT ON; declare @dt datetime=DateAdd(day,-2,getdate()); declare @ano int=ANO(@dt); declare @mês int=MÊS(@dt); declare @dia int=DAY(@dt); declare @hora int=DatePart(hora, @dt); declare @minuto int=DatePart(minuto, @dt); declare @second int=DatePart(second, @dt); declare @pathBackup nvarchar(255); declare @pathstr nvarchar(255); declare @DBName nvarchar(255); declare @backupName nvarchar(255); declare @sql nvarchar(max); declare @backupSetId como int; declare @FileNameLog nvarchar(255); declare @SourcePathRestore nvarchar(255); declare @TargetPathRestore nvarchar(255); declare @Ext nvarchar(255); declare @tbl table ( [DBName] [nvarchar](255) NOT NULL, [FullPathRestore] [nvarchar](255) NOT NULL ); declare @tbl_files table ( [DBName] [nvarchar](255) NOT NULL, [SourcePathRestore] [nvarchar](255) NOT NULL, [TargetPathRestore] [nvarchar](255) NOT NULL, [Ext] [nvarchar](255) NÃO NULO ); --recuperando uma lista de nomes de banco de dados e os caminhos para cópias de backup completas insira em @tbl ( [DBName], [FullPathRestore] ) selecione [DBName] ,[FullPathRestore] de [srv].[RestoreSettings]; --recuperando informações detalhadas sobre a nova localização dos arquivos DB, insira em @tbl_files ( [DBName], [SourcePathRestore] ,[TargetPathRestore] ,[Ext] ) selecione [DBName] ,[SourcePathRestore] ,[TargetPathRestore] ,[Ext] de [ srv].[RestoreSettingsDetail]; --processando cada um dos BDs que obtivemos anteriormente while(exists(select top(1) 1 from @tbl)) start set @backupSetId=NULL; selecione top(1) @DBName=[DBName], @pathBackup=[FullPathRestore] de @tbl; set @[email protected]+N'_Full_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))--+N'_' --+cast(@hora como nvarchar(255))+N'_'+cast(@minuto como nvarchar(255))+N'_'+cast(@ segundo como nvarchar(255)); set @[email protected]@sqldat.com+N'.bak'; --criando uma consulta de backup e executando-a set @sql=N'RESTORE DATABASE ['[email protected]+N'_Restore] FROM DISK =N'+N''''[email protected]+N''' '+ N' COM ARQUIVO =1,'; while(exists(select top(1) 1 from @tbl_files where [DBName][email protected])) start selecione top(1) @SourcePathRestore=[SourcePathRestore], @TargetPathRestore=[TargetPathRestore], @Ext=[Ext] de @tbl_files onde [DBName][email protected]; set @[email protected]+N' MOVE N'+N''''[email protected]+N''''+N' PARA N'+N''''[email protected]+N' _Restore.'[email protected]+N''''+N','; delete de @tbl_files onde [DBName][email protected] e [SourcePathRestore][email protected] e [Ext][email protected]; end set @[email protected]+N' NOUNLOAD, REPLACE, STATS =5'; exec(@sql); --verificando a integridade do banco de dados @sql=N'DBCC CHECKDB(N'+N''''[email protected]+'_Restore'+N''''+N') WITH NO_INFOMSGS'; exec(@sql); delete de @tbl onde [DBName][email protected]; fimEND

[/expandir]

Para especificar qual cópia de backup completa deve ser usada para restauração, um nome de arquivo especialmente estruturado é usado:

_Full_backup___.bak

Para automatizar esse processo de restauração do banco de dados, a chamada do procedimento armazenado que implementamos deve ser colocada no Agendador de Tarefas do Windows, nos trabalhos do Agente ou em qualquer serviço similar disponível.

Você pode ver as cópias de backup do banco de dados mais recentes usando a seguinte representação:
USE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE VIEW [inf].[vServerLastBackupDB] aswith backup_cte as( selecione bs.[database_name], backup_type =case bs.[type] quando 'D' então 'database' quando 'L ' então 'log' quando 'I' então 'diferencial' else 'outro' final, bs.[first_lsn], bs.[last_lsn], bs.[backup_start_date], bs.[backup_finish_date], cast(bs.[backup_size] como decimal(18,3))/1024/1024 como BackupSizeMb, rownum =row_number() sobre ( partição por bs.[database_name], digite ordem por bs.[backup_finish_date] desc ), LogicalDeviceName =bmf.[logical_device_name], PhysicalDeviceName =bmf.[physical_device_name], bs.[server_name], bs.[user_name] FROM msdb.dbo.backupset bs INNER JOIN msdb.dbo.backupmediafamily bmf ON [bs].[media_set_id] =[bmf].[media_set_id]) selecione [server_name] como [ServerName], [database_name] como [DBName], [user_name] como [USerName], [backup_type] como [BackupType], [backup_start_date] como [BackupStartDate], [backup_finish_date] como [BackupFinishDate], [BackupSizeMb], -- tamanho descompactado [LogicalDeviceName], [PhysicalDeviceName], [first_lsn] como [FirstLSN], [last_lsn] como [LastLSN] de backup_ctewhere rownum =1;

O resultado


Neste guia, analisamos a implementação do processo de backup automatizado em um servidor e a consequente restauração em outro (um servidor de teste, por exemplo).

Este método permite automatizar o processo de criação de cópias de segurança, verificar as cópias de segurança restaurando-as e ajustar os processos mostrados acima.

Fontes:


Backup
Restaurar
Backupset
CHECKDB
SHRINKFILE
sys.master_files