你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

排查 Azure Arc 部署启用的 SQL 托管实例问题

本文介绍了潜在问题,并介绍了如何诊断已启用 Azure Arc 的数据服务的部署这些问题的根本原因。

连接到 Azure Arc 启用的 SQL 托管实例故障转移组

本部分介绍如何排查连接到故障转移组时遇到的问题。

检查故障转移组连接与同步状态

kubectl -n $nameSpace get fog $fogName -o jsonpath-as-json='{.status}'

结果:

在每端,一个故障转移组都有两个副本。 检查每个副本的 connectedStatesynchronizationState 的值。

如果其中一个 connectedState 不等于 CONNECTED,请参阅检查参数下的说明。

如果其中一个 synchronizationState 不等于 HEALTHY,请关注 synchronizationState 不等于 HEALTHY 的实例。 请参阅无法连接到 Azure Arc 启用的 SQL 托管实例

检查参数

在异地主数据库和异地辅助数据库上,针对另一端的 $sqlmiName 实例检查故障转移规范。

本地端命令

针对本地实例运行以下命令,以获取本地实例的规范。

kubectl -n $nameSpace get fog $fogName -o jsonpath-as-json='{.spec}'

远程端命令

针对远程实例运行以下命令:

kubectl -n $nameSpace get sqlmi $sqlmiName -o jsonpath-as-json='{.status.highAvailability.mirroringCertificate}'
kubectl -n $nameSpace get sqlmi $sqlmiName -o jsonpath-as-json='{.status.endpoints.mirroring}'

结果:

将远程实例的结果与本地实例的结果进行比较。

  • 本地实例中的 partnerMirroringURLpartnerMirroringCert 必须匹配来自以下位置的远程实例值:

    • kubectl -n $nameSpace get sqlmi $sqlmiName -o jsonpath-as-json='{.status.endpoints.mirroring}'
    • kubectl -n $nameSpace get sqlmi $sqlmiName -o jsonpath-as-json='{.status.highAvailability.mirroringCertificate}'
  • kubectl -n $nameSpace get fog $fogName -o jsonpath-as-json='{.spec}' 中的 partnerMI 必须与远程实例的 $sqlmiName 匹配。

  • kubectl -n $nameSpace get fog $fogName -o jsonpath-as-json='{.spec}' 中的 sharedName 是可选的。 如果未显示,则它与 sourceMI 相同。 如果显示,则两个网站的 sharedName 应该相同。

  • kubectl -n $nameSpace get fog $fogName -o jsonpath-as-json='{.spec}' 中的角色应在两个站点之间有所不同。 一侧应该是主要端,另一端应该是辅助端。

如果描述的任何值与比较不匹配,请删除两个站点上的故障转移组并重新创建。

如果没有错误,请按照检查两端的镜像终结点下的说明进行操作。

检查两端的镜像终结点

在异地主数据库和异地辅助数据库上,通过以下命令公开外部镜像终结点。

kubectl -n test get services $sqlmiName-external-svc -o jsonpath-as-json='{.spec.ports}'

结果

  • 应该在列表中显示 port-mssql-mirroring。 另一端的故障转移组应对 partnerMirroringURL 使用相同的值。 如果值不匹配,请更正错误并从头开始重试。

验证 SQL Server 是否可以访问另一站点的外部终结点

尽管无法直接 ping 另一站点的镜像终结点,但请使用以下命令访问 SQL Server 表格格式数据流 (TDS) 端口的另一端外部终结点。

kubectl exec -ti -n $nameSpace $sqlmiName-0 -c arc-sqlmi -- /opt/mssql-tools/bin/sqlcmd -S $remotePrimaryEndpoint -U $remoteUser -P $remotePassword -Q "SELECT @@ServerName"

结果

如果 SQL Server 可以使用外部终结点 TDS,则很有可能会到达外部镜像终结点,因为它们在同一服务中定义和激活,特别是 $sqlmiName-external-svc

无法连接到由 Azure Arc 启用的 SQL 托管实例

本部分确定了排查与 Azure Arc 启用的 SQL 托管实例的连接问题的具体步骤。

注意

如果实例许可证类型为 DisasterRecovery,则无法连接到 Azure Arc 启用的 SQL 托管实例。

检查托管实例状态

SQL 托管实例 (SQLMI) 状态信息指示实例是否已就绪。

kubectl -n $nameSpace get sqlmi $sqlmiName -o jsonpath-as-json='{.status}'

结果

状态应为 Ready。 如果值不为 Ready,则需要等待。 如果状态为错误,请获取消息字段、收集日志并联系支持人员。 请参阅收集日志

检查有状态集的路由标签

有状态集的路由标签用于将外部终结点路由到匹配的 Pod。 标签的名称为 role.ag.mssql.microsoft.com

kubectl -n $nameSpace get pods $sqlmiName-0 -o jsonpath-as-json='{.metadata.labels}'
kubectl -n $nameSpace get pods $sqlmiName-1 -o jsonpath-as-json='{.metadata.labels}'
kubectl -n $nameSpace get pods $sqlmiName-2 -o jsonpath-as-json='{.metadata.labels}'

结果

如果未找到主节点,请终止没有任何 role.ag.mssql.microsoft.com 标签的 Pod。 如果这样做无法解决问题,请收集日志并联系支持人员。 请参阅收集日志

从本地容器连接获取副本状态

使用 localhost,1533statefulset 的每个副本中连接 sql。 此连接应始终成功。 使用此连接查询 SQL HA 副本状态。

kubectl exec -ti -n $nameSpace $sqlmiName-0 -c arc-sqlmi -- /opt/mssql-tools/bin/sqlcmd -S localhost,1533 -U $User -P $Password -Q "SELECT * FROM sys.dm_hadr_availability_replica_states"
kubectl exec -ti -n $nameSpace $sqlmiName-1 -c arc-sqlmi -- /opt/mssql-tools/bin/sqlcmd -S localhost,1533 -U $User -P $Password -Q "SELECT * FROM sys.dm_hadr_availability_replica_states"
kubectl exec -ti -n $nameSpace $sqlmiName-2 -c arc-sqlmi -- /opt/mssql-tools/bin/sqlcmd -S localhost,1533 -U $User -P $Password -Q "SELECT * FROM sys.dm_hadr_availability_replica_states"

结果

所有副本都应连接并正常工作。 下面是查询结果 sys.dm_hadr_availability_replica_states 的详细说明。

如果发现它未同步或未意外连接,请尝试终止有问题的 Pod。 如果问题仍然存在,请收集日志并联系支持人员。 请参阅收集日志

注意

如果实例中有一些大型数据库,则到辅助数据库的种子设定过程可能需要一段时间。 如果发生这种情况,请等待种子设定完成。

检查 SQLMI SQL 引擎侦听器

SQL 引擎侦听器是将连接路由到故障转移组的组件。

kubectl exec -ti -n $nameSpace $sqlmiName-0 -c arc-sqlmi -- /opt/mssql-tools/bin/sqlcmd -S localhost,1433 -U $User -P $Password -Q "SELECT @@ServerName"
kubectl exec -ti -n $nameSpace $sqlmiName-1 -c arc-sqlmi -- /opt/mssql-tools/bin/sqlcmd -S localhost,1433 -U $User -P $Password -Q "SELECT @@ServerName"
kubectl exec -ti -n $nameSpace $sqlmiName-2 -c arc-sqlmi -- /opt/mssql-tools/bin/sqlcmd -S localhost,1433 -U $User -P $Password -Q "SELECT @@ServerName"

结果

应从每个副本的 Listener 获取 ServerName。 如果无法获取 ServerName,请终止有问题的 Pod。 如果问题在恢复后仍然存在,请收集日志并联系支持人员。 请参阅收集日志

检查 Kubernetes 网络连接

在 Kubernetes 群集中,顶部有 Kubernetes 网络,允许 Pod 和路由之间通信。 检查 SQLMI Pod 是否可以通过群集 IP 相互通信。 针对所有副本运行此项。

kubectl exec -ti -n $nameSpace $sqlmiName-0 -c arc-sqlmi -- /opt/mssql-tools/bin/sqlcmd -S $(kubectl -n test get service $sqlmiName-p-svc -o jsonpath={'.spec.clusterIP'}),1533 -U $User -P $Password -Q "SELECT @@ServerName"

结果

应该能够从另一个 Pod 访问有状态集的 Pod 的任何群集 IP 地址。 如果不是这种情况,请参阅 Kubernetes 文档 - 群集网络以获取详细信息或获取服务提供商来解决此问题。

检查 Kubernetes 负载均衡器或 nodeport 服务

负载均衡器或 nodeport 服务是向外部网络公开服务端口的服务。

kubectl -n $nameSpace expose pod $sqlmiName-0 --port=1533  --name=ha-$sqlmiName-0 --type=LoadBalancer
kubectl -n $nameSpace expose pod $sqlmiName-1 --port=1533  --name=ha-$sqlmiName-1 --type=LoadBalancer
kubectl -n $nameSpace expose pod $sqlmiName-2 --port=1533  --name=ha-$sqlmiName-2 --type=LoadBalancer

结果

应能够连接到公开的外部端口(已在步骤 3 内部确认)。 如果无法连接到外部端口,请参阅 Kubernetes 文档 - 创建外部负载均衡器并获取有关问题的服务提供商帮助。

可以使用任何客户端(如 SqlCmd、SQL Server Management Studio (SSMS) Azure Data Studio (ADS))测试此问题。

故障转移组之间的连接丢失

如果主和异地辅助 Arc SQL 托管实例之间的故障转移组配置为处于 sync 模式,并且由于任何原因导致连接在很长一段时间内丢失,则在将事务发送到异地辅助数据库之前,无法截断主 Arc SQL 托管实例上的日志。 这可能会导致日志填满并可能耗尽主站点上的空间。 若要打破这种情况,请删除故障转移组,并在重新建立站点之间的连接时重新配置。

可以在主站点和辅助站点上删除故障转移组,如下所示:

如果数据控制器是在 indirect 模式下部署的:kubectl delete fog <failovergroup name>

如果数据控制器是在 direct 模式下部署的,请提供 sharedname 并在两个站点上删除故障转移组:az sql instance-failover-group-arc delete --name fogcr --mi <arcsqlmi> --resource-group <resource group>

删除主站点上的故障转移组后,可以截断日志以释放空间。

收集日志

如果前面的步骤全部成功且没有任何问题,但你仍无法登录,请收集日志并联系支持人员

收集控制器日志

MyController=$(kubectl -n $nameSpace get pods --selector=app=controller -o jsonpath='{.items[*].metadata.name}')
kubectl -n $nameSpace cp  $MyController:/var/log/controller $localFolder/controller -c controller

获取每个副本的 SQL Server 和监督器日志

为每个副本运行以下命令以获取 SQL Server 和监督器日志

kubectl -n $nameSpace cp $sqlmiName-0:/var/opt/mssql/log $localFolder/$sqlmiName-0/log -c  arc-sqlmi
kubectl -n $nameSpace cp $sqlmiName-0:/var/log/arc-ha-supervisor $localFolder/$sqlmiName-0/arc-ha-supervisor -c arc-ha-supervisor

获取业务流程协调程序日志

kubectl -n $nameSpace  cp $sqlmiName-ha-0:/var/log $localFolder/$sqlmiName-ha-0/log -c arc-ha-orchestrator

获取日志以便对已启用 Azure Arc 的数据服务进行故障排除