Articles in the "Database seeding estimation" series
- Estimate the time to complete seeding a mailbox database copy [This article]
- Database seeding completion estimate script updated
Seeding a mailbox database copy, especially across a WAN, can take days to complete. The shell doesn’t give any indication of the time it will complete, though it does show a progress bar and the amount of data written. If you want to know when the seeding will actually finish, you can extrapolate this from the throughput of the seeding, dividing that into the amount of data remaining to be copied.
The throughput of a copy being seeded is available as a performance counter, as are the percentage complete and the amount written. Using this information I wrote a script to estimate the date and time the database seeding will complete. Because throughput can vary greatly from second to second, the default sample duration is 60 seconds. You can specify any number of seconds, choosing accuracy or impatience. Retrieving performance counters can take some time (not even counting any sampling you may do), so a progress indicator will indicate any time that is occurring. (Three separate queries for performance counters occur to provide the output.)
To run the script, provide a database copy and, optionally, a sample duration. The copy will be validated that it is being seeded, then the seeding throughput will be retrieved for 60 seconds or the duration you specified. Then the amount of data written so far is retrieved, comparing that to the total size of the database, so that the remaining amount can be determined. That amount is divided by the average throughput during the sample duration and calculating the time it will be done. Bear in mind that this calculation does not include the time to seed the content index or copy and replay transaction logs that have been generated since seeding began. The output will show the percentage of the database size that has been seeded thus far and the estimated date and time the seeding will complete.
You can copy the code below or download the script via the link.
Get-DatabaseSeedingCompletion.zip (1.5 KiB)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
<# .Synopsis Estimate time of completion for database seeding .Description Using a customizable sample duration of the seeding throughput for a database copy, the script estimates the date and time the seeding will complete. This does not include the time to seed the content index or copy transaction logs that have been accruing since the seeding started. .Parameter Identity The identity of a database copy, using the format Database\Server. .Parameter SampleDuration The number of seconds (in one-second intervals) to monitor the seeding throughput in order to calculate the completion time. The default is 60 seconds. .Example Get-DatabaseSeedingCompletion.ps1 -Identity database1\server2 .Example Get-DatabaseSeedingCompletion.ps1 -Identity database2\serverA -SampleDuration 360 .Notes Version: 1.1 Date: 11/22/13 #> param ( [parameter(Mandatory=$true,Position=0)][string]$Identity, [parameter(Mandatory=$false,Position=1)][int]$SampleDuration = 60 ) $database = $Identity.Substring(0,$Identity.IndexOf('\')) $server = $Identity.Substring($Identity.IndexOf('\') + 1) $showProgress = $true while ($showProgress -eq $true) { Write-Progress -Activity 'Getting seeding progress percentage...' -Status 'Retrieving' $percentCompleteCounter = Get-Counter -ComputerName $server -Counter "\MSExchange Replica Seeder($database)\Database Seeding Progress %" -ErrorAction 'SilentlyContinue' $showProgress = $false Write-Progress -Activity 'Getting seeding progress percentage...' -Status 'Retrieving' -Completed } if (-not($percentCompleteCounter)) { Write-Warning -Message "$Identity is not currently being seeded." } else { $percentComplete = $percentCompleteCounter.CounterSamples[0].CookedValue #Get seeding throughput $showProgress = $true while ($showProgress -eq $true) { Write-Progress -Activity 'Getting seeding throughput...' -Status "Sampling for $SampleDuration seconds" $kBytesWrittenPerSecondCounter = Get-Counter -ComputerName $server -Counter "MSExchange Replica Seeder($database)\Database Seeding Bytes Written (KB/sec)" -MaxSamples $SampleDuration $showProgress = $false Write-Progress -Activity 'Getting seeding throughput...' -Status 'Sampling' -Completed } $kBytesWrittenPerSecondAverage = $kBytesWrittenPerSecondCounter | ForEach-Object {$_.CounterSamples[0].CookedValue} | Measure-Object -Average | Select-Object -ExpandProperty Average if ($kBytesWrittenPerSecondAverage -eq 0) { Write-Warning -Message 'Cannot estimate completion time because throughput for the sampling period is 0 KB.' } else { #Get bytes written so far $showProgress = $true while ($showProgress -eq $true) { Write-Progress -Activity 'Getting seeding amount written so far...' -Status 'Retrieving' $kBytesWrittenCounter = Get-Counter -ComputerName $server -Counter "MSExchange Replica Seeder($database)\Database Seeding Bytes Written (KB)" $showProgress = $false Write-Progress -Activity 'Getting seeding amount written so far...' -Status 'Retrieving' -Completed } $kBytesWrittenValue = $kBytesWrittenCounter.CounterSamples[0].CookedValue #Get DB size to calculate remaining amount $dbSizeRaw = (Get-MailboxDatabase -Identity $database -Status).DatabaseSize if ($dbSizeRaw.GetType().Name -eq 'ByteQuantifiedSize') #Object type when using EMS { $dbSize = $dbSizeRaw.ToBytes() } else { #Object type when using remoting is string $dbSize = [int64]($dbSizeRaw.Split("(")[1].Split()[0]) } $KBRemaining = $dbSize/1KB - $kBytesWrittenValue $estimatedMinutesToCompletion = $KBRemaining/$kBytesWrittenPerSecondAverage/60 $completionTime = (Get-Date).AddMinutes($estimatedMinutesToCompletion) $outputObject = "" | Select-Object -Property Identity,PercentComplete,'Throughput(MB/sec)',EstimatedCompletion $outputObject.Identity = $Identity $outputObject.PercentComplete = $percentComplete $outputObject.'Throughput(MB/sec)' = [math]::Round($kBytesWrittenPerSecondAverage/1024,1) $outputObject.EstimatedCompletion = "{0:g}" -f $completionTime $outputObject } } |
Pingback: TOAA: Lokalisierte Server Software (oder auch: man lernt nie aus) | m-arx and the world.
Exactly what I was looking for! Thanks for writing this!
is working as expected …
thanks a lot ….. also as Jamie – exactly what I was looking for
Thanks, great script.
Thank you, great script
thank you very much! brilliant script
Should this work for Exchange 2013 as well? I initiated a reseed of a complete server yesterday (29 DB’s, ca. 2 TB of data) and when I ran this script this morning it concluded “Could not calculate remaining time because throughput in the sampling interval was 0 kb”. Does that REALLY mean it just hasn’t been doing anything for the past 16 hours or so?
Great script. Gave me exactly what I needed! Thanks.
Yes, it works with Exchange 2013 as the performance counters are the same. Throughput of 0 KB during the sampling period only means that no data was being written to the database during the time the script was looking at the performance counters. I can modify the script, however, to report the percentage completed even if it can’t tell when it will be completed.
Literally just what I needed. Thanks a lot for writing this!