Nella definizione di una strategia di disaster recovery uno dei principali fattori da tenere in considerazione è avere ben chiare le modalità di ripristino dei dati ed avere coscienza non solo della corretta sequenza di ripristino ma anche dei tempi attesi è un aspetto di primaria importanza. Il più delle volte si perde del tempo prezioso nel ricercare, all'interno di un device di backup, la posizione dei vari backup completi, differenziali e del t-log al fine di ricostruire la corretta sequenza di ripristino. Personalmente mi sono costruito questo script
================================
DECLARE @file VARCHAR(255)
SET @file = '\\server\cartella\file.bak'
DECLARE @sql VARCHAR(2048),
@data DATETIME,
@pos SMALLINT,
@logicfile SYSNAME,
@physfile VARCHAR(255),
@masterfile VARCHAR(255),
@db SYSNAME
SET NOCOUNT ON
IF OBJECT_ID('tempdb..#header') IS NOT NULL
DROP TABLE #header
IF OBJECT_ID('tempdb..#filelist') IS NOT NULL
DROP TABLE #filelist
CREATE TABLE #header
(
BackupName nvarchar(128) NULL ,
BackupDescription nvarchar(255) NULL ,
BackupType smallint NULL,
ExpirationDate datetime NULL ,
Compressed tinyint NULL ,
Position smallint NULL ,
DeviceType tinyint NULL ,
UserName nvarchar(128) NULL ,
ServerName nvarchar(128) NULL ,
DatabaseName nvarchar(128) NULL ,
DatabaseVersion int NULL ,
DatabaseCreationDate datetime NULL ,
BackupSize numeric(20,0) NULL ,
FirstLSN numeric(25,0) NULL ,
LastLSN numeric(25,0) NULL ,
CheckpointLSN numeric(25,0) NULL ,
DatabaseBackupLSN numeric(25,0) NULL ,
BackupStartDate datetime NULL ,
BackupFinishDate datetime NULL ,
SortOrder smallint NULL ,
CodePage smallint NULL ,
UnicodeLocaleId int NULL ,
UnicodeComparisonStyle int NULL ,
CompatibilityLevel tinyint NULL ,
SoftwareVendorId int NULL ,
SoftwareVersionMajor int NULL ,
SoftwareVersionMinor int NULL ,
SoftwareVersionBuild int NULL ,
MachineName nvarchar(128) NULL ,
Flags int NULL ,
BindingID uniqueidentifier NULL ,
RecoveryForkID uniqueidentifier NULL ,
Collation nvarchar(128) NULL ,
FamilyGUID uniqueidentifier NULL ,
HasBulkLoggedData bit NULL ,
IsSnapshot bit NULL ,
IsReadOnly bit NULL ,
IsSingleUser bit NULL ,
HasBackupChecksums bit NULL ,
IsDamaged bit NULL ,
BeginsLogChain bit NULL ,
HasIncompleteMetaData bit NULL ,
IsForceOffline bit NULL ,
IsCopyOnly bit NULL ,
FirstRecoveryForkID uniqueidentifier NULL ,
ForkPointLSN numeric(25,0) NULL ,
RecoveryModel nvarchar(60) NULL ,
DifferentialBaseLSN numeric(25,0) NULL ,
DifferentialBaseGUID uniqueidentifier NULL ,
BackupTypeDescription nvarchar(60) NULL ,
BackupSetGUID uniqueidentifier NULL
)
CREATE TABLE #filelist
(
LogicalName nvarchar(128) NOT NULL ,
PhysicalName nvarchar(260) NOT NULL ,
Type char(1) NOT NULL ,
FileGroupName nvarchar(128) NULL ,
Size decimal(20,0) NULL ,
MaxSize decimal(20,0) NULL ,
FileID bigint NULL ,
CreateLSN numeric(25,0) NULL ,
DropLSN numeric(25,0) NULL ,
UniqueID uniqueidentifier NULL ,
ReadOnlyLSN numeric(25,0) NULL ,
ReadWriteLSN numeric(25,0) NULL ,
BackupSizeInBytes bigint NULL ,
SourceBlockSize int NULL ,
FileGroupID int NULL ,
LogGroupGUID uniqueidentifier NULL ,
DifferentialBaseLSN numeric(25,0) NULL ,
DifferentialBaseGUID uniqueidentifier ,
IsReadOnly bit ,
IsPresent bit
)
SET @sql = 'RESTORE HEADERONLY FROM DISK = ''' + @file + ''''
INSERT #header
EXEC (@sql)
SELECT TOP 1 @pos = Position, @data = BackupStartDate , @db = DatabaseName
FROM #header
WHERE BackupType = 1
ORDER BY BackupStartDate DESC
DELETE #header
WHERE Position <= @pos
SET @sql = 'RESTORE FILELISTONLY FROM DISK = ''' + @file + ''' WITH FILE = ' + CONVERT(VARCHAR(5), @pos)
INSERT #filelist
EXEC (@sql)
SET @sql = 'RESTORE DATABASE *nomedb* FROM DISK = ''' + @file + '''' + CHAR(13) +
'WITH '
SELECT @masterfile = RTRIM(filename)
FROM master..sysfiles
WHERE fileid = 1
DECLARE cur CURSOR FOR
SELECT LogicalName, RIGHT(PhysicalName, CHARINDEX('\', REVERSE(PhysicalName)) -1)
FROM #filelist
OPEN cur
FETCH NEXT FROM cur INTO @logicfile, @physfile
WHILE @@FETCH_STATUS = 0
BEGIN
SET @physfile = REPLACE(@masterfile, 'master.mdf', @physfile)
SET @sql = @sql + 'MOVE ''' + @logicfile + ''' TO ''' + @physfile + ''', ' + CHAR(13) + ' '
FETCH NEXT FROM cur INTO @logicfile, @physfile
END
CLOSE cur
DEALLOCATE cur
SET @sql = @sql + 'FILE = ' + CONVERT(VARCHAR(5), @pos) + ', ' + CHAR(13) + ' '
SET @sql = @sql + 'NORECOVERY'
PRINT '--Ripristino del full backup del ' + CONVERT(VARCHAR(20), @data, 113)
PRINT @sql
PRINT 'GO' + CHAR(13) + CHAR(13)
SELECT TOP 1 @pos = Position, @data = BackupStartDate
FROM #header
WHERE BackupType = 5
ORDER BY BackupStartDate DESC
IF @@ROWCOUNT > 0
BEGIN
DELETE #header
WHERE Position <= @pos
SET @sql = 'RESTORE DATABASE *nomedb* FROM DISK = ''' + @file + '''' + CHAR(13) +
'WITH FILE = ' + CONVERT(VARCHAR(5), @pos) + ', ' + CHAR(13) + ' ' +
'NORECOVERY'
PRINT '--Ripristino del diff backup del ' + CONVERT(VARCHAR(20), @data, 113)
PRINT @sql
PRINT 'GO' + CHAR(13) + CHAR(13)
END
WHILE EXISTS (SELECT 1 FROM #header)
BEGIN
SELECT TOP 1 @pos = Position, @data = BackupStartDate
FROM #header
WHERE BackupType = 2
ORDER BY Position ASC
--PRINT CONVERT(varchar(4), @logfile)
DELETE #header
WHERE Position = @pos
SET @sql = 'RESTORE LOG *nomedb* FROM DISK = ''' + @file + '''' + CHAR(13) +
'WITH FILE = ' + CONVERT(VARCHAR(5), @pos) + ', ' + CHAR(13) + ' ' +
'NORECOVERY'
PRINT '--Ripristino del t-log del ' + CONVERT(VARCHAR(20), @data, 113)
PRINT @sql
PRINT 'GO' + CHAR(13) + CHAR(13)
END
PRINT '--Rende il database accessibile'
PRINT 'RESTORE DATABASE *nomedb* WITH RECOVERY'
PRINT 'GO' + CHAR(13) + CHAR(13)
================================
che vi consiglio di portare sempre con voi nella chiavetta USB.
Attenzione che lo script di cui sopra funziona con SQL Server 2005. In SQL Server 2000 differisce l'output dell'istruzione RESTORE HEADERONLY e quello dell'istruzione RESTORE FILELISTONLY ma è sufficiente modificare la definizione delle tabelle temporanee come indicato di seguito per utilizzarlo anche con SQL Server 2000
================================
CREATE TABLE #header
(
BackupName nvarchar(128) NULL,
BackupDescription nvarchar(255) NULL,
BackupType smallint NULL,
ExpirationDate datetime NULL,
Compressed tinyint NULL,
Position smallint NULL,
DeviceType tinyint NULL,
UserName nvarchar(128) NULL,
ServerName nvarchar(128) NULL,
DatabaseName nvarchar(128) NULL,
DatabaseVersion int NULL,
DatabaseCreationDate datetime NULL,
BackupSize decimal(20,0) NULL,
FirstLSN decimal(25,0) NULL,
LastLSN decimal(25,0) NULL,
CheckpointLSN decimal(25,0) NULL,
DatabaseBackupLSN decimal(25,0) NULL,
BackupStartDate datetime NULL,
BackupFinishDate datetime NULL,
SortOrder smallint NULL,
CodePage smallint NULL,
UnicodeLocaleId int NULL,
UnicodeComparisonStyle int NULL,
CompatibilityLevel tinyint NULL,
SoftwareVendorId int NULL,
SoftwareVersionMajor int NULL,
SoftwareVersionMinor int NULL,
SoftwareVersionBuild int NULL,
MachineName nvarchar(128) NULL,
Flags int NULL,
BindingID uniqueidentifier NULL,
RecoveryForkID uniqueidentifier NULL,
Collation nvarchar(128) NULL
)
CREATE TABLE #filelist
(
LogicalName nvarchar(128) NOT NULL,
PhysicalName nvarchar(260) NOT NULL,
Type char(1) NOT NULL,
FileGroupName nvarchar(128) NULL,
Size decimal(20,0) NULL,
MaxSize decimal(20,0) NULL
)
================================
Infine vi segnalo questo sondaggio che la rivista SQL Server Magazine fece qualche anno fa. Non credo che le cose siano molto cambiate da allora ed è estremamente preoccupante leggere che il 70% degli intervistati non si preoccupa affatto della procedura di ripristino dei dati che, ricordo, è parte fondamentale (direi vitale) della strategia di disaster recovery e non esagero dicendo che da essa può dipendere il futuro di ogni azienda.
Bye
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
- Tempo di commiati, il 4 giugno 2007 alle 15:04
- White paper su vardecimal storage format, il 30 maggio 2007 alle 10:49
- Tools per SQL Server, il 24 maggio 2007 alle 08:34
- Serie di articoli su SSIS, il 17 maggio 2007 alle 08:32
- Non c'è pace per il SP2, il 4 maggio 2007 alle 09:39
- Recuperare informazioni sugli indici, il 29 aprile 2007 alle 19:04