As Microsoft states as best practices :
"Monitoring online defragmentation enables you to verify that defragmentation of every Exchange database is completing often enough (at least every two weeks, as a best practice). Monitoring online defragmentation may also enable you to decrease the online maintenance window, which has the following advantages:
- Allows more time for database backup.
- Validates that online checksumming and page zeroing can be introduced within the current online maintenance window.
- Extended information for Event 703 allows you to more easily monitor online defragmentation pass completions.
- Two extended Extensible Storage Engine (ESE) performance counters for monitoring the effectiveness and efficiency of online defragmentation have been added for use with Performance Monitor (which is called Reliability and Performance Monitor in Windows Server 2008)."
With errors (not completed)
Name : DATABASE1-SG04
Identity : SERVER\STORAGEGROUP\DATABASE1-SG04
EdbFilePath : N:\STORAGEGROUP\DATABASE1-SG04
.edb
DefragStart :
DefragEnd :
DefragDuration :
DefragInvocations :
DefragDays :
DefragInterrupts :
DefragError : unexpected error :-327.--> this is a critical error, you shold repair the DB (http://technet.microsoft.com/en-us/library/bb218265(EXCHG.80).aspx)DefragStillRunningSince : 20/01/2011
DefragStillRunningDays : 13 ----> 13 days running
Without errors (completed)
Name : DATABASE-SG05
Identity : SERVER\STORAGEGROUP\DATABASE-SG05
EdbFilePath : P:\DATABASE\DATABASE-SG05.edb
DefragStart : 03/02/2011 04:54
DefragEnd : 03/02/2011 04:54
DefragDuration : 28976 seconds.
DefragInvocations : 2 time[s].
DefragDays : 1
DefragInterrupts : 03/02/2011 09:59 ---> Backup interruptions
DefragError :
DefragStillRunningSince :
DefragStillRunningDays :
The event 705 is preceded for the event 447 , this issue indicates that a corrupt page link was detected in a B-Tree.
Explanation:
Online defragmentation has failed because of some issues in this tree. Event 447 suggests that a B-tree consists a corrupt page link. The most common reasons for this problem to occur are:
- Hardware failure
- Antivirus software scanning of Exchange database directory (Antivirus's Exclisions for Exchange 2007)
Note: It is not safe to continue using such corrupted database as a bad page link indicates logical database corruption at ESE level. Also, you should ensure that no antivirus software is scanning the Exchange database files.
Solution:
- Check the Application log carefully for related events and patterns that may relate to this event. Check the System log carefully for related events and patterns including any errors related to hardware, drives, controllers, or the file system. If there are any such errors, replace the hardware, update the hardware system files, or repair the file system to prevent any future errors. Do this before proceeding to the next step
- If the Exchange store database is running, use ExMerge to merge your data to .pst files, delete the database, create a blank database, and then run ExMerge t databases to a blank database.
- If the database is running, you may also move all the mailboxes to another store, delete the affected database, create a new database, and then move all the mailboxes back.
- If the Exchange store database will not mount, the suggested remedy is to restore from online backup before the errors appear in the Application log.
- If the Exchange store database will not mount and there is no backup, the last resort is to repair the database by running eseutil /p and then repeatedly running isinteg -fix until there are no fixes reported. Finally, run ExMerge, create a blank store, and use ExMerge to move the data back in.
$srv = Get-ExchangeServer |where {$_.IsMailboxServer -eq 'True'}
$output = @()
$dmtf = [System.Management.ManagementDateTimeconverter]
$Startdate = $dmtf::ToDmtfDateTime( (Get-Date).AddDays(-1).Date )
$free = @{Name="WhiteSpace(MB)";Expression={[int]$_.InsertionStrings[0]}}
foreach ($dbserver in $srv){
# Get the mailbox databases from the server
$mbdatabases = Get-MailboxDatabase -Server $dbserver.name | Sort-Object -Property Name
# Get the public folder databases from the server
$pfdatabases = Get-PublicFolderDatabase -Server $dbserver.name | Sort-Object -Property Name
# Create an array for the databases
$databases = @()
# Check if mailbox databases were found on the server
If ($mbdatabases) {
# Loop through the databases
ForEach ($mdb in $mbdatabases) {
# Create an object to store information about the database
$db = "" | Select-Object Name,Identity,EdbFilePath,DefragStart,DefragEnd,DefragDuration,DefragInvocations,DefragDays,DefragInterrupts,DefragError,DefragStillRunningSince,DefragStillRunningDays
# Populate the object
$db.Name = $mdb.Name.ToString()
$db.Identity = $mdb.Identity.ToString()
$db.EdbFilePath = $mdb.EdbFilePath.ToString()
# Add this database to the array
$databases = $databases + $db
}
}
# Check if public folder databases were found on the server
If ($pfdatabases) {
# Loop through the databases
ForEach ($pfdb in $pfdatabases) {
# Create an object to store information about the database
$db = "" | Select-Object Name,Identity,EdbFilePath,DefragStart,DefragEnd, DefragDuration,DefragInvocations,DefragDays,DefragInterrupts,DefragError,DefragStillRunningSince,DefragStillRunningDays
# Populate the object
$db.Name = $pfdb.Name.ToString()
$db.Identity = $pfdb.Identity.ToString()
$db.EdbFilePath = $pfdb.EdbFilePath.ToString()
# Add this database to the array
$databases = $databases + $db
}
}
# Retrieve the events from the local Application log, filter them for ESE messages
$logs = Get-WMIObject Win32_NTLogEvent -ComputerName $dbserver.name -Filter "LogFile='Application' AND Timewritten>='$startdate' AND sourceName='ESE' AND CategoryString='Online Defragmentation' "
# Loop through each of the databases and search the event logs for relevant messages
ForEach ($db in $databases) {
# Create the search string to look for in the Message property of each log entry
$s = "*" + $db.EdbFilePath + "*"
# Search for an event 701 or 703, meaning that online defragmentation finished
$end = $logs | where {
$_.Message -like "$s" -and ($_.eventcode -eq 701 -or $_.eventcode -eq 703)
} | select-object -First 1
# Search for the first event 700 which preceeds the finished event
$start = $logs | where {
$_.Message -like "$s" -and $_.eventcode -eq 700 -and $_.Index -le $end.Index
} | select-object -First 1
$interr = $logs | where {
$_.Message -like "$s" -and $_.eventcode -eq 704
} | select-object -First 1
$defError = $logs | where {
$_.Message -like "$s" -and $_.eventcode -eq 705
} | select-object -First 1
$defStillRun = $logs | where {
$_.Message -like "$s" -and $_.eventcode -eq 702
} | select-object -First 1
# Make sure we found both a start and an end message
if ($start -and $end ) {
# Get the start and end times
$st= $start.TimeGenerated
$stY=$st.substring(0,4)
$stM=$st.substring(4,2)
$stD=$st.substring(6,2)
$stH=$st.substring(8,2)
$stMs=$st.substring(10,2)
$et= $end.TimeGenerated
$etY=$et.substring(0,4)
$etM=$et.substring(4,2)
$etD=$et.substring(6,2)
$etH=$et.substring(8,2)
$etMs=$et.substring(10,2)
$db.DefragStart = $stD + "/" + $stM + "/" + $stY + " " + $stH + ":" + $stMs
$db.DefragEnd = $etD + "/" + $etM + "/" + $etY + " " + $etH + ":" + $etMs
# Parse the end event message for the number of seconds defragmentation ran for
$end.Message -match "This pass started on .* and ran for a total of .* seconds" >$null
#$db.DefragStart = $Matches[0].Split(" ")[4] + " restarted."
$db.DefragDuration = $Matches[0].Split(" ")[11] + " seconds."
# Parse the end event message for the number of invocations and days
$end.Message -match "requiring .* invocations over .* days" > $null
$db.DefragInvocations = $Matches[0].Split(" ")[1] + " time[s]."
$db.DefragDays = $Matches[0].Split(" ")[4]
#$interr.Message -match "was interrupted and terminated." >$null
if ($interr) {
$it= [string]$interr.TimeGenerated
$itY=$it.substring(0,4)
$itM=$it.substring(4,2)
$itD=$it.substring(6,2)
$itH=$it.substring(8,2)
$itMs=$it.substring(10,2)
$db.DefragInterrupts=$itD + "/" + $itM + "/" + $itY + " " + $itH + ":" + $itMs
}
} else {
if ($defError -and $defStillRun) {
$defError.Message -match "after encountering unexpected error .*" >$null
$db.DefragError = "unexpected error :" + $Matches[0].Split(" ")[4]
$defStillRun.Message -match "pass started on .* and has been running for .* days" >$null
$db.DefragStillRunningSince = $Matches[0].Split(" ")[3]
$db.DefragStillRunningDays = $Matches[0].Split(" ")[9]
}
}
# Add the data for this database to the output
$output = $output + $db
}
}
# Print the output
$output
------end code
Don't worry...be happy.
-Dario
Remarkable issues here. I'm very satisfied to see your post. Thanks so much and I'm having a look forward to contact you. Will you kindly drop me a e-mail?
ReplyDeletemy web site - Repair edb files
I'm glad to help!!! please feel free to contact me at dario.may@gmail.com
Delete