This monitor checks if database mirror witness is accessible.
This monitor checks the status of the database mirroring witness as reported by Microsoft® SQL Server™. This is done by running a query against the master database of the SQL Server instance and returning the state of the database mirroring witness. If you receive an alert from this monitor, action is required in order to bring the database mirroring witness back to an operational state.
An unhealthy state indicates that the SQL Server™ database mirroring witness is currently unavailable. All states except CONNECTED and NO-WITNESS will cause an unhealthy state. The possible states are detailed below:
Mirroring Witness State | Description | MOM Health State |
CONNECTED | This is normal operational state. Mirroring Partner can access the Witness server. | HEALTHY |
NO-WITNESS | This is a custom state that is shown when Mirroring is configured without witness. This state indicates that there is no Witness specified for the mirroring session. It is normal operational state for High-Performance Mode and High-Safety Mode Without Automatic Failover. | HEALTHY |
UNKNOWN | There are some issues with connection between Mirroring Partner and Witness server. | WARNING |
DISCONNECTED | There is no connection between Mirroring Partner and Witness server. | CRITICAL |
To resolve the issue try the following:
Make sure mirroring configuration is complete and mirroring process is up and running.
Check physical link between Mirroring Partner and Witness server.
Configure firewall rules on both servers according to endpoints configuration.
Name | Description | Default Value |
Alert Priority | Defines Alert Priority. | Normal |
Alert Severity | Defines Alert Severity. | MatchMonitorHealth |
Enabled | Enables or disables the workflow. | Yes |
Generates Alerts | Defines whether the workflow generates an Alert. | Yes |
Interval (seconds) | The recurring interval of time in seconds in which to run the workflow. | 900 |
Synchronization Time | The synchronization time specified by using a 24-hour format. May be omitted. |
|
Timeout (seconds) | Specifies the time the workflow is allowed to run before being closed and marked as failed. | 300 |
Target | Microsoft.SQLServer.2014.Mirroring.Database | ||
Parent Monitor | System.Health.AvailabilityState | ||
Category | AvailabilityHealth | ||
Enabled | True | ||
Alert Generate | True | ||
Alert Severity | MatchMonitorHealth | ||
Alert Priority | Normal | ||
Alert Auto Resolve | True | ||
Monitor Type | Microsoft.SQLServer.2014.Mirroring.ScriptedThreeStateType | ||
Remotable | True | ||
Accessibility | Public | ||
Alert Message |
| ||
RunAs | Microsoft.SQLServer.2014.SQLProbeAccount |
<UnitMonitor ID="Microsoft.SQLServer.2014.Mirroring.WitnessStateMonitor" Accessibility="Public" Enabled="true" Target="SQL2014Mirroring!Microsoft.SQLServer.2014.Mirroring.Database" ParentMonitorID="Health!System.Health.AvailabilityState" TypeID="Microsoft.SQLServer.2014.Mirroring.ScriptedThreeStateType" Remotable="true" Priority="Normal" ConfirmDelivery="false" RunAs="SQL2014Core!Microsoft.SQLServer.2014.SQLProbeAccount">
<Category>AvailabilityHealth</Category>
<AlertSettings AlertMessage="Microsoft.SQLServer.2014.Mirroring.WitnessStateMonitor.AlertMessage">
<AlertOnState>Warning</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>MatchMonitorHealth</AlertSeverity>
<AlertParameters>
<AlertParameter1>$Target/Property[Type="SQL2014Core!Microsoft.SQLServer.2014.Database"]/DatabaseName$</AlertParameter1>
<AlertParameter2>$Target/Host/Property[Type="SQL2014Core!Microsoft.SQLServer.2014.ServerRole"]/InstanceName$</AlertParameter2>
<AlertParameter3>$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</AlertParameter3>
<AlertParameter4>$Target/Property[Type="SQL2014Mirroring!Microsoft.SQLServer.2014.Mirroring.Database"]/Witness$</AlertParameter4>
</AlertParameters>
</AlertSettings>
<OperationalStates>
<OperationalState ID="Good" MonitorTypeStateID="Good" HealthState="Success"/>
<OperationalState ID="NeitherGoodNorBad" MonitorTypeStateID="NeitherGoodNorBad" HealthState="Warning"/>
<OperationalState ID="Bad" MonitorTypeStateID="Bad" HealthState="Error"/>
</OperationalStates>
<Configuration>
<ScriptName>GetSQL2014MirroringWitnessState.vbs</ScriptName>
<ScriptBody> '#Include File:GetSQL2014MirroringWitnessState.vbs
'Copyright (c) Microsoft Corporation. All rights reserved.
' This script takes a single parameter
' Param 0: The SQL connection string to connect to
Const SQL_MONITORING_CONNECT_FAILURE = -1
Const SQL_MONITORING_QUERY_FAILURE = -2
Const SQL_MONITORING_SUCCESS = 0
Const SCRIPT_EVENT_ID = 4201
Dim GetWitnessStatusQuery
GetWitnessStatusQuery = "SELECT " &_
" d.name, " &_
" CASE WHEN dm.mirroring_witness_name = '' THEN 'NO-WITNESS' ELSE ISNULL(dm.mirroring_witness_state_desc, 'UNKNOWN') END " &_
" FROM sys.databases d " &_
" INNER JOIN sys.database_mirroring dm ON dm.database_id = d.database_id " &_
" WHERE dm.mirroring_guid IS NOT NULL"
Call GetWitnessAccessibility()
Sub GetWitnessAccessibility()
If WScript.Arguments.Count = 4 Then
Dim oBag
Set oBag = oAPI.CreatePropertyBag()
Dim state, serviceName
serviceName = GetSQLServiceName(WScript.Arguments(2))
state = GetServiceState(WScript.Arguments(1), serviceName)
if (state <> "Running") And (state <> "Unknown") Then
Call oAPI.Return(oBag)
WScript.Quit()
End If
Dim nResult
nResult = WitnessAccessibility(WScript.Arguments(0), oBag, WScript.Arguments(1), WScript.Arguments(2), WScript.Arguments(3))
Call oAPI.Return(oBag)
Call GlobalErrorListToEventLog()
Else
Wscript.Quit()
End If
End Sub
Function WitnessAccessibility(ByVal sSQLConnectionString, ByRef oBag, ByVal sComputerName, ByVal sInstanceName, ByVal sTcpPort)
Dim e
Set e = New Error
Dim cnADOConnection
Set cnADOConnection = SmartConnectWithoutSQLADODB(sSQLConnectionString, sTcpPort, sComputerName, sInstanceName, "master")
if cnADOConnection Is Nothing Then
WitnessAccessibility = SQL_MONITORING_CONNECT_FAILURE
Exit Function
End If
Dim oResults
e.Clear
On Error Resume Next
Set oResults = cnADOConnection.Execute(GetWitnessStatusQuery)
e.Save
On Error Goto 0
If e.Number <> 0 Then
WitnessAccessibility = SQL_MONITORING_QUERY_FAILURE
ThrowScriptErrorNoAbort "Query execution failed", e
If (oResults <> null) Then oResults.Close
cnADOConnection.Close
Exit Function
End If
Do While Not oResults.EOF
Call oBag.AddValue(oResults(0) & "-State", CStr(oResults(1)))
oResults.MoveNext
Loop
cnADOConnection.Close
WitnessAccessibility = SQL_MONITORING_SUCCESS
End Function
</ScriptBody>
<IntervalSeconds>900</IntervalSeconds>
<SyncTime/>
<TimeoutSeconds>300</TimeoutSeconds>
<ConnectionString>$Target/Host/Property[Type="SQL2014Core!Microsoft.SQLServer.2014.DBEngine"]/ConnectionString$</ConnectionString>
<GoodExpression>
<Or>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='$Target/Property[Type="SQL2014Core!Microsoft.SQLServer.2014.Database"]/DatabaseName$-State']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">CONNECTED</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='$Target/Property[Type="SQL2014Core!Microsoft.SQLServer.2014.Database"]/DatabaseName$-State']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">NO-WITNESS</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</Or>
</GoodExpression>
<NeitherGoodNorBadExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='$Target/Property[Type="SQL2014Core!Microsoft.SQLServer.2014.Database"]/DatabaseName$-State']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">UNKNOWN</Value>
</ValueExpression>
</SimpleExpression>
</NeitherGoodNorBadExpression>
<BadExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='$Target/Property[Type="SQL2014Core!Microsoft.SQLServer.2014.Database"]/DatabaseName$-State']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">DISCONNECTED</Value>
</ValueExpression>
</SimpleExpression>
</BadExpression>
</Configuration>
</UnitMonitor>