若要故障转移,首先必须使用 Transact-SQL (T-SQL) 切换 SQL Server 实例的复制模式。
然后,可以使用 PowerShell 对角色进行故障转移和切换。
切换复制模式(故障转移到 SQL MI)
默认情况下,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 和托管实例之间的故障转移向导来生成适合你的环境的脚本。 可以从主要副本或次要副本执行计划的故障转移。 若要执行强制故障转移,请连接到次要副本。
若要在故障转移或迁移数据库时断开链接并停止复制,而无论 SQL Server 版本如何,请使用 Remove-AzSqlInstanceLink PowerShell 或 az sql mi link delete Azure CLI 命令。
注意
- 在进行故障转移之前,请停止源数据库上的工作负载,使复制数据库能够完全赶上进度并完成故障转移,且不会丢失数据。 如果执行强制故障转移,或者在 LSN 匹配之前断开链接,可能会丢失数据。
- 若在 SQL Server 2019 及更早版本中故障转移数据库,会断开并删除两个副本之间的链接。 无法故障回复到初始主要副本。
- 目前可在预览版中故障转移数据库,同时保留与 SQL Server 2022 的链接。
以下示例脚本会断开链接并结束副本之间的复制,使数据库可在两个实例上执行读/写操作。 将:
<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