sql >> Database teknologi >  >> RDS >> Database

Implementering af automatiseret databasebackup og gendannelse med standardmidler

Introduktion

Du kan finde en masse guider til, hvordan du sikkerhedskopierer og gendanner databaser. I denne vil vi vise, hvordan dette kan gøres ved hjælp af standard MS SQL Server-midler.

Dette eksempel vil dække en række tilgange – fra kontrol af databasens integritet før sikkerhedskopiering til gendannelse af databasen fra en tidligere oprettet sikkerhedskopi.

Løsningen

Lad os først se på den overordnede algoritme, vi vil bruge til at sikkerhedskopiere en database:

1) Definition af hvilke databaser der skal sikkerhedskopieres
2) Kontrol af integriteten af ​​de valgte databaser
3) Oprettelse af en sikkerhedskopi (fuld, differentiel eller transaktionslogkopi) for hver af de valgte databaser
4) Kontrol af de oprettede sikkerhedskopier
5) Komprimering af transaktionsloggene (hvis nødvendigt)

Nedenfor kan du finde et implementeringseksempel på denne algoritme.

For at definere, hvilke databaser der skal sikkerhedskopieres, opretter vi følgende tabel:

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[BackupSettings]( [DBID] [int] NOT NULL, [FullPathBackup] [nvarchar](255) NOT NULL, [DiffPath ) NULL, [LogPathBackup] [nvarchar](255) NULL, [InsertUTCDate] [datetime] IKKE NULL, BEGRÆNSNING [PK_BackupSettings] PRIMÆR NØGLE KLUSTERET ( [DBID] ASC) MED (PAD_INDEX =OFF, STATISTICS_D, OFF, STATISTICS_D, IGNPUTE_N ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY];GOALTER TABEL [srv].[BackupSettings] TILFØJ BEGRÆNSNING [DF_BackupSettings_InsertUTCDate] DEFAULT (getutcdate;sertUT) FOR 

Database-id'et er placeret i den første kolonne, 'FullPathBackup' indeholder stien til oprettelse af fuld sikkerhedskopi (f.eks. 'disk:\...\'), og DiffPathBackup og LogPathBackup indeholder fulde stier til oprettelse af differential- og transaktionslogkopier henholdsvis. Hvis kolonnerne DiffPathBackup eller LogPathBackup er tomme, vil differential- og/eller transaktionslogkopi for denne database ikke blive oprettet.

Vi kan også oprette en repræsentation baseret på denne tabel:

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE visning [srv].[vBackupSettings]asSELECT [DBID] ,DB_Name([DBID]) som [DBName] ,[FullPathBackup] ,[DiffPathInBackup]CD-Backup,[UTBackup] ] FRA [srv].[BackupSettings];GO

Denne repræsentation giver dig mulighed for effektivt at kontrollere, hvilke databaser der deltager i backup-processen.

Lad os nu oprette en repræsentation, der viser databasefiloplysninger fra sys.master_files-systemrepræsentationen:

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE visning [inf].[ServerDBFileInfo] asSELECT @@Servername AS Server , File_id ,--DB fil-id. Grundværdien for fil_id er 1 Type_desc ,--Type filbeskrivelse Navn som [Filnavn] ,--DB logisk filnavn LEFT(Fysisk_Navn, 1) AS Drev ,--Drevflag for DB-filens placering Physical_Name ,--Fuld fil navn i OS HØJRE(fysisk_navn, 3) AS Ext ,--Filutvidelse Størrelse som CountPage, --Aktuel filstørrelse i 8Kb sider runde((cast(Størrelse*8 som float))/1024,3) som SizeMb, - -Filstørrelse i Mb-runde((cast(Størrelse*8 som float))/1024/1024,3) som SizeGb, --Filstørrelse i Gb-tilfælde, når is_percent_growth=0 derefter Vækst*8 ellers 0 slutter som Vækst, -- Filvækst i 8Kb siders tilfælde, når is_percent_growth=0 derefter rund((cast(Growth*8 as float))/1024,3) slutter som GrowthMb, --Filvækst i Mb tilfælde, når is_percent_growth=0 derefter round((cast(Growth) *8 som float))/1024/1024,3) slutter som GrowthGb, --Filvækst i Gb-tilfælde, når is_percent_growth=1 derefter Growth else 0 slutter som GrowthPercent, --Filvækst i procent is_percent_growth, --Procent growth-attribut database_id , DB_ Navn(database_id) som [DB_Name], State,--File state state_desc as StateDesc,--File state description is_media_read_only as IsMediaReadOnly,--Filen er placeret på drevet som skrivebeskyttet (0 - og til skrivning) is_read_only som IsReadOnly ,--fil er markeret som skrivebeskyttet (0 - og til skrivning) is_sparse som IsSpace,--Sparse fil is_name_reserved as IsNameReserved,--1 - Fjernfilnavn, tilgængelig til brug. --Det er nødvendigt at få en log-backup, før du bruger det samme navn (navn eller fysisk_navn-argumenter) igen til en ny fil --0 - Filnavn, utilgængeligt til brug create_lsn som CreateLsn,--Transaktionsregistreringsnummer i loggen (LSN) som blev brugt til at oprette filen drop_lsn som DropLsn,--LSN som blev brugt til at slette filen read_only_lsn som ReadOnlyLsn,--LSN som blev brugt af filgruppen, der indeholdt filen til at ændre "read and write"-typen til "read -only" (den seneste ændring) read_write_lsn som ReadWriteLsn,--LSN som blev brugt af filgruppen, der indeholdt filen til at ændre "read-only" typen til "read and write" (den seneste ændring) differential_base_lsn som DifferentialBaseLsn,- -En base for differentielle sikkerhedskopier. Dataomfang, som blev ændret efter LSN, er inkluderet i den differentielle backup. differential_base_guid som DifferentialBaseGuid,--Unik identifikator for den grundlæggende sikkerhedskopi, som vil blive brugt til at oprette en differentiel kopi. differential_base_time as DifferentialBaseTime,--Den tid, der svarer til differential_base_lsn redo_start_lsn som RedoStartLsn,--LSN bruges til at bestemme starten på næste redo --Er NULL, undtagen i de tilfælde hvor tilstand =RESTORING eller state =RECOVERY_PENDING redoguForid_Guido_Start -Unik identifikator for gendannelsesgaffelpunktet --first_fork_guid-argumentværdien for den næste gendannede sikkerhedskopi skal være lig med denne værdi redo_target_lsn som RedoTargetLsn,--LSN, der fungerer som et stoppunkt for en "online"-mode om i denne fil -- Er NULL, bortset fra de tilfælde, hvor tilstand =RESTORING eller tilstand =RECOVERY_PENDING redo_target_fork_guid som RedoTargetForkGuid,--Restoration fork, hvorpå beholderen kan gendannes. Bruges sammen med redo_target_lsn backup_lsn som BackupLsn--LSN af de seneste data eller filens differentielle backup copyFROM sys.master_files--database_files;GO

For at oprette fulde sikkerhedskopier, lad os implementere følgende lagrede procedure:

[expand title =”Kode “]

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunFullBackupDB] @ClearLog bit=1 --specificerer om transaktionslogstørrelsen skal reduceresASBEGIN /* Oprettelse af en fuld DB-sikkerhedskopi og kontrol af DB'en for integritet på forhånd */ SÆT ANTAL TIL; erklær @dt datetime=getdate(); erklær @år int=ÅR(@dt); erklær @month int=MONTH(@dt); erklær @dag int=DAG(@dt); erklære @hour int=DatoPart(time, @dt); erklær @minut int=DatoPart(minut, @dt); erklære @second int=DatePart(second, @dt); erklære @pathBackup nvarchar(255); erklære @pathstr nvarchar(255); erklære @DBName nvarchar(255); erklær @backupName nvarchar(255); erklære @sql nvarchar(max); erklære @backupSetId som int; erklære @FileNameLog nvarchar(255); erklær @tbllog tabel( [DBNavn] [nvarchar](255) IKKE NULL, [FilnavnLog] [nvarchar](255) IKKE NULL ); erklær @tbl tabel ([DBName] [nvarchar](255) NOT NULL, [FullPathBackup] [nvarchar](255) NOT NULL); --Henter DB-navn og fulde stier til oprettelse af fuld sikkerhedskopi, indsæt i @tbl ( [DBName], [FullPathBackup] ) vælg DB_NAME([DBID]), [FullPathBackup] fra [srv].[BackupSettings]; --Hentning af DB-navnet og navnene på de tilsvarende transaktionslogfiler (da en DB kan have flere logfiler), indsæt i @tbllog([DBNavn], [FilnavnLog]) vælg t.[DBNavn], tt.[Filnavn] som [FilnavnLog] ] fra @tbl som t indre join [inf].[ServerDBFileInfo] som tt på t.[DBName]=DB_NAME(tt.[database_id]) hvor tt.[Type_desc]='LOG'; -- sekventiel behandling af hver af de DB'er, vi fik tidligere, mens (eksisterer (vælg top(1) 1 fra @tbl)) startsæt @backupSetId=NULL; vælg top(1) @DBName=[DBName], @pathBackup=[FullPathBackup] fra @tbl; sæt @[email protected]+N'_Full_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))--+N'_' --+cast(@time som nvarchar(255))+N'_'+cast(@minut som nvarchar(255))+N'_'+cast(@ anden som nvarchar(255)); set @[email protected]@sqldat.com+N'.bak'; --kontrol af DB'en for integritetssæt @sql=N'DBCC CHECKDB(N'+N''''[email protected]+N''''+N') MED NO_INFOMSGS'; exec(@sql); --udførelse af proceduren for oprettelse af sikkerhedskopi sat @sql=N'BACKUP DATABASE ['[email protected]+N'] TO DISK =N'+N''''[email protected]+N''''+ N' MED NOFORMAT, NOINIT, NAME =N'+N''''[email protected]+N''''+ N', CHECKSUM, STOP_ON_ERROR, SKIP, SPOLD TILBAGE, KOMPRESSION, STATISTIK =10;'; exec(@sql); --kontrol af sikkerhedskopien, vi oprettede, vælg @backupSetId =position fra msdb..backupset hvor [email protected] og backup_set_id=(vælg max(backup_set_id) fra msdb..backupset hvor [email protected]); set @sql=N'Verifikationsfejl. Sikkerhedskopieringsoplysninger for "'[email protected]+'"-databasen blev ikke fundet.'; hvis @backupSetId er null start raiserror(@sql, 16, 1) end else start set @sql=N'RESTORE VERIFYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId som nvarchar(255)); exec(@sql); end -- at komprimere DB-transaktionslogfilerne if(@ClearLog=1) start while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) start select top(1) @FileNameLog=FileNameLog fra @tbllog hvor [email protected]; sæt @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N', 0 , TRUNCATEONLY)'; exec(@sql); slet fra @tbllog hvor [email protected] og [email protected]; slut slut slet fra @tbl hvor [DBName][email protected]; endENDGO

[/udvid]

Ifølge koden kan vi se, at denne procedure giver en løsning på de resterende trin i algoritmen til oprettelse af sikkerhedskopier.

Procedurer, der opretter differential- og transaktionslogkopier, implementeres på lignende måde:

[expand title =”Kode “]

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunDiffBackupDB] @ClearLog bit=1 --specificerer om transaktionslogstørrelsen skal reduceresASBEGIN /* Oprettelse af en differentiel DB-sikkerhedskopi ON; erklær @dt datetime=getdate(); erklær @år int=ÅR(@dt); erklær @month int=MONTH(@dt); erklær @dag int=DAG(@dt); erklære @hour int=DatoPart(time, @dt); erklær @minut int=DatoPart(minut, @dt); erklære @second int=DatePart(second, @dt); erklære @pathBackup nvarchar(255); erklære @pathstr nvarchar(255); erklære @DBName nvarchar(255); erklær @backupName nvarchar(255); erklære @sql nvarchar(max); erklære @backupSetId som int; erklære @FileNameLog nvarchar(255); erklær @tbl tabel ([DBName] [nvarchar](255) NOT NULL, [DiffPathBackup] [nvarchar](255) NOT NULL); erklær @tbllog tabel( [DBNavn] [nvarchar](255) IKKE NULL, [FilnavnLog] [nvarchar](255) IKKE NULL ); --Hentning af DB-navnet og de fulde stier til oprettelse af differentielle sikkerhedskopier, indsæt i @tbl ( [DBName] ,[DiffPathBackup] ) vælg DB_NAME([DBID]),[DiffPathBackup] fra [srv].[BackupSettings] hvor [DiffPathBackup] er ikke nul; --Hentning af DB-navn og de fulde navne på de tilsvarende transaktionslogfiler (da en DB kan have flere logfiler) indsæt i @tbllog([DBNavn], [FilnavnLog]) vælg t.[DBNavn], tt.[Filnavn] som [FileNameLog] fra @tbl som t indre join [inf].[ServerDBFileInfo] som tt på t.[DBName]=DB_NAME(tt.[database_id]) hvor tt.[Type_desc]='LOG'; -- sekventiel behandling af hver af de DB'er, vi fik tidligere, mens (eksisterer (vælg top(1) 1 fra @tbl)) startsæt @backupSetId=NULL; vælg top(1) @DBName=[DBName], @pathBackup=[DiffPathBackup] fra @tbl; sæt @[email protected]+N'_Diff_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))+N'_' +cast(@time som nvarchar(255))+N'_'+cast(@minut som nvarchar(255))+N'_'+cast(@second as nvarchar( 255)); set @[email protected]@sqldat.com+N'.bak'; --kontrol af DB'en for integritetssæt @sql=N'DBCC CHECKDB(N'+N''''[email protected]+N''''+N') MED NO_INFOMSGS'; exec(@sql); --udførelse af sikkerhedskopieringsproceduren sæt @sql=N'BACKUP DATABASE ['[email protected]+N'] TO DISK =N'+N''''[email protected]+N''''+ N' MED DIFFERENTIAL, NOFORMAT, NOINIT, NAME =N'+N''''[email protected]+N'''''+ N', CHECKSUM, STOP_ON_ERROR, SKIP, SPOLD TILBAKE, KOMPRESSION, STATISTIK =10;'; exec(@sql); --kontrol af den sikkerhedskopi, vi lige har oprettet, vælg @backupSetId =position fra msdb..backupset hvor [email protected] og backup_set_id=(vælg max(backup_set_id) fra msdb..backupset hvor [email protected]); set @sql=N'Verifikationsfejl. Sikkerhedskopieringsoplysninger for "'[email protected]+'"-databasen blev ikke fundet.'; hvis @backupSetId er null start raiserror(@sql, 16, 1) end else start set @sql=N'RESTORE VERIFYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId som nvarchar(255)); exec(@sql); end -- at komprimere DB-transaktionslogfilerne if(@ClearLog=1) start while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) start select top(1) @FileNameLog=FileNameLog fra @tbllog hvor [email protected]; sæt @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N', 0 , TRUNCATEONLY)'; exec(@sql); slet fra @tbllog hvor [email protected] og [email protected]; slut slut slet fra @tbl hvor [DBName][email protected]; endENDGO

[/udvid]

Da kontrol af databaser for integritet kræver mange ressourcer, kan vi udelade det, mens vi opretter en differentiel sikkerhedskopi.

[expand title =”Kode “]

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunLogBackupDB] @ClearLog bit=1 --specificerer om transaktionslogstørrelsen skal reduceresASBEGIN /* Sikkerhedskopiering af DB transaktionslog ON */ SET NOCOUNT COUNT; erklær @dt datetime=getdate(); erklær @år int=ÅR(@dt); erklær @month int=MONTH(@dt); erklær @dag int=DAG(@dt); erklære @hour int=DatoPart(time, @dt); erklær @minut int=DatoPart(minut, @dt); erklære @second int=DatePart(second, @dt); erklære @pathBackup nvarchar(255); erklære @pathstr nvarchar(255); erklære @DBName nvarchar(255); erklær @backupName nvarchar(255); erklære @sql nvarchar(max); erklære @backupSetId som int; erklære @FileNameLog nvarchar(255); erklær @tbl tabel ([DBName] [nvarchar](255) NOT NULL, [LogPathBackup] [nvarchar](255) NOT NULL); erklær @tbllog tabel( [DBNavn] [nvarchar](255) IKKE NULL, [FilnavnLog] [nvarchar](255) IKKE NULL ); --Hentning af DB-navne og fulde stier til oprettelse af sikkerhedskopier af transaktionslogfiler med en ikke-simpel gendannelsesmodel (fuld eller bulk-logget). System-DB'er er også udelukket, indsæt i @tbl ( [DBName] ,[LogPathBackup] ) vælg DB_NAME(b.[DBID]), b.[LogPathBackup] fra [srv].[BackupSettings] som b indre join sys.databaser som d på b.[DBID]=d.[database_id] hvor d.recovery_model<3 og DB_NAME([DBID]) ikke er i ( N'master', N'tempdb', N'model', N'msdb', N' ReportServer', N'ReportServerTempDB' ) og [LogPathBackup] er ikke null; --Hentning af DB-navn og de fulde navne på de tilsvarende transaktionslogfiler (da en DB kan have flere logfiler) indsæt i @tbllog([DBNavn], [FilnavnLog]) vælg t.[DBNavn], tt.[Filnavn] som [FileNameLog] fra @tbl som t indre join [inf].[ServerDBFileInfo] som tt på t.[DBName]=DB_NAME(tt.[database_id]) hvor tt.[Type_desc]='LOG'; -- sekventiel behandling af hver af de DB'er, vi fik tidligere, mens (eksisterer (vælg top(1) 1 fra @tbl)) startsæt @backupSetId=NULL; vælg top(1) @DBName=[DBName], @pathBackup=[LogPathBackup] fra @tbl; sæt @[email protected]+N'_Log_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))+N'_' +cast(@time som nvarchar(255))+N'_'+cast(@minut som nvarchar(255))+N'_'+cast(@second as nvarchar( 255)); sæt @[email protected]@sqldat.com+N'.trn'; --udførelse af sikkerhedskopieringsproceduren sæt @sql=N'BACKUP LOG ['[email protected]+N'] TO DISK =N'+N''''[email protected]+N''''+ N' MED NOFORMAT, NOINIT, NAME =N'+N''''[email protected]+N''''+ N', CHECKSUM, STOP_ON_ERROR, SKIP, SPOLD TILBAGE, KOMPRESSION, STATISTIK =10;'; exec(@sql); --Tjek den sikkerhedskopi af transaktionsloggen, vi lige har oprettet, vælg @backupSetId =position fra msdb..backupset hvor [email protected] og backup_set_id=(vælg max(backup_set_id) fra msdb..backupset hvor [email protected]); set @sql=N'Verifikationsfejl. Sikkerhedskopieringsoplysninger for "'[email protected]+'"-databasen blev ikke fundet.'; hvis @backupSetId er null start raiserror(@sql, 16, 1) end else start set @sql=N'RESTORE VERIFYONLY FROM DISK =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId som nvarchar(255)); exec(@sql); end -- at komprimere DB-transaktionslogfilerne if(@ClearLog=1) start while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) start select top(1) @FileNameLog=FileNameLog fra @tbllog hvor [email protected]; sæt @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N', 0 , TRUNCATEONLY)'; exec(@sql); slet fra @tbllog hvor [email protected] og [email protected]; slut slut slet fra @tbl hvor [DBName][email protected]; endENDGO

[/udvid]

Som nævnt ovenfor er kontrol af databaser for integritet en ressourcetung opgave. Kombineret med det faktum, at sikkerhedskopier af transaktionslog normalt skal oprettes ret ofte, giver dette os en grund til at undlade integritetskontrol, mens vi opretter en kopi af transaktionslog.

Husk også, at fuldstændige sikkerhedskopier af 'master', 'msdb' og 'model' databaser skal laves med jævne mellemrum.

For at automatisere processen for oprettelse af sikkerhedskopier skal du blot ringe til de tidligere implementerede procedurer i Windows Task Scheduler, agentjob eller en lignende tilgængelig tjeneste.

Du skal indstille opkaldsfrekvensen for hver af disse procedurer individuelt baseret på belastningstoppene, aktivitetsplateauer osv.

Den grundlæggende tilgang er som følger:

1) Oprettelse af en fuld sikkerhedskopi én gang om dagen
2) Oprettelse af differentielle sikkerhedskopier hver 2.-4. time
3) Oprettelse af sikkerhedskopier af transaktionslog hvert 5.-60. minut

Vær opmærksom på, at databaser normalt deltager i det fejlsikre og hurtige adgangssystem. Og hvis den senere bruger backup-kopier af transaktionslog, er det meget vigtigt ikke at forstyrre proceduren. Mere specifikt betyder det, at transaktionslogkopier ikke bør oprettes af flere forskellige processer – hvis dette sker, vil sikkerhedskopieringssekvensen fra disse kopier gå tabt.

Her har vi set eksempler på, at hver database behandles sekventielt, én ad gangen. Vi kan dog opnå parallel bearbejdning i produktionsmiljøet – hvilket giver mulighed for at lave flere sikkerhedskopier samtidigt. Dette kan gribes an på flere forskellige måder. For eksempel ved at kalde følgende lagrede procedure:

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [inf].[RunAsyncExecute]( @sql nvarchar(max), @jobnavn nvarchar(57) =null, @database nvarchar(128)=nullchar(owner) 128) =null)AS BEGIN/* Asynkron pakkekørsel via agentens job RunAsyncExecute - asynkron udførelse af T-SQL kommando eller lagret prodecure 2012 Antonin Foller, Motobit Software, www.motobit.com http://www.motobit.com/ tips/detpg_async-execute-sql/ */ SET NOCOUNT ON; erklære @id unikidentifikator; --Opret et unikt jobnavn, hvis navnet ikke er angivet, hvis (@jobnavn er null) sæt @jobnavn=''; sæt @jobnavn =@jobnavn + '_async_' + convert(varchar(64),NEWID()); if (@owner er null) sæt @owner ='sa'; --Opret et nyt job, få job-id udfør msdb..sp_add_job @jobnavn, @[email protected], @[email protected] OUTPUT; --Specificer en jobserver for opgavens udførelse msdb..sp_add_jobserver @[email protected]; --Specificer et første trin af jobbet - SQL-kommandoen --(@on_success_action =3 ... Gå til næste trin) udfør msdb..sp_add_jobstep @[email protected], @step_name='Step1', @command =@sql, @database_name =@database, @on_success_action =3; --Specificer næste trin af jobbet - slet opgaveerklæringen @deletecommand varchar(200); set @deletecommand ='udfør msdb..sp_delete_job @job_name='''[email protected]+''''; udfør msdb..sp_add_jobstep @[email protected], @step_name='Trin2', @command =@deletecommand; --Start jobbet udføre msdb..sp_start_job @[email protected]; SLUT GO

Her opnås asynkroni ved dynamisk at skabe Agent-jobbene, udføre og slette dem bagefter.

Lad os nu se på den generelle algoritme til gendannelse af databaser fra sikkerhedskopier, der tidligere er oprettet i et andet/testmiljø:

1) Definition af hvilke databaser der skal gendannes og placeringen af ​​deres sikkerhedskopier
2) Gendannelse af databaserne
3) Kontrol af de gendannede databaser for integritet

Nu vil vi se på en implementering af en algoritme, som gendanner en database fra en fuld sikkerhedskopi. For en differentiel kopi er proceduren ens – den eneste forskel er, at en fuld sikkerhedskopi skal gendannes førstehånds, efterfulgt af den differentielle kopi.

For at definere, hvilke databaser der skal gendannes, samt placeringen af ​​deres sikkerhedskopier, lad os oprette to tabeller som vist nedenfor:

BRUG [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ÆR NØGLE KLYNGET ( [DBName] ASC) MED (PAD_INDEX =FRA_N STORECOMIST , IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY];GOALTER TABLE [srv].[RestoreSettings] TILFØJ BEGRÆNSNING [DF_RestoreSettings_Indato_Ind. /pre> 

Her er formålet med kolonnerne analogt med dem fra tabellen [srv].[BackupSettings]. Den eneste forskel er, at den fulde sti vil blive brugt til at finde sikkerhedskopierne til gendannelse og ikke til at oprette nye.

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[RestoreSettingsDetail]( [Row_GUID] [uniqueidentifier] IKKE NULL, [DBName] [nvarchar](255) NOT NULL](] [Sourcen5PathcharRestore ) NOT NULL, TargetPathRestore [nvarchar](255) NOT NULL, [Ext] [nvarchar](255) NOT NULL, [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_RestoreSettingsDetail] PRIMÆR NØGLE CLUSTERED ( [SCOW)WITH (A) PAD_INDEX =FRA, STATISTICS_NORECOMPUTE =FRA, IGNORE_DUP_KEY =FRA, ALLOW_ROW_LOCKS =TIL, ALLOW_PAGE_LOCKS =TIL) PÅ [PRIMÆR]) PÅ [PRIMÆR]; GOALTER TABLE [srv]. FOR [Row_GUID];GOALTER TABLE [srv].[RestoreSettingsDetail] TILFØJ BEGRÆNSNING [DF_RestoreSettingsDetail_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate];GO

Denne tabel er nødvendig for at definere de komplette filnavne på databasen, der gendannes, som derefter bruges til yderligere overførsel (f.eks. [SourcePathRestore]='Logisk filnavn' og [TargetPathRestore]='disk:\...\Fysisk filnavn ', mens [Ext]='Filudvidelse')

Faktisk kan vi definere logiske navne på databasefilerne ved hjælp af følgende forespørgsel:

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

Hentning af information om sikkerhedskopier placeret i en fil kan gøres på denne måde:

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

Dernæst har vi en implementering af en lagret procedure, der bruges til at gendanne en database fra en fuld sikkerhedskopi og kontrollere den for dataintegritet:

[expand title =”Kode “]

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunFullRestoreDB]ASBEGIN /* Gendannelse af en DB fra en fuld sikkerhedskopi og kontrol af DB'en for integritet */ SET NOCOUNT ON; erklær @dt datetime=DateAdd(dag,-2,getdate()); erklær @år int=ÅR(@dt); erklær @month int=MONTH(@dt); erklær @dag int=DAG(@dt); erklære @hour int=DatoPart(time, @dt); erklær @minut int=DatoPart(minut, @dt); erklære @second int=DatePart(second, @dt); erklære @pathBackup nvarchar(255); erklære @pathstr nvarchar(255); erklære @DBName nvarchar(255); erklær @backupName nvarchar(255); erklære @sql nvarchar(max); erklære @backupSetId som int; erklære @FileNameLog nvarchar(255); erklære @SourcePathRestore nvarchar(255); erklære @TargetPathRestore nvarchar(255); erklære @Ext nvarchar(255); erklær @tbl tabel ([DBName] [nvarchar](255) NOT NULL, [FullPathRestore] [nvarchar](255) NOT NULL); erklær @tbl_files tabel ( [DBName] [nvarchar](255) NOT NULL, [SourcePathRestore] [nvarchar](255) NOT NULL, [TargetPathRestore] [nvarchar](255) NOT NULL, [Ext] [nvarchar](255) IKKE NULL ); --hentning af en liste over DB-navne og stierne til fulde sikkerhedskopier indsæt i @tbl ( [DBName], [FullPathRestore] ) vælg [DBName], [FullPathRestore] fra [srv].[RestoreSettings]; --henter detaljerede oplysninger om de nye DB-filers placering indsæt i @tbl_files ([DBName],[SourcePathRestore],[TargetPathRestore],[Ext] ) vælg [DBName],[SourcePathRestore],[TargetPathRestore] ,[Ext] fra [ srv].[RestoreSettingsDetail]; --behandler hver af de DB'er, vi fik tidligere, mens(eksisterer(vælg top(1) 1 fra @tbl)) startsæt @backupSetId=NULL; vælg top(1) @DBName=[DBName], @pathBackup=[FullPathRestore] fra @tbl; sæt @[email protected]+N'_Full_backup_'+cast(@year as nvarchar(255))+N'_'+cast(@month as nvarchar(255))+N'_'+cast(@day as nvarchar(255))--+N'_' --+cast(@time som nvarchar(255))+N'_'+cast(@minut som nvarchar(255))+N'_'+cast(@ anden som nvarchar(255)); set @[email protected]@sqldat.com+N'.bak'; --oprettelse af en backup-forespørgsel og udførelse af den sæt @sql=N'RESTORE DATABASE ['[email protected]+N'_Restore] FRA DISK =N'+N''''[email protected]+N''' '+ N' MED FIL =1,'; while(eksisterer(vælg top(1) 1 fra @tbl_filer hvor [DBName][email protected])) start vælg top(1) @SourcePathRestore=[SourcePathRestore], @TargetPathRestore=[TargetPathRestore], @Ext=[Ext] fra @tbl_files hvor [DBName][email protected]; sæt @[email protected]+N' MOVE N'+N''''[email protected]+N''''+N' TO N'+N''''[email protected]+N' _Gendan.'[email protected]+N''''+N','; slet fra @tbl_filer hvor [DBName][email protected] og [SourcePathRestore][email protected] og [Ext][email protected]; slutsæt @[email protected]+N' NOUNLOAD, REPLACE, STATS =5'; exec(@sql); --kontrol af DB'en for integritetssæt @sql=N'DBCC CHECKDB(N'+N''''[email protected]+'_Restore'+N''''+N') WITH NO_INFOMSGS'; exec(@sql); slet fra @tbl hvor [DBName][email protected]; endEND

[/udvid]

For at angive, hvilken fuld sikkerhedskopi der skal bruges til gendannelse, bruges et specielt struktureret filnavn:

_Fuld_backup___.bak

For at automatisere denne databasegendannelsesproces skal opkaldet til den lagrede procedure, vi implementerede, placeres i Windows Task Scheduler, Agent-jobs eller en lignende tilgængelig tjeneste.

Du kan se de seneste sikkerhedskopier af databasen ved at bruge følgende repræsentation:

BRUG [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE VISNING [inf].[vServerLastBackupDB] aswith backup_cte as( vælg bs.[database_name], backup_type =case bs.[type] når 'D' derefter 'database' når 'L ' derefter 'log' når 'I' så 'differential' ellers '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() over ( partition efter bs.[database_name], skriv rækkefølge efter bs.[backup_finish_date] desc ), LogicalDeviceName =bmf.[logical_device_name], Physical_Device_Name =bmf.[fysisk_enhedsnavn], bs.[server_navn], bs.[brugernavn] FRA msdb.dbo.backupset bs INNER JOIN msdb.dbo.backupmediafamily bmf ON [bs].[media_set_id] =[bmf].[media_set_id]) vælg [server_name] som [ServerName], [database_name] som [DBName], [brugernavn] som [Brugernavn], [backup_type] som [BackupType], [backup_start_date] som [BackupStartDate], [backup_finish_date] som [BackupFinishDate], [BackupSizeMb], -- ukomprimeret størrelse [LogicalDeviceName], [PhysicalDeviceName], [first_lsn] som [FirstLSN], [last_lsn] som [LastLSN]fra backup_ctewhere rownum =1;

Resultatet

I denne vejledning har vi set på en implementering af automatiseret backup-proces på én server og efterfølgende gendannelse på en anden (f.eks. en testserver).

Denne metode giver os mulighed for at automatisere processen for oprettelse af sikkerhedskopier, kontrollere sikkerhedskopierne ved at gendanne dem og finjustere processerne vist ovenfor.

Kilder:

Sikkerhedskopiering
Gendan
Backupsæt
CHECKDB
SHRINKFILE
sys.master_files


  1. Opret forbindelse til MySQL eksternt

  2. Hvordan fejlretter man postgresql lagrede procedurer?

  3. Oracle PL/SQL-strengsammenligningsproblem

  4. Databaseoptimering:Indekser