
Tag : Logshipping,Restore,script,SQL Server
Gör en restore med NORECOVERY lägg sedan detta script som ett jobb på ett ställe som har åtkomst till både source och target. Jobbet kommer sedan läsa på alla trn loggar som tagits sedan senast återläsningen baserat på lsn nummer.
Om du inte kan använda powershell av någon anledning finns det ett T-sql script här
Det som behövs utöver powershell koden är en json fil i detta format.
[
{
"TargetName": "TestRecover1",
"TargetServer": "DBServerTarget",
"SourceName": "Test",
"SourceServer": "DBServerSource"
},
{
"TargetName": "TestRecover2",
"TargetServer": "DBServerTarget",
"SourceName": "Test",
"SourceServer": "DBServerSource"
},
{
"TargetName": "TestRecover3",
"TargetServer": "DBServerTarget",
"SourceName": "Test",
"SourceServer": "DBServerSource"
},
{
"TargetName": "TestRecover4",
"TargetServer": "DBServerTarget",
"SourceName": "Test",
"SourceServer": "DBServerSource"
},
{
"TargetName": "TestRecover5",
"TargetServer": "DBServerTarget",
"SourceName": "Test",
"SourceServer": "DBServerSource"
}
]
Här är powershellkoden.
$DBS = Get-Content "[Path To Json]" | convertfrom-json
#Add domains for source and target server
$SourceDomain = ".corp.se"
$TargetDomain = ".corp.se"
# Loops every database in the json file
foreach ($DB in $DBS)
{
$SrcConnection = $Db.SourceServer + $SourceDomain
$TargetConncetion = $Db.TargetServer + $TargetDomain
$SqlServer = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $TargetConncetion
$RecoveryDB = $DB.TargetName
$SourceDB = $DB.SourceName
#Gets the last restored LSN number on target database
$LastLsnRestoreQuery = @"
SELECT TOP 1 b.last_lsn
FROM msdb..restorehistory a
INNER JOIN msdb..backupset b ON a.backup_set_id = b.backup_set_id
WHERE a.destination_database_name = '$($RecoveryDB)'
ORDER BY restore_date DESC
"@
$LastLsn = Invoke-Sqlcmd -ServerInstance $TargetConncetion -Database master -Query $LastLsnRestoreQuery
#Gets the file with the same lsn as the last and every file after on the sourcedb
$LastBackupFilesQuery = @"
SELECT
a.server_name,
a.database_name, backup_finish_date, a.backup_size,
b.physical_device_name
FROM msdb.dbo.backupset a join msdb.dbo.backupmediafamily b
ON a.media_set_id = b.media_set_id
WHERE a.first_lsn >= '$($LastLsn.last_lsn)' AND database_name = '$($SourceDB)' AND a.type = 'L'
ORDER BY a.backup_finish_date DESC
"@
$FilesToRestore = Invoke-Sqlcmd -ServerInstance $SrcConnection -Database master -Query $LastBackupFilesQuery
$TrnFiles = $FilesToRestore | Select-Object backup_finish_date, physical_device_name | Sort-Object backup_finish_date
# Loops every trn file that you want to restor
foreach ($FullBckFile in $TrnFiles.physical_device_name)
{
$Restore = new-object Microsoft.SqlServer.Management.Smo.Restore -Property @{
Action = 'database'
Database = $RecoveryDB
ReplaceDatabase = $true
NoRecovery = $true
}
$BckNumber = New-Object -TypeName Microsoft.SqlServer.Management.Smo.BackupDeviceItem -ArgumentList $FullBckFile, "File"
$Restore.Devices.Add($BckNumber)
# The restore of each file executes
$Restore.SqlRestore($SqlServer)
}
}
<#
# When all trn files are restored you can use this part to open the databases
# Gets all databases in recovery
$RecoveryDBs = $Sqlserver.Databases | Where-Object { $_.Status -eq 'Restoring' } | Select-Object name
# Loops all dbs in recovery and opens them
foreach ($RecoveryDB in $RecoveryDBs.Name)
{
$ExecuteDB = $SqlServer.databases['master']
$ExecuteDB.ExecuteWithResults("RESTORE DATABASE $RecoveryDB WITH RECOVERY")
}
#>