SQL Server용 Azure 확장 문제 해결
적용 대상: SQL Server
Azure Resource Graph를 쿼리하여 Azure Arc 지원 서버에서 SQL Server용 Azure 확장 상태를 식별합니다. 이 문서에서는 비정상 확장을 식별하는 쿼리를 보여 줍니다.
팁
아직 익숙하지 않은 경우 Azure Resource Graph에 대해 알아보세요.
비정상 확장 식별
이 쿼리는 확장이 설치되었지만 정상적이지 않은 서버의 SQL Server 인스턴스를 반환합니다. 날짜는 쿼리로 하드 코드됩니다. 확장 상태가 비정상이거나 확장 마지막 업로드 시간이 2024년 5월(2024/05
) 또는 2024년 6월(2024/06
)이 아닌 리소스를 반환합니다. 리소스의 날짜를 해당 날짜로 바꿉니다.
resources
| where type == "microsoft.hybridcompute/machines/extensions"
| where properties.type in ("WindowsAgent.SqlServer","LinuxAgent.SqlServer")
| where properties.instanceView.status.message !contains "SQL Server Extension Agent: Healthy" or (properties.instanceView.status.message !contains "timestampUTC : 2024/05" and properties.instanceView.status.message !contains "timestampUTC : 2024/06") or properties.instanceView.status.message !contains "uploadStatus : OK"
| project id, resourceGroup, subscriptionId,
ExtensionHealth = iif(properties.instanceView.status.message !contains "SQL Server Extension Agent: Healthy", "Unhealthy", "Healthy"),
LastUploadTimestamp = iif(indexof(properties.instanceView.status.message,"timestampUTC : ") > 0, iif(properties.instanceView.status.message !contains "timestampUTC : 2024/06", substring(properties.instanceView.status.message,indexof(properties.instanceView.status.message,"timestampUTC : ") + 15, 10),"Recent"),"no timestamp"),
LastUploadStatus = iif(indexof(properties.instanceView.status.message,"uploadStatus : OK") > 0, "OK", "Unhealthy"),
Message = properties.instanceView.status.message
가능한 특정 문제를 식별하려면 쿼리 결과에서 메시지 속성의 값을 검토합니다.
비정상 확장 식별(PowerShell)
이 예제는 PowerShell에서 실행됩니다. PowerShell을 사용하면 하드 코드되지 않은 날짜로 실행할 수 있습니다. 이 예에서는 확장 상태가 비정상이거나 확장 마지막 업로드 시간이 이번 달 또는 이전 달이 아닌 리소스를 반환합니다.
# PowerShell script to execute an Azure Resource Graph query using Azure CLI
# where the extension status is unhealthy or the extension last upload time isn't in this month or the previous month.
# Requires the Az.ResourceGraph PowerShell module
# Login to Azure if needed
#az login
$currentYear = (Get-Date).Year
$currentMonth = "{0:D2}" -f (Get-Date).Month
$previousMonth = "{0:D2}" -f ((Get-Date).Month-1)
$currentDay = "{0:D2}" -f (Get-Date).Day
$currentYearMonth = "$currentYear/$currentMonth"
$previousYearMonth = "$currentYear/$previousMonth"
$currentDate = "$currentYear/$currentMonth/$currentDay"
# Define the Azure Resource Graph query
$query = @"
Resources
| where type == 'microsoft.hybridcompute/machines/extensions'
| where properties.type in ('WindowsAgent.SqlServer','LinuxAgent.SqlServer')
| where properties.instanceView.status.message !contains 'SQL Server Extension Agent: Healthy'
or (properties.instanceView.status.message !contains 'timestampUTC : $previousYearMonth'
and properties.instanceView.status.message !contains 'timestampUTC : $currentYearMonth')
or properties.instanceView.status.message !contains 'uploadStatus : OK'
| project id, resourceGroup, subscriptionId,
ExtensionHealth = iif(properties.instanceView.status.message !contains 'SQL Server Extension Agent: Healthy', 'Unhealthy', 'Healthy'),
LastUploadTimestamp = iif(indexof(properties.instanceView.status.message,'timestampUTC : ') > 0, iif(properties.instanceView.status.message !contains 'timestampUTC : $currentYearMonth', substring(properties.instanceView.status.message,indexof(properties.instanceView.status.message,'timestampUTC : ') + 15, 10),'Recent'),'no timestamp'),
LastUploadStatus = iif(indexof(properties.instanceView.status.message,'uploadStatus : OK') > 0, 'OK', 'Unhealthy'),
Message = properties.instanceView.status.message
"@
# Execute the Azure Resource Graph query
$result = Search-AzGraph -Query $query
# Output the results
$result | Format-Table -Property ExtensionHealth, LastUploadTimestamp, LastUploadStatus, Message
가능한 특정 문제를 식별하려면 결과에서 메시지 열의 값을 검토하세요.
업데이트 누락된 확장 식별
최근 상태를 업데이트하지 않은 확장을 식별합니다. 이 쿼리는 확장이 마지막으로 상태를 업데이트한 이후 일 수로 정렬된 SQL Server용 Azure 확장 목록을 반환합니다. 값 '-1'은 확장이 중단되었으며 확장 상태에 호출 스택이 있음을 나타냅니다.
// Show the timestamp extracted
// If an extension has crashed (i.e. no heartbeat), fill timestamp with "1900/01/01, 00:00:00.000"
//
resources
| where type =~ 'microsoft.hybridcompute/machines/extensions'
| extend extensionStatus = parse_json(properties).instanceView.status.message
| extend timestampExtracted = extract(@"timestampUTC\s*:\s*(\d{4}/\d{2}/\d{2}, \d{2}:\d{2}:\d{2}\.\d{3})", 1, tostring(extensionStatus))
| extend timestampNullFilled = iff(isnull(timestampExtracted) or timestampExtracted == "", "1900/01/01, 00:00:00.000", timestampExtracted)
| extend timestampKustoFormattedString = strcat(replace(",", "", replace("/", "-", replace("/", "-", timestampNullFilled))), "Z")
| extend agentHeartbeatUtcTimestamp = todatetime(timestampKustoFormattedString)
| extend agentHeartbeatLagInDays = datetime_diff('day', now(), agentHeartbeatUtcTimestamp)
| project id, extensionStatus, agentHeartbeatUtcTimestamp, agentHeartbeatLagInDays
| limit 100
| order by ['agentHeartbeatLagInDays'] asc
이 쿼리는 확장이 마지막으로 상태를 업데이트한 이후 일 수로 그룹화된 확장 수를 반환합니다. 값 '-1'은 확장이 중단되었으며 확장 상태에 호출 스택이 있음을 나타냅니다.
// Aggregate by timestamp
//
// -1: Crashed extension with no heartbeat, we got a stacktrace instead
// 0: Healthy
// >1: Stale/Offline
//
resources
| where type =~ 'microsoft.hybridcompute/machines/extensions'
| extend extensionStatus = parse_json(properties).instanceView.status.message
| extend timestampExtracted = extract(@"timestampUTC\s*:\s*(\d{4}/\d{2}/\d{2}, \d{2}:\d{2}:\d{2}\.\d{3})", 1, tostring(extensionStatus))
| extend timestampNullFilled = iff(isnull(timestampExtracted) or timestampExtracted == "", "1900/01/01, 00:00:00.000", timestampExtracted)
| extend timestampKustoFormattedString = strcat(replace(",", "", replace("/", "-", replace("/", "-", timestampNullFilled))), "Z")
| extend agentHeartbeatUtcTimestamp = todatetime(timestampKustoFormattedString)
| extend agentHeartbeatLagInDays = iff(agentHeartbeatUtcTimestamp == todatetime("1900/01/01, 00:00:00.000Z"), -1, datetime_diff('day', now(), agentHeartbeatUtcTimestamp))
| summarize numExtensions = count() by agentHeartbeatLagInDays
| order by numExtensions desc