sql >> Databáze >  >> RDS >> Database

Implementace automatického zálohování a obnovy databáze pomocí výchozích prostředků

Úvod

Můžete najít spoustu návodů, jak zálohovat a obnovovat databáze. V tomto si ukážeme, jak to lze provést pomocí výchozích prostředků MS SQL Server.

Tento příklad pokryje řadu přístupů – od kontroly integrity databáze před jejím zálohováním až po obnovu databáze z dříve vytvořené záložní kopie.

Řešení

Nejprve se podívejme na celkový algoritmus, který použijeme pro zálohování databáze:

1) Definování, které databáze je třeba zálohovat
2) Kontrola integrity vybraných databází
3) Vytvoření zálohy (úplné, rozdílové nebo transakční kopie protokolu) pro každou z vybraných databází
4) Kontrola vytvořených záložních kopií
5) Komprimace protokolů transakcí (v případě potřeby)

Níže naleznete příklad implementace tohoto algoritmu.

Abychom určili, které databáze je třeba zálohovat, vytvoříme následující tabulku:

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[BackupSettings]( [DBID] [int] NOT NULL, [FullPathBackup] [nvarchar](255) NOT NULL, [2DiffPathBcharkup] ) NULL, [LogPathBackup] [nvarchar](255) NULL, [InsertUTCDate] [datetime] NENÍ NULL, OMEZENÍ [PK_BackupSettings] PRIMÁRNÍ KLÍČ SE SLUSTROVANÝ ( [DBID] ASC)WITH (PAD_INDEX =VYPNUTO, STATUS_COMISTICS =OFF, STATUPPUGNORE_N ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) NA [PRIMÁRNÍ]) NA [PRIMÁRNÍ]; TABULKA BRANKA [srv].[BackupSettings] PŘIDAT OMEZENÍ [DF_BackupSettings_InsertUTCDate] VÝCHOZÍ (getutcdate() CDate] FORMULÁŘ 

Identifikátor databáze se nachází v prvním sloupci, 'FullPathBackup' obsahuje cestu pro vytvoření úplné záložní kopie (například 'disk:\…\') a DiffPathBackup a LogPathBackup obsahují úplné cesty pro vytváření kopií rozdílových a transakčních protokolů. resp. Pokud jsou sloupce DiffPathBackup nebo LogPathBackup prázdné, nebude pro tuto databázi vytvořena kopie protokolu rozdílů a/nebo transakcí.

Můžeme také vytvořit reprezentaci založenou na této tabulce:

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE zobrazení [srv].[vBackupSettings]jako SELECT [DBID] ,DB_Name([DBID]) jako [DBName] ,[FullPathBackup] ,[CD]LogPackup,[DiffPathBackup] ] OD [srv].[BackupSettings];GO

Tato reprezentace vám umožňuje efektivně kontrolovat, které databáze se účastní procesu zálohování.

Nyní vytvořte reprezentaci, která zobrazí informace o databázovém souboru ze systémové reprezentace sys.master_files:

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE zobrazení [inf].[ServerDBFileInfo] jako SELECT @@Servername AS Server , File_id ,--DB identifikátor souboru. Základní hodnota pro file_id je 1 Type_desc ,--Type popis souboru Název jako [FileName] ,--DB název logického souboru LEFT(Physical_Name, 1) AS Drive ,--Disk příznak umístění souboru DB Fyzický_název ,--Úplný soubor jméno v OS RIGHT(fyzické_jméno, 3) AS Ext ,--Přípona souboru Velikost jako CountPage, --Aktuální velikost souboru na stránkách 8Kb zaokrouhleně((cast(Velikost*8 jako plovoucí))/1024,3) jako SizeMb, - -Velikost souboru v Mb zaokrouhlení ((cast(Velikost*8 jako plovoucí))/1024/1024,3) jako SizeGb, --Velikost souboru v Gb, když je_percento_growth=0 pak Růst*8 jinak 0 končí jako Růst, -- Růst souboru v případě stránek o velikosti 8 kB, když is_percent_growth=0 then round((cast(Růst*8 jako plovoucí))/1024,3) konec jako GrowthMb, --Růst souboru v případě Mb, když is_percent_growth=0 then round((cast(Growth) *8 jako plovoucí))/1024/1024,3) končí jako GrowthGb, --Růst souboru v Gb, když je_percent_growth=1, pak Růst jinak 0 končí jako GrowthPercent, --Růst souboru v procentech je_procento_growth, --Atribut růstu v procentech database_id , DB_ Name(database_id) jako [DB_Name], State,--Stav souboru state_desc jako StateDesc,--Popis stavu souboru is_media_read_only jako IsMediaReadOnly,--Soubor je umístěn na disku jako pouze pro čtení (0 - a pro zápis) is_read_only as IsReadOnly ,--soubor je označen jako pouze pro čtení (0 - a pro zápis) is_sparse jako IsSpace,--Sparse soubor is_name_reserved jako IsNameReserved,--1 - Název vzdáleného souboru, přístupný pro použití. --Je nutné získat zálohu protokolu, než znovu použijete stejný název (název nebo argumenty fyzické_jméno) pro nový soubor --0 - Název souboru, nepřístupný pro použití create_lsn jako CreateLsn, -- Registrační číslo transakce v protokolu (LSN) který byl použit k vytvoření souboru drop_lsn jako DropLsn,--LSN který byl použit k odstranění souboru read_only_lsn jako ReadOnlyLsn,--LSN, který byl použit skupinou souborů obsahující soubor ke změně typu "čtení a zápis" na "čtení" -only" (poslední změna) read_write_lsn jako ReadWriteLsn,--LSN, které bylo použito skupinou souborů obsahující soubor ke změně typu "pouze pro čtení" na "čtení a zápis" (poslední změna) DifferentialBaseLsn,- -Základ pro rozdílové záložní kopie. Rozsahy dat, které byly změněny po LSN, jsou zahrnuty do rozdílové zálohy. different_base_guid jako DifferentialBaseGuid, -- Jedinečný identifikátor základní záložní kopie, která bude použita k vytvoření rozdílové kopie. different_base_time jako DifferentialBaseTime,--Čas odpovídající diferenciální_base_lsn redo_start_lsn jako RedoStartLsn,--LSN použitý k určení začátku dalšího opakování --Je NULL, kromě případů, kdy stav =RESTORING nebo stav =RECOVERY_PENDING redo_start_fork_guidk as -Jedinečný identifikátor pro bod rozvětvení obnovy --hodnota argumentu first_fork_guid další obnovené záložní kopie by se měla rovnat této hodnotě redo_target_lsn jako RedoTargetLsn,--LSN, které slouží jako bod zastavení pro opakování v "online" režimu v tomto souboru -- Je NULL, s výjimkou případů, kdy stav =RESTORING nebo stav =RECOVERY_PENDING redo_target_fork_guid jako RedoTargetForkGuid, -- Obnovovací vidlice, na které lze kontejner obnovit. Používá se spolu s redo_target_lsn backup_lsn jako BackupLsn--LSN nejnovějších dat nebo rozdílová záložní kopie souboruFROM sys.master_files--database_files;GO

Chcete-li vytvořit úplné záložní kopie, implementujme následující uloženou proceduru:

[rozbalit název =”Kód “]

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunFullBackupDB] @ClearLog bit=1 -- určuje, zda by se měla zmenšit velikost protokolu transakcíASBEGIN /* Vytvoření úplné záložní kopie DB a kontrola integrity DB předem */ SET NOCOUNT ON; deklarovat @dt datetime=getdate(); deklarovat @rok int=YEAR(@dt); deklarovat @měsíc int=MONTH(@dt); deklarovat @day int=DAY(@dt); deklarovat @hour int=DatePart(hodina, @dt); deklarovat @minute int=DatePart(minuta, @dt); deklarovat @second int=DatePart(second, @dt); deklarovat @pathBackup nvarchar(255); deklarovat @pathstr nvarchar(255); deklarovat @DBName nvarchar(255); deklarovat @název_zálohy nvarchar(255); deklarovat @sql nvarchar(max); deklarovat @backupSetId jako int; deklarovat @FileNameLog nvarchar(255); deklarovat tabulku @tbllog( [Název DB] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); deklarovat tabulku @tbl ( [DBName] [nvarchar](255) NOT NULL, [FullPathBackup] [nvarchar](255) NOT NULL ); --Načtení názvu DB a úplných cest pro vytvoření úplné záložní kopie vložte do @tbl ( [DBName] ,[FullPathBackup] ) vyberte DB_NAME([DBID]) ,[FullPathBackup] z [srv].[BackupSettings]; --Načtení názvu DB a názvů příslušných protokolů transakcí (protože jedna DB může mít více protokolů) vložte do @tbllog([DBName], [FileNameLog]) vyberte t.[DBName], tt.[FileName] jako [FileNameLog ] z @tbl jako t vnitřní spojení [inf].[ServerDBFileInfo] jako tt na t.[DBName]=DB_NAME(tt.[id_databáze]) kde tt.[Type_desc]='LOG'; --sekvenčně zpracováváme každou z DB, kterou jsme získali dříve while(exists(select top(1) 1 from @tbl)) begin set @backupSetId=NULL; select top(1) @DBName=[DBName], @pathBackup=[FullPathBackup] z @tbl; nastavit @[email protected]+N'_Full_backup_'+cast(@rok jako nvarchar(255))+N'_'+cast(@měsíc jako nvarchar(255))+N'_'+cast(@den jako nvarchar(255))--+N'_' --+cast(@hodina jako nvarchar(255))+N'_'+cast(@minuta jako nvarchar(255))+N'_'+cast(@ druhý jako nvarchar(255)); set @[email protected]@sqldat.com+N'.bak'; --kontrola sady integrity DB @sql=N'DBCC CHECKDB(N'+N''''[email protected]+N''''+N') S NO_INFOMSGS'; exec(@sql); --provedení procedury vytvoření záložní kopie set @sql=N'BACKUP DATABASE ['[email protected]+N'] NA DISK =N'+N''''[email protected]+N''''+ N' WITH NOFORMAT, NOINIT, JMÉNO =N'+N''''[email protected]+N''''+ N', KONTROLNÍ SOUČET, STOP_ON_ERROR, PŘESKOČIT, PŘETOČIT ZPĚT, KOMPRESE, STATS =10;'; exec(@sql); --kontrola záložní kopie, kterou jsme vytvořili, vyberte @backupSetId =pozici z msdb..backupset kde [email protected] a backup_set_id=(vyberte max(backup_set_id) z msdb..backupset kde [email protected]); set @sql=N'Chyba ověření. Informace o záložní kopii databáze "'[email protected]+'" nebyly nalezeny.'; pokud je @backupSetId null begin raiserror(@sql, 16, 1) end else begin set @sql=N'RESTORE VERIFYYONLY Z DISKU =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId as nvarchar(255)); exec(@sql); end --komprimace protokolů transakcí DB if(@ClearLog=1) begin while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) begin select top(1) @FileNameLog=FileNameLog z @tbllog kde [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N' , 0 , POUZE ZKRÁCENÝ)'; exec(@sql); odstranit z @tbllog kde [email protected] a [email protected]; end end delete from @tbl where [DBName][email protected]; endENDGO

[/expand]

Podle kódu vidíme, že tento postup poskytuje řešení pro zbývající kroky algoritmu vytváření záložní kopie.

Postupy, které vytvářejí rozdílové kopie a kopie protokolu transakcí, jsou implementovány podobným způsobem:

[rozbalit název =”Kód “]

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunDiffBackupDB] @ClearLog bit=1 --uvádí, zda by se měla zmenšit velikost protokolu transakcíASBEGIN /* Vytvoření rozdílové záložní kopie DB */ SET NOCOUNT ON; deklarovat @dt datetime=getdate(); deklarovat @rok int=YEAR(@dt); deklarovat @měsíc int=MONTH(@dt); deklarovat @day int=DAY(@dt); deklarovat @hour int=DatePart(hodina, @dt); deklarovat @minute int=DatePart(minuta, @dt); deklarovat @second int=DatePart(second, @dt); deklarovat @pathBackup nvarchar(255); deklarovat @pathstr nvarchar(255); deklarovat @DBName nvarchar(255); deklarovat @název_zálohy nvarchar(255); deklarovat @sql nvarchar(max); deklarovat @backupSetId jako int; deklarovat @FileNameLog nvarchar(255); deklarovat tabulku @tbl ( [DBName] [nvarchar](255) NOT NULL, [DiffPathBackup] [nvarchar](255) NOT NULL ); deklarovat tabulku @tbllog( [Název DB] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); --Načtení názvu DB a úplných cest pro vytváření rozdílových záložních kopií vložte do @tbl ( [DBName] ,[DiffPathBackup] ) vyberte DB_NAME([DBID]) ,[DiffPathBackup] z [srv].[BackupSettings] kde [DiffPathBackup] není null; --Načtení názvu DB a úplných názvů příslušných souborů protokolu transakcí (protože jedna DB může mít více protokolů) vložte do @tbllog([DBName], [FileNameLog]) vyberte t.[DBName], tt.[FileName] jako [FileNameLog] z @tbl jako t vnitřní spojení [inf].[ServerDBFileInfo] jako tt na t.[DBName]=DB_NAME(tt.[database_id]) kde tt.[Type_desc]='LOG'; --sekvenčně zpracováváme každou z DB, kterou jsme získali dříve while(exists(select top(1) 1 from @tbl)) begin set @backupSetId=NULL; select top(1) @DBName=[DBName], @pathBackup=[DiffPathBackup] z @tbl; set @[email protected]+N'_Diff_backup_'+cast(@rok jako nvarchar(255))+N'_'+cast(@měsíc jako nvarchar(255))+N'_'+cast(@den jako nvarchar(255))+N'_' +cast(@hodina jako nvarchar(255))+N'_'+cast(@minuta jako nvarchar(255))+N'_'+cast(@sekunda jako nvarchar( 255)); set @[email protected]@sqldat.com+N'.bak'; --kontrola sady integrity DB @sql=N'DBCC CHECKDB(N'+N''''[email protected]+N''''+N') S NO_INFOMSGS'; exec(@sql); --provedení procedury zálohování nastavit @sql=N'BACKUP DATABASE ['[email protected]+N'] NA DISK =N'+N''''[email protected]+N''''+ N' S DIFERENCIÁLEM, NOFORMAT, NOINIT, JMÉNO =N'+N''''[email protected]+N''''+ N', KONTROLNÍ SOUČET, STOP_ON_ERROR, PŘESKOČIT, ZPĚT, KOMPRESE, STATS =10;'; exec(@sql); --kontrola záložní kopie, kterou jsme právě vytvořili, vyberte @backupSetId =pozici z msdb..backupset kde [email protected] a backup_set_id=(vyberte max(backup_set_id) z msdb..backupset kde [email protected]); set @sql=N'Chyba ověření. Informace o záložní kopii databáze "'[email protected]+'" nebyly nalezeny.'; pokud je @backupSetId null begin raiserror(@sql, 16, 1) end else begin set @sql=N'RESTORE VERIFYYONLY Z DISKU =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId as nvarchar(255)); exec(@sql); end --komprimace protokolů transakcí DB if(@ClearLog=1) begin while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) begin select top(1) @FileNameLog=FileNameLog z @tbllog kde [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N' , 0 , POUZE ZKRÁCENÝ)'; exec(@sql); odstranit z @tbllog kde [email protected] a [email protected]; end end delete from @tbl where [DBName][email protected]; endENDGO

[/expand]

Protože kontrola integrity databází vyžaduje mnoho zdrojů, můžeme ji při vytváření rozdílové záložní kopie vynechat.

[rozbalit název =”Kód “]

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunLogBackupDB] @ClearLog bit=1 -- specifikuje, zda by se měla zmenšit velikost transakčního protokoluASBEGIN /* Zálohování transakčního protokolu DB */ SET NOCOUNT ON; deklarovat @dt datetime=getdate(); deklarovat @rok int=YEAR(@dt); deklarovat @měsíc int=MONTH(@dt); deklarovat @day int=DAY(@dt); deklarovat @hour int=DatePart(hodina, @dt); deklarovat @minute int=DatePart(minuta, @dt); deklarovat @second int=DatePart(second, @dt); deklarovat @pathBackup nvarchar(255); deklarovat @pathstr nvarchar(255); deklarovat @DBName nvarchar(255); deklarovat @název_zálohy nvarchar(255); deklarovat @sql nvarchar(max); deklarovat @backupSetId jako int; deklarovat @FileNameLog nvarchar(255); deklarovat tabulku @tbl ( [DBName] [nvarchar](255) NOT NULL, [LogPathBackup] [nvarchar](255) NOT NULL ); deklarovat tabulku @tbllog( [Název DB] [nvarchar](255) NOT NULL, [FileNameLog] [nvarchar](255) NOT NULL ); --Načítání názvů DB a úplných cest pro vytváření záložních kopií protokolů transakcí s nejednoduchým modelem obnovy (úplné nebo hromadně protokolované). Systémové databáze jsou také vyloučeny vložte do @tbl ( [DBName] ,[LogPathBackup] ) vyberte DB_NAME(b.[DBID]) ,b.[LogPathBackup] z [srv].[BackupSettings] jako b vnitřní spojení sys.databases jako d na b.[DBID]=d.[id_databáze] kde d.recovery_model<3 a DB_NAME([DBID]) nejsou v ( N'master', N'tempdb', N'model', N'msdb', N' ReportServer', N'ReportServerTempDB' ) a [LogPathBackup] není null; --Načtení názvu DB a úplných názvů příslušných souborů protokolu transakcí (protože jedna DB může mít více protokolů) vložte do @tbllog([DBName], [FileNameLog]) vyberte t.[DBName], tt.[FileName] jako [FileNameLog] z @tbl jako t vnitřní spojení [inf].[ServerDBFileInfo] jako tt na t.[DBName]=DB_NAME(tt.[database_id]) kde tt.[Type_desc]='LOG'; --sekvenčně zpracováváme každou z DB, kterou jsme získali dříve while(exists(select top(1) 1 from @tbl)) begin set @backupSetId=NULL; select top(1) @DBName=[DBName], @pathBackup=[LogPathBackup] z @tbl; set @[email protected]+N'_Log_backup_'+cast(@rok jako nvarchar(255))+N'_'+cast(@měsíc jako nvarchar(255))+N'_'+cast(@den jako nvarchar(255))+N'_' +cast(@hodina jako nvarchar(255))+N'_'+cast(@minuta jako nvarchar(255))+N'_'+cast(@sekunda jako nvarchar( 255)); set @[email protected]@sqldat.com+N'.trn'; --provedení procedury zálohování nastavte @sql=N'BACKUP LOG ['[email protected]+N'] NA DISK =N'+N''''[email protected]+N''''+ N' S NOFORMAT, NOINIT, NAME =N'+N''''[email protected]+N''''+ N', KONTROLNÍ SOUČET, STOP_ON_ERROR, PŘESKOČIT, PŘEVRÁTIT, KOMPRESE, STATS =10;'; exec(@sql); --Kontrola záložní kopie protokolu transakcí, kterou jsme právě vytvořili, vyberte @backupSetId =pozici z msdb..backupset kde [email protected] a backup_set_id=(vyberte max(backup_set_id) z msdb..backupset kde [email protected]); set @sql=N'Chyba ověření. Informace o záložní kopii databáze "'[email protected]+'" nebyly nalezeny.'; pokud je @backupSetId null begin raiserror(@sql, 16, 1) end else begin set @sql=N'RESTORE VERIFYYONLY Z DISKU =N'+''''[email protected]+N''''+N' WITH FILE ='+cast(@backupSetId as nvarchar(255)); exec(@sql); end --komprimace protokolů transakcí DB if(@ClearLog=1) begin while(exists(select top(1) 1 from @tbllog where [DBName][email protected])) begin select top(1) @FileNameLog=FileNameLog z @tbllog kde [email protected]; set @sql=N'USE ['[email protected]+N'];'+N' DBCC SHRINKFILE (N'+N''''[email protected]+N''''+N' , 0 , POUZE ZKRÁCENÝ)'; exec(@sql); odstranit z @tbllog kde [email protected] a [email protected]; end end delete from @tbl where [DBName][email protected]; endENDGO

[/expand]

Jak bylo řečeno výše, kontrola integrity databází je úkol náročný na zdroje. V kombinaci se skutečností, že záložní kopie protokolu transakcí je obvykle nutné vytvářet poměrně často, nám to dává důvod vynechat kontrolu integrity při vytváření kopie protokolu transakcí.

Také mějte na paměti, že je třeba pravidelně vytvářet úplné záložní kopie databází „master“, „msdb“ a „model“.

Chcete-li zautomatizovat proces vytváření záložní kopie, stačí zavolat dříve implementované procedury do Plánovače úloh systému Windows, úloh agenta nebo jakékoli podobné dostupné služby.

Frekvenci volání pro každou z těchto procedur budete muset nastavit individuálně na základě špiček zátěže, plató aktivity atd.

Základní přístup je následující:

1) Vytváření úplné záložní kopie jednou denně
2) Vytváření rozdílových záložních kopií každé 2-4 hodiny
3) Vytváření záložních kopií protokolu transakcí každých 5-60 minut

Mějte prosím na paměti, že databáze se obvykle účastní systému bezpečného a rychlého přístupu. A pokud později používá záložní kopie protokolu transakcí, je životně důležité nezasahovat do postupu. Konkrétně to znamená, že kopie protokolu transakcí by neměly být vytvářeny několika různými procesy – pokud k tomu dojde, sekvence záloh z těchto kopií bude ztracena.

Zde jsme viděli příklady každé databáze, která je zpracovávána postupně, jedna po druhé. Můžeme však dosáhnout paralelního zpracování v produkčním prostředí – umožňující vytvoření několika záložních kopií současně. K tomu lze přistupovat několika různými způsoby. Například voláním následující uložené procedury:

POUŽÍVEJTE POSTUP PŘI VYTVOŘENÍ [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER [inf].[RunAsyncExecute]( @sql nvarchar(max), @jobname nvarchar(57) =null, @database nvarchar(null,128)char 128) =null)AS BEGIN/* Asynchronní spouštění balíčku prostřednictvím úloh agenta RunAsyncExecute - asynchronní provádění příkazu T-SQL nebo uloženého prodecure 2012 Antonin Foller, Motobit Software, www.motobit.com http://www.motobit.com/ tips/detpg_async-execute-sql/ */ SET NOCOUNT ON; deklarovat @id jedinečný identifikátor; --Vytvořit jedinečný název úlohy, pokud není zadán název if (@jobname je null) set @jobname=''; set @jobname =@jobname + '_async_' + convert(varchar(64),NEWID()); if (@owner je null) set @owner ='sa'; --Vytvořte novou úlohu, získejte ID úlohy spusťte msdb..sp_add_job @jobname, @[email protected], @[email protected] VÝSTUP; --Určete server úlohy pro provedení úlohy msdb..sp_add_jobserver @[email protected]; --Určete první krok úlohy - příkaz SQL ---(@on_success_action =3 ... Přejít na další krok) spusťte msdb..sp_add_jobstep @[email protected], @step_name='Step1', @command =@sql, @name_database =@database, @on_success_action =3; --Určete další krok úlohy - odstraňte úlohu deklarujte @deletecommand varchar(200); set @deletecommand ='provést msdb..sp_delete_job @job_name='''[email protected]+''''; spustit msdb..sp_add_jobstep @[email protected], @step_name='Step2', @command =@deletecommand; --Spusťte úlohu spusťte msdb..sp_start_job @[email protected]; END GO

Zde je asynchronie dosaženo dynamickým vytvářením úloh agenta, jejich následným spouštěním a mazáním.

Nyní se podívejme na obecný algoritmus pro obnovu databází ze záložních kopií dříve vytvořených v jiném/testovacím prostředí:

1) Definování, které databáze by měly být obnoveny, a umístění jejich záložních kopií
2) Obnovení databází
3) Kontrola integrity obnovených databází

Nyní se podíváme na implementaci algoritmu, který obnoví databázi z úplné záložní kopie. Pro rozdílovou kopii je postup podobný – jediný rozdíl je v tom, že z první ruky je třeba obnovit plnou záložní kopii a poté rozdílovou kopii.

Chcete-li definovat, které databáze by měly být obnoveny, a také umístění jejich záložních kopií, vytvořte dvě tabulky, jak je uvedeno níže:

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[RestoreSettings]( [DBName] [nvarchar](255) NOT NULL, [FullPathRestore] [nvarchar](255) [nvarchar](255) Diff NOT NULL,char ](255) NENÍ NULL, [LogPathRestore] [nvarchar](255) NOT NULL, [InsertUTCDate] [datumčas] NENÍ NULL, OMEZENÍ [PK_RestoreSettings] PRIMÁRNÍ KLÍČ V KLUSTERU ( [DBName] ASC) S (PAD_STATOFFISTIC =VYPNUTO, VYPNUTO 1 /před> 

Zde je účel sloupců analogický těm z tabulky [srv].[BackupSettings]. Jediný rozdíl je v tom, že úplná cesta bude použita k vyhledání záložních kopií pro obnovení, nikoli k vytvoření nových.

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[RestoreSettingsDetail]( [Row_GUID] [uniqueidentifier] NENÍ NULL, [DBName] [nvarchar](255) NOT NULL, [Source25Pan5Restore] ) NOT NULL, TargetPathRestore [nvarchar](255) NOT NULL, [Ext] [nvarchar](255) NOT NULL, [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_RestoreSettingsDetail] PRIMÁRNÍ KLÍČ SE SLUSTROVANÝ ( [Row_GUID] PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMARY]) ZAPNUTO [PRIMARY];TABULKA CÍLŮ [srv].[Restore_)Detail id_Kontrola_Restore]DE FOR [Row_GUID];TABULKA BRANKA [srv].[RestoreSettingsDetail] PŘIDAT OMEZENÍ [DF_RestoreSettingsDetail_InsertUTCDate] VÝCHOZÍ (getutcdate()) PRO [InsertUTCDate];PŘEJÍT

Tato tabulka je potřebná k definování úplných názvů souborů obnovované databáze, které se pak použijí pro další přenos (například [SourcePathRestore]='Logical file name' a [TargetPathRestore]='disk:\…\Physical file name ', zatímco [Ext]='Přípona souboru')

Ve skutečnosti můžeme definovat logická jména databázových souborů pomocí následujícího dotazu:

OBNOVIT SOUBOR POUZE Z DISKU ='disk:\...\záložní kopie.BAK';

Získání informací o záložních kopiích umístěných v souboru lze provést tímto způsobem:

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

Dále máme implementaci uložené procedury používané pro obnovu databáze z úplné záložní kopie a její kontrolu integrity dat:

[rozbalit název =”Kód “]

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER PROCEDURE [srv].[RunFullRestoreDB]ASBEGIN /* Obnova DB z úplné záložní kopie a kontrola integrity DB */ SET NOCOUNT ON; deklarovat @dt datetime=DateAdd(den,-2,getdate()); deklarovat @rok int=YEAR(@dt); deklarovat @měsíc int=MONTH(@dt); deklarovat @day int=DAY(@dt); deklarovat @hour int=DatePart(hodina, @dt); deklarovat @minute int=DatePart(minuta, @dt); deklarovat @second int=DatePart(second, @dt); deklarovat @pathBackup nvarchar(255); deklarovat @pathstr nvarchar(255); deklarovat @DBName nvarchar(255); deklarovat @název_zálohy nvarchar(255); deklarovat @sql nvarchar(max); deklarovat @backupSetId jako int; deklarovat @FileNameLog nvarchar(255); deklarovat @SourcePathRestore nvarchar(255); deklarovat @TargetPathRestore nvarchar(255); deklarovat @Ext nvarchar(255); deklarovat tabulku @tbl ( [DBName] [nvarchar](255) NOT NULL, [FullPathRestore] [nvarchar](255) NOT NULL ); deklarovat tabulku @tbl_files ( [DBName] [nvarchar](255) NOT NULL, [SourcePathRestore] [nvarchar](255) NOT NULL, [TargetPathRestore] [nvarchar](255) NOT NULL, [Ext] [nvarchar](255) NENULOVÝ ); --načtení seznamu názvů DB a cest k úplným záložním kopiím vložte do @tbl ( [DBName] ,[FullPathRestore] ) vyberte [DBName] ,[FullPathRestore] z [srv].[RestoreSettings]; --načtení podrobných informací o novém umístění souborů DB vložte do @tbl_files ( [DBName] ,[SourcePathRestore] ,[TargetPathRestore] ,[Ext] ) vyberte [DBName] ,[SourcePathRestore] ,[TargetPathRestore] ,[Ext] z [ srv].[RestoreSettingsDetail]; --zpracování každé z DB, které jsme získali dříve while(exists(select top(1) 1 from @tbl)) begin set @backupSetId=NULL; select top(1) @DBName=[DBName], @pathBackup=[FullPathRestore] z @tbl; nastavit @[email protected]+N'_Full_backup_'+cast(@rok jako nvarchar(255))+N'_'+cast(@měsíc jako nvarchar(255))+N'_'+cast(@den jako nvarchar(255))--+N'_' --+cast(@hodina jako nvarchar(255))+N'_'+cast(@minuta jako nvarchar(255))+N'_'+cast(@ druhý jako nvarchar(255)); set @[email protected]@sqldat.com+N'.bak'; --vytvoření záložního dotazu a jeho provedení set @sql=N'RESTORE DATABASE ['[email protected]+N'_Restore] Z DISKU =N'+N''''[email protected]+N''' '+ N' SE SOUBOREM =1,'; while(exists(select top(1) 1 from @tbl_files where [DBName][email protected])) begin select top(1) @SourcePathRestore=[SourcePathRestore], @TargetPathRestore=[TargetPathRestore], @Ext=[Ext] z @tbl_files kde [DBName][email protected]; nastavit @[email protected]+N' PŘESUN N'+N''''[email protected]+N''''+N' DO N'+N''''[email protected]+N' _Restore.'[email protected]+N''''+N','; odstranit z @tbl_files kde [Název DB][email protected] a [SourcePathRestore][email protected] a [Ext][email protected]; koncová sada @[email protected]+N' NOUNLOAD, REPLACE, STATS =5'; exec(@sql); --kontrola sady integrity DB @sql=N'DBCC CHECKDB(N'+N''''[email protected]+'_Restore'+N''''+N') S NO_INFOMSGS'; exec(@sql); smazat z @tbl kde [název DB][email protected]; endEND

[/expand]

K určení, která plná záložní kopie by měla být použita pro obnovu, se používá speciálně strukturovaný název souboru:

_Full_backup___.bak

Pro automatizaci tohoto procesu obnovy databáze by volání uložené procedury, které jsme implementovali, mělo být umístěno do Plánovače úloh systému Windows, úloh agenta nebo jakékoli podobné dostupné služby.

Nejnovější záložní kopie databáze můžete zobrazit pomocí následujícího znázornění:

POUŽÍVEJTE [DB_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE VIEW [inf].[vServerLastBackupDB] aswith backup_cte as( vyberte bs.[název_databáze], typ_zálohy =případ bs.[typ] když 'D', pak 'databáze' když 'L ' potom 'log' když 'I' pak 'diferenciální' jinak 'jiný' konec, bs.[first_lsn], bs.[last_lsn], bs.[backup_start_date], bs.[backup_finish_date], cast(bs.[backup_size] as decimal(18,3))/1024/1024 as BackupSizeMb, rownum =row_number() over (oddíl podle bs.[název_databáze], pořadí typů podle bs.[databáze_zálohy] desc ), název logického zařízení =bmf.[název_logického_zařízení], název fyzického zařízení =bmf.[název_fyzického_zařízení], bs.[název_serveru], bs.[uživatelské_jméno] OD msdb.dbo.backupset bs VNITŘNÍ PŘIPOJENÍ msdb.dbo.backupmediafamily bmf ON [bs].[id_souboru médií] =[bmf].[id_setu médií]) vyberte [název_serveru] jako [ServerName], [database_name] jako [DBName], [user_name] jako [USerName], [backup_type] jako [BackupType], [backup_start_date] jako [BackupStartDate], [backup_finish_date] jako [BackupFinishDate], [BackupSizeMb] nekomprimovaná velikost [LogicalDeviceName], [PhysicalDeviceName], [first_lsn] jako [FirstLSN], [last_lsn] jako [LastLSN] ze backup_ctewhere rownum =1;

Výsledek

V této příručce jsme se zabývali implementací procesu automatického zálohování na jednom serveru a následné obnovy na jiném serveru (například testovací server).

Tato metoda nám umožňuje automatizovat proces vytváření záložní kopie, kontrolovat záložní kopie jejich obnovením a doladit procesy uvedené výše.

Zdroje:

Záloha
Obnovit
Sada záloh
CHECKDB
SHRINKFILE
sys.master_files


  1. Úprava řádků tabulky / záznamů v SQL Server Management Studio ( SSMS) - SQL Server výukový program / TSQL výukový program, část 18

  2. Jak uložit hodnoty NULL do polí data a času v MySQL?

  3. Proč Oracle používá DBMS_STATS.GATHER_TABLE_STATS?

  4. Jak přidat skupinu souborů do databáze SQL Server (T-SQL)