sql >> Databasteknik >  >> RDS >> Database

Implementera automatisk säkerhetskopiering och återställning av databas med standardmedel

Introduktion

Du kan hitta många guider om hur du säkerhetskopierar och återställer databaser. I den här kommer vi att visa hur detta kan göras med standardmetoden för MS SQL Server.

Det här exemplet kommer att täcka ett antal tillvägagångssätt – från att kontrollera databasens integritet innan du säkerhetskopierar den till att återställa databasen från en tidigare skapad säkerhetskopia.

Lösningen

Låt oss först titta på den övergripande algoritmen vi kommer att använda för att säkerhetskopiera en databas:

1) Definiera vilka databaser som behöver säkerhetskopieras
2) Kontrollera integriteten för de valda databaserna
3) Skapa en säkerhetskopia (fullständig, differentiell eller transaktionsloggkopia) för var och en av de valda databaserna
4) Kontrollera de skapade säkerhetskopiorna
5) Komprimera transaktionsloggarna (om det behövs)

Nedan kan du hitta ett implementeringsexempel på denna algoritm.

För att definiera vilka databaser som måste säkerhetskopieras skapar vi följande tabell:

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[BackupSettings]( [DBID] [int] NOT NULL, [FullPathBackup] [nvarchar](255) INTE NULL, [DiffPathBack ) NULL, [LogPathBackup] [nvarchar](255) NULL, [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_BackupSettings] PRIMÄRNYCKEL CLUSTERED ( [DBID] ASC)WITH (PAD_INDEX =AV, STATISTICS_N, OFF, STATISTICS_N, OFF ALLOW_ROW_LOCKS =PÅ, ALLOW_PAGE_LOCKS =PÅ) PÅ [PRIMÄR]) PÅ [PRIMÄR];GOALTER TABELL [srv].[BackupSettings] LÄGG TILL BEGRÄNSNING [DF_BackupSettings_InsertUTCDate] DEFAULT (getutcdate[Infoga) FÖR 

Databasidentifieraren finns i den första kolumnen, 'FullPathBackup' innehåller sökvägen för att skapa fullständig säkerhetskopia (till exempel 'disk:\...\'), och DiffPathBackup och LogPathBackup innehåller fullständiga sökvägar för att skapa differential- och transaktionsloggkopior respektive. Om kolumnerna DiffPathBackup eller LogPathBackup är tomma kommer inte differential- och/eller transaktionsloggkopian för denna databas att skapas.

Vi kan också skapa en representation baserat på denna tabell:

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE visa [srv].[vBackupSettings]asSELECT [DBID] ,DB_Name([DBID]) som [DBName] ,[FullPathBackup] ,[DiffPathInBackup]CDBackup,[UTBackup] ] FRÅN [srv].[BackupSettings];GO

Denna representation låter dig effektivt kontrollera vilka databaser som deltar i säkerhetskopieringsprocessen.

Låt oss nu skapa en representation som visar databasfilinformation från sys.master_files-systemrepresentationen:

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE visa [inf].[ServerDBFileInfo] asSELECT @@Servername AS Server , File_id ,--DB filidentifierare. Basvärdet för fil_id är 1 Typ_desc ,--Typ filbeskrivning Namn som [Filnamn] ,--DB logiskt filnamn LEFT(Fysiskt_Namn, 1) AS Drive ,--Enhetsflagga för DB-filplatsen Physical_Name ,--Fullständig fil namn i OS HÖGER(fysiskt_namn, 3) AS Ext ,--Fitillägg Storlek som CountPage, --Aktuell filstorlek i 8Kb sidor runt ((cast(Size*8 som float))/1024,3) som SizeMb, - -Filstorlek i Mb round((cast(Size*8 som float))/1024/1024,3) som SizeGb, --Filstorlek i Gb fall när is_percent_growth=0 sedan Tillväxt*8 annars slutar 0 som Growth, -- Filtillväxt i 8Kb sidor fall när is_percent_growth=0 sedan round((cast(Growth*8 as float))/1024,3) slut som GrowthMb, --Filtillväxt i Mb fall när is_percent_growth=0 sedan round((cast(Growth) *8 som float))/1024/1024,3) slutar som GrowthGb, --Filtillväxt i Gb-fallet när is_percent_growth=1 sedan Growth else 0 slutar som GrowthPercent, --Filtillväxt i procent is_percent_growth, --Procent growth attribut database_id , DB_ Namn(database_id) som [DB_Name], State,--File state state_desc as StateDesc,--File state description is_media_read_only as IsMediaReadOnly,--Filen finns på enheten som skrivskyddad (0 - och för skrivning) is_read_only som IsReadOnly ,--filen är flaggad som skrivskyddad (0 - och för skrivning) is_sparse som IsSpace,--Sparse file is_name_reserved as IsNameReserved,--1 - Fjärrfilnamn, tillgänglig för användning. --Det är nödvändigt att skaffa en loggbackup innan du använder samma namn (namn eller fysiskt_namn-argument) igen för en ny fil --0 - Filnamn, otillgängligt för användning create_lsn som CreateLsn,--Transaktionsregistreringsnummer i loggen (LSN) som användes för att skapa filen drop_lsn som DropLsn,--LSN som användes för att radera filen read_only_lsn som ReadOnlyLsn,--LSN som användes av filgruppen som innehöll filen för att ändra typen "läs och skriv" till "läs -only" (den senaste ändringen) read_write_lsn som ReadWriteLsn,--LSN som användes av filgruppen som innehöll filen för att ändra typen "read-only" till "read and write" (den senaste ändringen) differential_base_lsn som DifferentialBaseLsn,- -En bas för differentiella säkerhetskopior. Dataomfattningar som ändrades efter LSN ingår i den differentiella säkerhetskopieringen. differential_base_guid som DifferentialBaseGuid,--Unik identifierare för bassäkerhetskopian som kommer att användas för att skapa en differentiell kopia. differential_base_time as DifferentialBaseTime,--Den tid som motsvarar differential_base_lsn redo_start_lsn som RedoStartLsn,--LSN som används för att bestämma starten av nästa redo --Är NULL, förutom de fall där tillstånd =RESTORING eller state =RECOVERY_PENDING redoguForid_Guido_Start -Unik identifierare för återställningsgaffelpunkten --first_fork_guid-argumentvärdet för nästa återställda säkerhetskopia ska vara lika med detta värde redo_target_lsn som RedoTargetLsn,--LSN som fungerar som en stopppunkt för ett "online"-läge gör om i den här filen -- Är NULL, förutom de fall där tillstånd =ÅTERSTÄLLNING eller tillstånd =RECOVERY_PENDING redo_target_fork_guid som RedoTargetForkGuid, -- Återställningsgaffel där behållaren kan återställas. Används tillsammans med redo_target_lsn backup_lsn som BackupLsn--LSN av de senaste data eller filens differentiella backup copyFROM sys.master_files--database_files;GO

För att skapa fullständiga säkerhetskopior, låt oss implementera följande lagrade procedur:

[expand title =”Kod "]

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDUR [srv].[RunFullBackupDB] @ClearLog bit=1 --specificerar om transaktionsloggstorleken ska reducerasASBEGIN /* Skapa en fullständig DB-säkerhetskopia och kontrollera DB:s integritet i förväg */ STÄLL IN NOCOUNT PÅ; deklarera @dt datetime=getdate(); deklarera @år int=ÅR(@dt); deklarera @month int=MONTH(@dt); deklarera @dag int=DAG(@dt); deklarera @hour int=DatePart(timme, @dt); deklarera @minute int=DatePart(minut, @dt); deklarera @second int=DatePart(andra, @dt); deklarera @pathBackup nvarchar(255); deklarera @pathstr nvarchar(255); deklarera @DBName nvarchar(255); deklarera @backupName nvarchar(255); deklarera @sql nvarchar(max); deklarera @backupSetId som int; deklarera @FileNameLog nvarchar(255); deklarera @tbllog-tabell( [DBName] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); deklarera @tbl-tabell ([DBName] [nvarchar](255) NOT NULL, [FullPathBackup] [nvarchar](255) NOT NULL); --Hämtar DB-namn och fullständiga sökvägar för att skapa fullständiga säkerhetskopior, infoga i @tbl ( [DBName] ,[FullPathBackup] ) välj DB_NAME([DBID]),[FullPathBackup] från [srv].[BackupSettings]; --Hämta DB-namnet och namnen på motsvarande transaktionsloggar (eftersom en DB kan ha flera loggar) infoga i @tbllog([DBName], [FileNameLog]) välj t.[DBName], tt.[FileName] som [FileNameLog] ] från @tbl som t inre join [inf].[ServerDBFileInfo] som tt på t.[DBName]=DB_NAME(tt.[database_id]) där tt.[Type_desc]='LOG'; -- sekventiell bearbetning av var och en av de DB:er vi fick tidigare while(exists(select top(1) 1 from @tbl)) start set @backupSetId=NULL; välj top(1) @DBName=[DBName], @pathBackup=[FullPathBackup] från @tbl; ställ in @[email protected]+N'_Full_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))--+N'_' --+cast(@hour as nvarchar(255))+N'_'+cast(@minute as nvarchar(255))+N'_'+cast(@ andra som nvarchar(255)); set @[email protected]@sqldat.com+N'.bak'; --kontrollerar DB:n för integritetsuppsättning @sql=N'DBCC CHECKDB(N'+N''''[email protected]+N''''+N') WITH NO_INFOMSGS'; exec(@sql); --exekvera proceduren för att skapa en säkerhetskopia 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); --kontrollera säkerhetskopian vi skapade välj @backupSetId =position från msdb..backupset där [email protected] och backup_set_id=(välj max(backup_set_id) från msdb..backupset där [email protected]); set @sql=N'Verifieringsfel. Säkerhetskopieringsinformation för databasen "'[email protected]+'" hittades inte.'; om @backupSetId är null start raiserror(@sql, 16, 1) end else start set @sql=N'RESTORE VERIFIYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId som nvarchar(255)); exec(@sql); end --komprimering av DB-transaktionsloggarna if(@ClearLog=1) start while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) start select top(1) @FileNameLog=FileNameLog från @tbllog där [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N', 0 , TRUNCATEONLY)'; exec(@sql); radera från @tbllog där [email protected] och [email protected]; end end delete från @tbl där [DBName][email protected]; endENDGO

[/expand]

Enligt koden kan vi se att denna procedur ger en lösning för de återstående stegen i algoritmen för att skapa säkerhetskopior.

Procedurer som skapar differential- och transaktionsloggkopior implementeras på liknande sätt:

[expand title =”Kod "]

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDUR [srv].[RunDiffBackupDB] @ClearLog bit=1 --specificerar om transaktionsloggens storlek ska reducerasASBEGIN /* Skapa en differentiell DB-säkerhetskopia ON; deklarera @dt datetime=getdate(); deklarera @år int=ÅR(@dt); deklarera @month int=MONTH(@dt); deklarera @dag int=DAG(@dt); deklarera @hour int=DatePart(timme, @dt); deklarera @minute int=DatePart(minut, @dt); deklarera @second int=DatePart(andra, @dt); deklarera @pathBackup nvarchar(255); deklarera @pathstr nvarchar(255); deklarera @DBName nvarchar(255); deklarera @backupName nvarchar(255); deklarera @sql nvarchar(max); deklarera @backupSetId som int; deklarera @FileNameLog nvarchar(255); deklarera @tbl-tabell ([DBName] [nvarchar](255) NOT NULL, [DiffPathBackup] [nvarchar](255) NOT NULL ); deklarera @tbllog-tabell( [DBName] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); --Hämta DB-namnet och fullständiga sökvägar för att skapa differentiella säkerhetskopior, infoga i @tbl ( [DBName] ,[DiffPathBackup] ) välj DB_NAME([DBID]),[DiffPathBackup] från [srv].[BackupSettings] där [DiffPathBackup] är inte null; --Hämta DB-namn och de fullständiga namnen på de transaktionsloggfiler som följer (eftersom en DB kan ha flera loggar) infoga i @tbllog([DBName], [FileNameLog]) välj t.[DBName], tt.[Filnamn] som [FileNameLog] från @tbl som t inre join [inf].[ServerDBFileInfo] som tt på t.[DBName]=DB_NAME(tt.[database_id]) där tt.[Type_desc]='LOG'; -- sekventiell bearbetning av var och en av de DB:er vi fick tidigare while(exists(select top(1) 1 from @tbl)) start set @backupSetId=NULL; välj top(1) @DBName=[DBName], @pathBackup=[DiffPathBackup] från @tbl; ställ in @[email protected]+N'_Diff_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))+N'_' +cast(@hour as nvarchar(255))+N'_'+cast(@minute as nvarchar(255))+N'_'+cast(@second as nvarchar( 255)); set @[email protected]@sqldat.com+N'.bak'; --kontrollerar DB:n för integritetsuppsättning @sql=N'DBCC CHECKDB(N'+N''''[email protected]+N''''+N') WITH NO_INFOMSGS'; exec(@sql); --exekvera säkerhetskopieringsproceduren set @sql=N'BACKUP DATABASE ['[email protected]+N'] TO DISK =N'+N''''[email protected]+N''''+ N' WITH DIFFERENTIAL, NOFORMAT, NOINIT, NAME =N'+N''''[email protected]+N''''+ N', CHECKSUM, STOP_ON_ERROR, SKIP, REWIND, COMPRESSION, STATS =10;'; exec(@sql); --kontrollera säkerhetskopian vi just skapade välj @backupSetId =position från msdb..backupset där [email protected] och backup_set_id=(välj max(backup_set_id) från msdb..backupset där [email protected]); set @sql=N'Verifieringsfel. Säkerhetskopieringsinformation för databasen "'[email protected]+'" hittades inte.'; om @backupSetId är null start raiserror(@sql, 16, 1) end else start set @sql=N'RESTORE VERIFIYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId som nvarchar(255)); exec(@sql); end --komprimering av DB-transaktionsloggarna if(@ClearLog=1) start while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) start select top(1) @FileNameLog=FileNameLog från @tbllog där [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N', 0 , TRUNCATEONLY)'; exec(@sql); radera från @tbllog där [email protected] och [email protected]; end end delete från @tbl där [DBName][email protected]; endENDGO

[/expand]

Eftersom det tar mycket resurser att kontrollera databaser för integritet, kan vi utelämna det när vi skapar en differentiell säkerhetskopia.

[expand title =”Kod "]

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDUR [srv].[RunLogBackupDB] @ClearLog bit=1 --specificerar om transaktionsloggens storlek ska reducerasASBEGIN /* Säkerhetskopiera DB-transaktionslogg PÅ */ SET NOCOUNT ON; deklarera @dt datetime=getdate(); deklarera @år int=ÅR(@dt); deklarera @month int=MONTH(@dt); deklarera @dag int=DAG(@dt); deklarera @hour int=DatePart(timme, @dt); deklarera @minute int=DatePart(minut, @dt); deklarera @second int=DatePart(andra, @dt); deklarera @pathBackup nvarchar(255); deklarera @pathstr nvarchar(255); deklarera @DBName nvarchar(255); deklarera @backupName nvarchar(255); deklarera @sql nvarchar(max); deklarera @backupSetId som int; deklarera @FileNameLog nvarchar(255); deklarera @tbl-tabell ([DBName] [nvarchar](255) NOT NULL, [LogPathBackup] [nvarchar](255) NOT NULL); deklarera @tbllog-tabell( [DBName] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); --Hämta DB-namn och fullständiga sökvägar för att skapa säkerhetskopior av transaktionsloggar med en icke-enkel återställningsmodell (fullständig eller bulkloggad). System-DB:er är också uteslutna infoga i @tbl ( [DBName] ,[LogPathBackup] ) välj DB_NAME(b.[DBID]), b.[LogPathBackup] från [srv].[BackupSettings] som b inre join sys.databases as d på b.[DBID]=d.[database_id] där d.recovery_model<3 och DB_NAME([DBID]) inte finns i ( N'master', N'tempdb', N'model', N'msdb', N' ReportServer', N'ReportServerTempDB' ) och [LogPathBackup] är inte null; --Hämta DB-namn och de fullständiga namnen på de transaktionsloggfiler som följer (eftersom en DB kan ha flera loggar) infoga i @tbllog([DBName], [FileNameLog]) välj t.[DBName], tt.[Filnamn] som [FileNameLog] från @tbl som t inre join [inf].[ServerDBFileInfo] som tt på t.[DBName]=DB_NAME(tt.[database_id]) där tt.[Type_desc]='LOG'; -- sekventiell bearbetning av var och en av de DB:er vi fick tidigare while(exists(select top(1) 1 from @tbl)) start set @backupSetId=NULL; välj top(1) @DBName=[DBName], @pathBackup=[LogPathBackup] från @tbl; ställ in @[email protected]+N'_Log_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))+N'_' +cast(@hour as nvarchar(255))+N'_'+cast(@minute as nvarchar(255))+N'_'+cast(@second as nvarchar( 255)); set @[email protected]@sqldat.com+N'.trn'; --exekvera säkerhetskopieringsproceduren set @sql=N'BACKUP LOG ['[email protected]+N'] TO DISK =N'+N''''[email protected]+N''''+ N' MED NOFORMAT, NOINIT, NAMN =N'+N''''[email protected]+N''''+ N', CHECKSUM, STOP_ON_ERROR, SKIP, SPOLA BAKÅT, KOMPRESSION, STATISTIK =10;'; exec(@sql); --Kontrollera transaktionsloggen säkerhetskopia vi just skapade välj @backupSetId =position från msdb..backupset där [email protected] och backup_set_id=(välj max(backup_set_id) från msdb..backupset där [email protected]); set @sql=N'Verifieringsfel. Säkerhetskopieringsinformation för databasen "'[email protected]+'" hittades inte.'; om @backupSetId är null start raiserror(@sql, 16, 1) end else start set @sql=N'RESTORE VERIFIYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId som nvarchar(255)); exec(@sql); end --komprimering av DB-transaktionsloggarna if(@ClearLog=1) start while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) start select top(1) @FileNameLog=FileNameLog från @tbllog där [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N', 0 , TRUNCATEONLY)'; exec(@sql); radera från @tbllog där [email protected] och [email protected]; end end delete från @tbl där [DBName][email protected]; endENDGO

[/expand]

Som nämnts ovan är det en resurstung uppgift att kontrollera databaser för integritet. I kombination med det faktum att säkerhetskopior av transaktionslogg vanligtvis måste skapas ganska ofta, ger detta oss en anledning att utelämna integritetskontroll när vi skapar en transaktionsloggkopia.

Tänk också på att fullständiga säkerhetskopior av "master", "msdb" och "model" databaser måste göras med jämna mellanrum.

För att automatisera processen för att skapa säkerhetskopior behöver du bara ringa de tidigare implementerade procedurerna till Windows Task Scheduler, agentjobb eller någon liknande tillgänglig tjänst.

Du måste ställa in samtalsfrekvensen för var och en av dessa procedurer individuellt baserat på belastningstoppar, aktivitetsplatåer etc.

Det grundläggande tillvägagångssättet är följande:

1) Skapa en fullständig säkerhetskopia en gång om dagen
2) Skapa differentiella säkerhetskopior var 2-4:e timme
3) Skapa säkerhetskopior av transaktionslogg var 5-60:e minut

Kom ihåg att databaser vanligtvis deltar i det felsäkra och snabba åtkomstsystemet. Och om den senare använder säkerhetskopior av transaktionsloggar är det ytterst viktigt att inte störa proceduren. Mer specifikt innebär detta att transaktionsloggkopior inte ska skapas av flera olika processer – om detta händer kommer säkerhetskopieringssekvensen från dessa kopior att gå förlorad.

Här har vi sett exempel på att varje databas bearbetas sekventiellt, en i taget. Däremot kan vi åstadkomma parallell bearbetning i produktionsmiljön – vilket gör att flera säkerhetskopior kan göras samtidigt. Detta kan närma sig på några olika sätt. Till exempel genom att anropa följande lagrade procedur:

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [inf].[RunAsyncExecute]( @sql nvarchar(max), @jobname nvarchar(57) =null, @database nvarchar(128)=nullvar(owner) 128) =null)SOM BÖRJAN/* Asynkron paketexekvering via Agentens jobb RunAsyncExecute - asynkron exekvering av T-SQL-kommando eller lagrad prodecure 2012 Antonin Foller, Motobit Software, www.motobit.com http://www.motobit.com/ tips/detpg_async-execute-sql/ */ STÄLL IN NOCOUNT PÅ; deklarera @id unikidentifierare; --Skapa ett unikt jobbnamn om namnet inte är specificerat om (@jobname är null) set @jobname=''; set @jobname =@jobname + '_async_' + convert(varchar(64),NEWID()); if (@owner är null) ställ in @owner ='sa'; --Skapa ett nytt jobb, få jobb-ID exekvera msdb..sp_add_job @jobname, @[email protected], @[email protected] OUTPUT; --Specificera en jobbserver för jobbet exekvera msdb..sp_add_jobserver @[email protected]; --Specificera ett första steg i jobbet - SQL-kommandot --(@on_success_action =3 ... Gå till nästa steg) exekvera msdb..sp_add_jobstep @[email protected], @step_name='Steg1', @command =@sql, @database_name =@databas, @on_success_action =3; --Specificera nästa steg i jobbet - ta bort jobbdeklarationen @deletecommand varchar(200); set @deletecommand ='kör msdb..sp_delete_job @job_name='''[email protected]+''''; kör msdb..sp_add_jobstep @[email protected], @step_name='Steg2', @command =@deletecommand; --Starta jobbet exekvera msdb..sp_start_job @[email protected]; END GO

Här uppnås asynkroni genom att dynamiskt skapa agentjobben, exekvera och ta bort dem efteråt.

Låt oss nu titta på den allmänna algoritmen för att återställa databaser från säkerhetskopior som tidigare skapats i en annan/testmiljö:

1) Definiera vilka databaser som ska återställas och platsen för deras säkerhetskopior
2) Återställa databaserna
3) Kontrollera de återställda databaserna för integritet

Nu ska vi titta på en implementering av en algoritm som återställer en databas från en fullständig säkerhetskopia. För en differentiell kopia är proceduren liknande – den enda skillnaden är att en fullständig säkerhetskopia måste återställas i första hand, följt av den differentiella kopian.

För att definiera vilka databaser som ska återställas, samt platsen för deras säkerhetskopior, låt oss skapa två tabeller som visas nedan:

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[RestoreSettings]( [DBName] [nvarchar](255) NOT NULL, [FullPathRestore] [nvarchar](255) [DiffPcharathRestore, [ ](255) NOT NULL, [LogPathRestore] [nvarchar](255) NOT NULL, [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_RestoreSettings] PRIMÄRNYCKEL KLUSTERAD ( [DBName] ASC) MED (PAD_INDEX =AV, STORECOMIST , IGNORE_DUP_KEY =AV, ALLOW_ROW_LOCKS =PÅ, ALLOW_PAGE_LOCKS =PÅ) PÅ [PRIMÄR]) PÅ [PRIMÄR];GOALTER TABLE [srv].[RestoreSettings] LÄGG TILL BEGRÄNSNING [DF_RestoreSettings_InsertGO] (FÖRSÄTTA]InsertGO())s; /pre> 

Här är syftet med kolumnerna analogt med dem från tabellen [srv].[BackupSettings]. Den enda skillnaden är att den fullständiga sökvägen kommer att användas för att hitta säkerhetskopiorna för återställning, och inte för att skapa nya.

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[RestoreSettingsDetail]( [Row_GUID] [uniqueidentifier] INTE NULL, [DBName] [nvarchar](255) NOT NULL](] [5PathcharRestore] [5Path ) NOT NULL, TargetPathRestore [nvarchar](255) NOT NULL, [Ext] [nvarchar](255) NOT NULL, [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_RestoreSettingsDetail] PRIMÄRNYCKEL CLUSTERED ( [Row)WITH] ( A PAD_INDEX =AV, STATISTICS_NORECOMPUTE =AV, IGNORE_DUP_KEY =AV, ALLOW_ROW_LOCKS =PÅ, ALLOW_PAGE_LOCKS =PÅ) PÅ [PRIMÄR]) PÅ [PRIMÄR];GOALTER TABLE [srv].[Seint]_Återställ DETALJER DETALJER [DETALJER]. FÖR [Row_GUID];GOALTER TABLE [srv].[RestoreSettingsDetail] LÄGG TILL BEGRÄNSNING [DF_RestoreSettingsDetail_InsertUTCDate] DEFAULT (getutcdate()) FÖR [InsertUTCDate];GO

Den här tabellen behövs för att definiera de fullständiga filnamnen för databasen som återställs, som sedan används för vidare överföring (till exempel [SourcePathRestore]='Logiskt filnamn' och [TargetPathRestore]='disk:\...\Fysiskt filnamn ', medan [Ext]='Filtillägg')

Egentligen kan vi definiera logiska namn på databasfilerna med hjälp av följande fråga:

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

Att få information om säkerhetskopior som finns i en fil kan göras på detta sätt:

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

Därefter har vi en implementering av en lagrad procedur som används för att återställa en databas från en fullständig säkerhetskopia och kontrollera den för dataintegritet:

[expand title =”Kod "]

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDUR [srv].[RunFullRestoreDB]ASBEGIN /* Återställer en DB från en fullständig säkerhetskopia och kontrollerar DB:n för integritet */ SET NOCOUNT ON; deklarera @dt datetime=DateAdd(dag,-2,getdate()); deklarera @år int=ÅR(@dt); deklarera @month int=MONTH(@dt); deklarera @dag int=DAG(@dt); deklarera @hour int=DatePart(timme, @dt); deklarera @minute int=DatePart(minut, @dt); deklarera @second int=DatePart(andra, @dt); deklarera @pathBackup nvarchar(255); deklarera @pathstr nvarchar(255); deklarera @DBName nvarchar(255); deklarera @backupName nvarchar(255); deklarera @sql nvarchar(max); deklarera @backupSetId som int; deklarera @FileNameLog nvarchar(255); deklarera @SourcePathRestore nvarchar(255); deklarera @TargetPathRestore nvarchar(255); deklarera @Ext nvarchar(255); deklarera @tbl-tabell ([DBName] [nvarchar](255) NOT NULL, [FullPathRestore] [nvarchar](255) NOT NULL); deklarera @tbl_files tabell ( [DBName] [nvarchar](255) NOT NULL, [SourcePathRestore] [nvarchar](255) NOT NULL, [TargetPathRestore] [nvarchar](255) NOT NULL, [Ext] [nvarchar](255) INTE NULL ); --hämta en lista med DB-namn och sökvägarna till fullständiga säkerhetskopior, infoga i @tbl ( [DBName], [FullPathRestore] ) välj [DBName], [FullPathRestore] från [srv].[RestoreSettings]; --hämta detaljerad information om de nya DB-filernas plats infoga i @tbl_files ([DBName],[SourcePathRestore],[TargetPathRestore],[Ext] ) välj [DBName],[SourcePathRestore],[TargetPathRestore] ,[Ext] från [ srv].[RestoreSettingsDetail]; --bearbetar var och en av de DB:er vi fick tidigare while(exists(select top(1) 1 from @tbl)) start set @backupSetId=NULL; välj top(1) @DBName=[DBName], @pathBackup=[FullPathRestore] från @tbl; ställ in @[email protected]+N'_Full_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))--+N'_' --+cast(@hour as nvarchar(255))+N'_'+cast(@minute as nvarchar(255))+N'_'+cast(@ andra som nvarchar(255)); set @[email protected]@sqldat.com+N'.bak'; --skapa en säkerhetskopieringsfråga och köra den set @sql=N'RESTORE DATABASE ['[email protected]+N'_Restore] FROM DISK =N'+N''''[email protected]+N''' '+ N' MED FIL =1,'; while(exists(select top(1) 1 from @tbl_files where [DBName][email protected])) start select top(1) @SourcePathRestore=[SourcePathRestore], @TargetPathRestore=[TargetPathRestore], @Ext=[Ext] från @tbl_files där [DBName][email protected]; set @[email protected]+N' MOVE N'+N''''[email protected]+N''''+N' TO N'+N''''[email protected]+N' _Restore.'[email protected]+N''''+N','; radera från @tbl_files där [DBName][email protected] och [SourcePathRestore][email protected] och [Ext][email protected]; slutuppsättning @[email protected]+N' NOUNLOAD, REPLACE, STATS =5'; exec(@sql); --kontrollerar DB:n för integritetsuppsättning @sql=N'DBCC CHECKDB(N'+N''''[email protected]+'_Restore'+N''''+N') WITH NO_INFOMSGS'; exec(@sql); radera från @tbl där [DBName][email protected]; endEND

[/expand]

För att ange vilken fullständig säkerhetskopia som ska användas för återställning, används ett speciellt strukturerat filnamn:

_Full_backup___.bak

För att automatisera denna databasåterställningsprocess bör anropet av den lagrade proceduren vi implementerade placeras i Windows Task Scheduler, Agent-jobb eller någon liknande tillgänglig tjänst.

Du kan se de senaste säkerhetskopiorna av databasen med följande representation:

ANVÄND [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE VIEW [inf].[vServerLastBackupDB] aswith backup_cte as( välj bs.[database_name], backup_type =case bs.[typ] när 'D' sedan 'databas' när 'L ' sedan 'logga' när 'jag' sedan 'differential' annars 'other' end, bs.[first_lsn], bs.[last_lsn], bs.[backup_start_date], bs.[backup_finish_date], cast(bs.[backup_size] som decimal(18,3))/1024/1024 som BackupSizeMb, rownum =row_number() över ( partition av bs.[database_name], skriv ordning efter bs.[backup_finish_date] desc ), LogicalDeviceName =bmf.[logical_device_name], Physical_Device_Name =bmf.[physical_device_name], bs.[server_name], bs.[user_name] FRÅN msdb.dbo.backupset bs INNER JOIN msdb.dbo.backupmediafamily bmf PÅ [bs].[media_set_id] =[bmf].[media_set_id]) välj [server_name] som [ServerName], [database_name] som [DBName], [user_name] som [UserName], [backup_type] som [BackupType], [backup_start_date] som [BackupStartDate], [backup_finish_date] som [BackupFinishDate], [BackupSizeMb], -- okomprimerad storlek [LogicalDeviceName], [PhysicalDeviceName], [first_lsn] som [FirstLSN], [last_lsn] som [LastLSN]från backup_ctewhere rownum =1;

Resultatet

I den här guiden har vi tittat på en implementering av en automatiserad säkerhetskopieringsprocess på en server och efterföljande återställning på en annan (till exempel en testserver).

Denna metod låter oss automatisera processen för att skapa säkerhetskopior, kontrollera säkerhetskopiorna genom att återställa dem och finjustera processerna som visas ovan.

Källor:

Säkerhetskopiering
Återställ
Säkerhetskopiering
KONTROLLDBAR
SHRINKFILE
sys.master_files


  1. Optimeringströsklar – gruppering och aggregering av data, del 3

  2. TreeView ImageCombo rullgardinsmeny

  3. Använda Oracle JDeveloper med MySQL Database Service på Oracle Cloud Platform, del 2

  4. Hur man säkerhetskopierar eller skapar en ny tabell från befintlig SQL Server-tabell i SQL Server - SQL Server / TSQL Tutorial Del 105