若要故障转移,首先必须使用 Transact-SQL (T-SQL) 切换 SQL Server 实例的复制模式。
然后,可以使用 PowerShell 进行故障转移并切换角色。
默认情况下,SQL Server 和 SQL 托管实例之间的复制是异步的。 如果要从 SQL Server 故障转移到 Azure SQL 托管实例,请在执行数据库故障转移之前,使用 Transact-SQL (T-SQL) 将 SQL Server 上的链接切换为同步模式。
注意
- 如果是从 SQL 托管实例故障转移到 SQL Server 2022,请跳过此步骤。
- 大范围网络距离的同步复制可能会减慢主要副本上的事务处理速度。
运行 SQL Server 上的以下 T-SQL 脚本,将分布式可用性组的复制模式从异步更改为同步。进行以下替换:
- 将
<DAGName>
替换为分布式可用性组的名称(用于创建链接)。
- 将
<AGName>
替换为在 SQL Server 上创建的可用性组的名称(用于创建链接)。
- 将
<ManagedInstanceName>
替换为托管实例的名称。
-- Run on SQL Server
-- Sets the distributed availability group to a synchronous commit.
-- ManagedInstanceName example: 'sqlmi1'
USE master
GO
ALTER AVAILABILITY GROUP [<DAGName>]
MODIFY
AVAILABILITY GROUP ON
'<AGName>' WITH
(AVAILABILITY_MODE = SYNCHRONOUS_COMMIT),
'<ManagedInstanceName>' WITH
(AVAILABILITY_MODE = SYNCHRONOUS_COMMIT);
若要确认是否已成功更改链接的复制模式,请使用以下动态管理视图。 结果指示 SYNCHRONOUS_COMMIT
状态。
-- Run on SQL Server
-- Verifies the state of the distributed availability group
SELECT
ag.name, ag.is_distributed, ar.replica_server_name,
ar.availability_mode_desc, ars.connected_state_desc, ars.role_desc,
ars.operational_state_desc, ars.synchronization_health_desc
FROM
sys.availability_groups ag
join sys.availability_replicas ar
on ag.group_id=ar.group_id
left join sys.dm_hadr_availability_replica_states ars
on ars.replica_id=ar.replica_id
WHERE
ag.is_distributed=1
现在,你已将 SQL Server 切换为同步提交模式,这两个实例之间的复制现在是同步的。 如果需要反转此状态,请执行相同的步骤并将 AVAILABILITY_MODE
设置为 ASYNCHRONOUS_COMMIT
。
检查 SQL Server 和 SQL 托管实例上的 LSN 值
若要完成故障转移或迁移,请确认复制到辅助副本的过程已完成。 为此,请确保 SQL Server 和 SQL 托管实例的日志记录中的日志序列号 (LSN) 是相同的。
最初,主副本上的 LSN 应高于辅助副本上的 LSN。 网络延迟可能会导致复制速度有所滞后于主服务器。 由于在主副本上的工作负载已停止,因此 LSN 将进行匹配并在一段时间后停止更改。
在 SQL Server 上使用以下 T-SQL 查询来读取最近记录的事务日志的 LSN。 进行以下替换:
- 将
<DatabaseName>
替换为你的数据库名称,并查找最后一个强化的 LSN 编号。
-- Run on SQL Server
-- Obtain the last hardened LSN for the database on SQL Server.
SELECT
ag.name AS [Replication group],
db.name AS [Database name],
drs.database_id AS [Database ID],
drs.group_id,
drs.replica_id,
drs.synchronization_state_desc AS [Sync state],
drs.end_of_log_lsn AS [End of log LSN],
drs.last_hardened_lsn AS [Last hardened LSN]
FROM
sys.dm_hadr_database_replica_states drs
inner join sys.databases db on db.database_id = drs.database_id
inner join sys.availability_groups ag on drs.group_id = ag.group_id
WHERE
ag.is_distributed = 1 and db.name = '<DatabaseName>'
在 SQL 托管实例上使用以下 T-SQL 查询来读取数据库的最后一个强化的 LSN。 将 <DatabaseName>
替换为你的数据库名称。
此查询将适用于常规用途 SQL 托管实例。 对于关键业务 SQL 托管实例,请取消脚本末尾的 and drs.is_primary_replica = 1
注释。 在业务关键服务层级,此筛选器可确保仅读取主要副本的详细信息。
-- Run on SQL managed instance
-- Obtain the LSN for the database on SQL Managed Instance.
SELECT
db.name AS [Database name],
drs.database_id AS [Database ID],
drs.group_id,
drs.replica_id,
drs.synchronization_state_desc AS [Sync state],
drs.end_of_log_lsn AS [End of log LSN],
drs.last_hardened_lsn AS [Last hardened LSN]
FROM
sys.dm_hadr_database_replica_states drs
inner join sys.databases db on db.database_id = drs.database_id
WHERE
db.name = '<DatabaseName>'
-- for Business Critical, add the following as well
-- AND drs.is_primary_replica = 1
或者,还可以使用 Get-AzSqlInstanceLink PowerShell 或 az sql mi link show Azure CLI 命令获取 SQL 托管实例上链接的 LastHardenedLsn
属性,该属性将提供与之前的 T-SQL 查询相同的信息。
重要
再次验证你的工作负载是否已在主副本上停止。 检查 SQL Server 和 SQL 托管实例上的 LSN 是否匹配,并且在一段时间内保持匹配和不变。 如果两种实例上的 LSN 稳定,则表示已将尾部日志复制到次要副本,并且工作负载已实际停止。
如果想要使用 PowerShell 在 SQL Server 2022 和 SQL 托管实例之间故障转移数据库,同时仍保留链接,或者要对任何版本的 SQL Server 执行故障转移(但会丢失数据),请在 SSMS 中使用 SQL Server 和托管实例之间的故障转移向导来生成适合你的环境的脚本。 可以从主副本或辅助副本执行计划的故障转移。 若要执行强制故障转移,请连接到辅助副本。
要在故障转移或迁移数据库时断开链接并停止复制,可以使用 Remove-AzSqlInstanceLink PowerShell 或 az sql mi link delete Azure CLI 命令,而无需考虑 SQL Server 版本。
警告
- 在故障转移之前,请先停止源数据库上的工作负载,使复制的数据库能够完全跟上,这样故障转移时才不会丢失数据。 如果执行强制故障转移,或者在 LSN 匹配之前断开链接,可能会丢失数据。
- 若在 SQL Server 2019 及更早版本中对数据库进行故障转移,会断开并删除两个副本之间的链接。 无法故障回复到初始主副本。
以下示例脚本会断开链接并结束副本之间的复制,使数据库可在两个实例上执行读/写操作。 进行以下替换:
<ManagedInstanceName>
表示托管实例的名称。
- 将
<DAGName>
替换为要故障转移的链接的名称(上面执行的 Get-AzSqlInstanceLink
命令中,属性 Name
的输出)。
# POWERSHELL SCRIPT TO FAIL OVER OR MIGRATE DATABASE TO AZURE
# ===== Enter user variables here ====
# Enter your managed instance name – for example, "sqlmi1"
$ManagedInstanceName = "<ManagedInstanceName>"
$LinkName = "<DAGName>"
# ==== Do not customize the following cmdlet ====
# Find out the resource group name
$ResourceGroup = (Get-AzSqlInstance -InstanceName $ManagedInstanceName).ResourceGroupName
# Failover the specified link
Remove-AzSqlInstanceLink -ResourceGroupName $ResourceGroup |
-InstanceName $ManagedInstanceName -Name $LinkName -Force
故障转移成功后,链接将被删除,不再存在。 SQL Server 数据库和 SQL 托管实例数据库都可以执行读/写工作负载,因为它们现在已完全独立。
重要
成功故障转移到 SQL 托管实例后,手动将应用程序连接字符串重新指向 SQL 托管实例 FQDN,以完成迁移或故障转移过程,并继续在 Azure 中运行。
删除链接后,可以在 SQL Server 上保留可用性组,但必须删除分布式可用性组才能从 SQL Server 中删除链接元数据。 只有当使用 PowerShell 进行故障转移时,才需要执行此附加步骤,因为 SSMS 会为你执行此操作。
若要删除分布式可用性组,请替换以下值,然后运行示例 T-SQL 代码:
- 将
<DAGName>
替换为 SQL Server 上分布式可用性组的名称(用于创建链接)。
-- Run on SQL Server
USE MASTER
GO
DROP AVAILABILITY GROUP <DAGName>
GO