Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 43b3610

Browse files
Merge pull request dataplat#3727 from sqlcollaborative/HellFroze
Adding time filtering before scanning for Maintenance Plan backups
2 parents 4629661 + c0ef7fd commit 43b3610

File tree

3 files changed

+107
-8
lines changed

3 files changed

+107
-8
lines changed

‎functions/Get-DbaBackupInformation.ps1

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ function Get-DbaBackupInformation {
5757
.PARAMETER MaintenanceSolution
5858
This switch tells the function that the folder is the root of a Ola Hallengren backup folder
5959
60+
.PARAMETER RestoreTime
61+
This parameter ONLY works with the MaintenanceSolution switch
62+
If both are specified we will pre filter the files before reading the headers. This is not guaranteed to always work if you've moved files, or they contain multiple backups or you've altered any of the default naming rules in Ola's scripts
63+
6064
.PARAMETER IgnoreLogBackup
6165
This switch only works with the MaintenanceSolution switch. With an Ola Hallengren style backup we can be sure that the LOG folder contains only log backups and skip it.
6266
For all other scenarios we need to read the file headers to be sure.
@@ -126,7 +130,7 @@ function Get-DbaBackupInformation {
126130
127131
As we know we are dealing with an Ola Hallengren style backup folder from the MaintenanceSolution switch, when IgnoreLogBackup is also included we can ignore the LOG folder to skip any scanning of log backups. Note this also means then WON'T be restored
128132
#>
129-
[CmdletBinding( DefaultParameterSetName = "Create")]
133+
[CmdletBinding( DefaultParameterSetName = "Create",SupportsShouldProcess=$false,ConfirmImpact="Low")]
130134
param (
131135
[parameter(Mandatory = $true, ValueFromPipeline = $true)]
132136
[object[]]$Path,
@@ -143,6 +147,7 @@ function Get-DbaBackupInformation {
143147
[switch]$DirectoryRecurse,
144148
[switch]$EnableException,
145149
[switch]$MaintenanceSolution,
150+
[DateTime]$RestoreTime,
146151
[switch]$IgnoreLogBackup,
147152
[string]$ExportPath,
148153
[string]$AzureCredential,
@@ -270,9 +275,7 @@ function Get-DbaBackupInformation {
270275
}
271276
else {
272277
if ($true -eq $MaintenanceSolution) {
273-
$Files += Get-XpDirTreeRestoreFile -Path $f\FULL -SqlInstance $server -NoRecurse
274-
$Files += Get-XpDirTreeRestoreFile -Path $f\DIFF -SqlInstance $server -NoRecurse
275-
$Files += Get-XpDirTreeRestoreFile -Path $f\LOG -SqlInstance $server -NoRecurse
278+
$Files += Get-XpDirTreeRestoreFile -Path $f -SqlInstance $server
276279
}
277280
else {
278281
Write-Message -Level VeryVerbose -Message "File"
@@ -286,7 +289,36 @@ function Get-DbaBackupInformation {
286289
Write-Message -Level Verbose -Message "Skipping Log Backups as requested"
287290
$Files = $Files | Where-Object {$_.FullName -notlike '*\LOG\*'}
288291
}
289-
292+
if($True -eq $MaintenanceSolution -and $null -ne $RestoreTime){
293+
Write-Message -Level Verbose -Message "Filtering via Maintenance Solution filename"
294+
Foreach ($file in $files){
295+
$null=$file.fullname -match '[A-z]*_(?<date>[0-9]*_[0-9]*)[_0-9]*.[A-z]{3}'
296+
$FileDate = Get-Date -year $matches.date.Substring(0,4) -Month $matches.date.Substring(4,2) -Day $matches.date.Substring(6,2) -Hour $matches.date.Substring(9,2) -Minute $matches.date.Substring(11,2) -Second $matches.date.Substring(13,2)
297+
$File | Add-Member -Type NoteProperty -Name CreateDate -Value $FileDate
298+
}
299+
#Get Full
300+
$Full = @()
301+
$Full += $Files | Where-object {$_.FullName -like '*FULL*' -and $_.CreateDate -lt $RestoreTime} | Sort-object -Property CreateDate -Descending | Select-Object -First 1
302+
#Get Stripe set
303+
$FullCreateDate = $Full.CreateDate
304+
$Full += $Files | Where-Object ($_.FullName -like '*FULL*' -and $_.CreateDate -eq $FullCreateDate)
305+
$Full = $Full | Sort-Object -Property FullName -Unique
306+
#return $files
307+
$Diff = @()
308+
$Diff += $Files | Where-Object {$_.FullName -like '*DIFF*' -and $_.CreateDate -gt $FullCreateDate -and $_.CreateDate -lt $RestoreTime} | Sort-Object -Property CreateDate -Descending | Select-Object -First 1
309+
if ($diff.count -eq 0){
310+
$DiffCreateDate = ($Full | Sort-Object -property CreateDate -Descending | select -First 1).CreateDate
311+
}
312+
else{
313+
$DiffCreateDate = $Diff.CreateDate
314+
$Diff += $Files | where-Object {$_.Fullname -like '*DIFF*' -and $_.CreateDate -eq $DiffCreateDate}
315+
}
316+
$Log = $Files | Where-Object {$_.FullName -like '*LOG*' -and $_.CreateDate -gt $DiffCreateDate -and $_.CreateDate -lt $RestoreTime}
317+
$Files = @()
318+
$Files += $Full | Select-Object FullName
319+
$files += $Diff | Select-Object FullName
320+
$files += $Log | Select-Object FullName
321+
}
290322
Write-Message -Level Verbose -Message "Reading backup headers of $($Files.Count) files"
291323
$FileDetails = Read-DbaBackupHeader -SqlInstance $server -Path $Files -AzureCredential $AzureCredential
292324

‎functions/Restore-DbaDatabase.ps1

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function Restore-DbaDatabase {
6868
6969
.PARAMETER MaintenanceSolutionBackup
7070
Switch to indicate the backup files are in a folder structure as created by Ola Hallengreen's maintenance scripts.
71-
This swith enables a faster check for suitable backups. Other options require all files to be read first to ensure we have an anchoring full backup. Because we can rely on specific locations for backups performed with OlaHallengren's backup solution, we can rely on file locations.
71+
This switch enables a faster check for suitable backups. Other options require all files to be read first to ensure we have an anchoring full backup. Because we can rely on specific locations for backups performed with OlaHallengren's backup solution, we can rely on file locations.
7272
7373
.PARAMETER FileMapping
7474
A hashtable that can be used to move specific files to a location.
@@ -285,6 +285,10 @@ function Restore-DbaDatabase {
285285
If server\instance1 is Enterprise edition this will be done online, if not it will be performed offline
286286
AllowContinue is required to make sure we cope with existing files
287287
288+
.EXAMPLE
289+
Restore-DbaDatabase -SqlInstance server\instance1 -Path c:\backups\db1 -MaintenanceSolutionBackup -RestoreTime (Get-Date).AddDays(-2)
290+
291+
Filters the backups fould in c:\backups\db1 down to those created withing the last 2 days based on the standard Maintenance Solution naming convention of yyMMdd_hhmmss
288292
.NOTES
289293
Tags: DisasterRecovery, Backup, Restore
290294
Author: Stuart Moore (@napalmgram), stuart-moore.com
@@ -538,7 +542,7 @@ function Restore-DbaDatabase {
538542
}
539543
}
540544
Write-Message -Level Verbose -Message "Unverified input, full scans - $($files -join ';')"
541-
$BackupHistory += Get-DbaBackupInformation -SqlInstance $RestoreInstance -SqlCredential $SqlCredential -Path $files -DirectoryRecurse:$DirectoryRecurse -MaintenanceSolution:$MaintenanceSolutionBackup -IgnoreLogBackup:$IgnoreLogBackup -AzureCredential $AzureCredential
545+
$BackupHistory += Get-DbaBackupInformation -SqlInstance $RestoreInstance -SqlCredential $SqlCredential -Path $files -DirectoryRecurse:$DirectoryRecurse -MaintenanceSolution:$MaintenanceSolutionBackup -RestoreTime $RestoreTime-IgnoreLogBackup:$IgnoreLogBackup -AzureCredential $AzureCredential
542546
}
543547
if ($PSCmdlet.ParameterSetName -eq "RestorePage") {
544548
if (-not (Test-DbaSqlPath -SqlInstance $RestoreInstance -Path $PageRestoreTailFolder)) {

‎tests/Get-DbaBackupInformation.Tests.ps1

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Write-Host -Object "Running $PSCommandpath" -ForegroundColor Cyan
33
. "$PSScriptRoot\constants.ps1"
44

55
Describe "$commandname Integration Tests" -Tags "IntegrationTests" {
6-
6+
<#
77
BeforeAll {
88
$DestBackupDir = 'C:\Temp\GetBackups'
99
if (-Not(Test-Path $DestBackupDir)) {
@@ -49,6 +49,7 @@ Describe "$commandname Integration Tests" -Tags "IntegrationTests" {
4949
$db3 | Backup-DbaDatabase -Type Full -BackupDirectory "$DestBackupDirOla\FULL"
5050
$db3 | Backup-DbaDatabase -Type Differential -BackupDirectory "$DestBackupDirOla\Diff"
5151
$db3 | Backup-DbaDatabase -Type Log -BackupDirectory "$DestBackupDirOla\LOG"
52+
5253
}
5354
5455
AfterAll {
@@ -130,5 +131,67 @@ Describe "$commandname Integration Tests" -Tags "IntegrationTests" {
130131
}
131132
132133
}
134+
#>
135+
Context "Check Simple Maintenance Solution Filtering works" {
136+
$results = Get-DbaBackupInformation -SqlInstance $script:instance1 -Path $script:appveyorlabrepo\OlaMsFilter\Simple
137+
It "Should return 4 records without filtering"{
138+
$results.count | Should Be 4
139+
}
140+
$results = Get-DbaBackupInformation -SqlInstance $script:instance1 -Path $script:appveyorlabrepo\OlaMsFilter\Simple -MaintenanceSolution -RestoreTime (Get-Date)
141+
It "Should return 2 records with filtering" {
142+
$results.count | Should Be 2
143+
}
144+
It "Should have returned 2 specific files"{
145+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\Simple\test_LOG_20160629_141330.trn"
146+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\Simple\test_FULL_20160629_141320.bak"
147+
}
148+
}
149+
150+
Context "Check it doesn't filter without the maintenancesolution switch" {
151+
$results = Get-DbaBackupInformation -SqlInstance $script:instance1 -Path $script:appveyorlabrepo\OlaMsFilter\Simple -RestoreTime (Get-Date)
152+
It "Should return 4 records as no filtering" {
153+
$results.count | Should Be 4
154+
}
155+
}
156+
157+
Context "Check complex filtering to latest point in time"{
158+
$results = Get-DbaBackupInformation -SqlInstance $script:instance1 -Path $script:appveyorlabrepo\OlaMsFilter\Complex -MaintenanceSolution -RestoreTime (Get-Date).adddays(1)
159+
It "Should return 4 results" {
160+
$results.count | Should Be 4
161+
}
162+
It "Should retun 4 specific files" {
163+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Log\test_LOG_20160629_143000.trn"
164+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Log\test_LOG_20160629_142900.trn"
165+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Diff\test_DIFF_20160629_142800.bak"
166+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Full\test_FULL_20160629_142200.bak"
167+
}
168+
}
169+
170+
Context "Check complex filtering to point in time with diff"{
171+
#Doing the date this way to avoid any locality issues.
172+
$date = Get-date -Day 29 -Month 6 -Year 2016 -hour 14 -Minute 20 -Second 30
173+
$results = Get-DbaBackupInformation -SqlInstance $script:instance1 -Path $script:appveyorlabrepo\OlaMsFilter\Complex -MaintenanceSolution -RestoreTime $Date
174+
It "Should return 3 results" {
175+
$results.count | Should Be 3
176+
}
177+
It "Should retun 3 specific files" {
178+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Full\test_FULL_20160629_141300.bak"
179+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Log\test_LOG_20160629_142000.trn"
180+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Diff\test_DIFF_20160629_141900.bak"
181+
}
182+
}
183+
Context "Check complex filtering to point in time without diff"{
184+
#Doing the date this way to avoid any locality issues.
185+
$date = Get-date -Day 29 -Month 6 -Year 2016 -hour 14 -Minute 15
186+
$results = Get-DbaBackupInformation -SqlInstance $script:instance1 -Path $script:appveyorlabrepo\OlaMsFilter\Complex -MaintenanceSolution -RestoreTime $Date
187+
It "Should return 3 results" {
188+
$results.count | Should Be 3
189+
}
190+
It "Should retun 3 specific files" {
191+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Full\test_FULL_20160629_141300.bak"
192+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Log\test_LOG_20160629_141400.trn"
193+
$results.fullname | Should Contain "$script:appveyorlabrepo\OlaMsFilter\complex\Log\test_LOG_20160629_141500.trn"
194+
}
195+
}
133196

134197
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /