本文档介绍如何将 Amazon Elastic Compute Cloud (Amazon EC2) 上安装的 Microsoft SQL Server 实例迁移到 Google Cloud 中 Compute Engine 上的 Microsoft SQL Server 实例。此迁移仅基于 Microsoft SQL Server 提供的内置数据库技术。此方法实际上是使用 Always On 可用性组的零停机时间方法。Always On 可用性组通过 VPN 与 AWS 和 Google Cloud 连接,并且允许复制 Microsoft SQL Server 数据库。本文假定您熟悉网络设置、Google Cloud、Compute Engine、AWS 和 Microsoft SQL Server。
如果您只想执行复制,可以按照本教程中的步骤执行操作,但要在添加测试数据并省略切换步骤后停止。
目标
- 部署一个多云端 Microsoft SQL Server Always On 可用性组,它涵盖 Amazon EC2 中的 Microsoft SQL Server 和 Compute Engine 上的 Google Cloud 中 Microsoft SQL Server。
- 在 Amazon EC2 中设置主 Microsoft SQL 实例。
- 在 Google Cloud 中将 Microsoft SQL Server 实例设置为 AWS 中主要 Microsoft SQL Server 的次要数据库(数据复制目标)。
- 通过在 Google Cloud 中将次要 Microsoft SQL Server 设置为 Google Cloud 中的主 Microsoft SQL Server,完成数据迁移。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
- Compute Engine
- SQL Server 虚拟机
您可使用价格计算器根据您的预计使用情况来估算费用。
本教程还要求 AWS 中的资源可能会产生费用。
准备工作
-
在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目。
-
在 Google Cloud 控制台中,激活 Cloud Shell。
了解数据库迁移
数据库迁移将数据从源数据库转移到目标数据库。通常,您可以迁移部分数据,也可以在源数据库和目标数据库中使用不同的架构。但是,本教程解决了需要迁移完整数据库而不需要更改的数据库迁移—目标数据库是源数据库的副本。
零停机时间数据库迁移
零停机时间指在迁移期间,访问源数据库的客户端将继续保持运行状态,不会中断。只有在迁移完成后客户端必须重新连接到目标数据库,才会发生停机。虽然这种方法不会造成零停机时间,但该术语指最小停机时间。
有关数据库迁移的一般讨论,请参阅数据库迁移 - 概念和原则(第 1 部分)和数据库迁移 - 概念和原则(第 2 部分)。这些文章概述了数据库在不同场景中的复杂性。
使用 Microsoft SQL Server 技术迁移数据库
某些数据库迁移技术提供独立的组件和服务。当数据库迁移需要源数据库的副本时,您可以使用内置的 Microsoft SQL Server 技术。
本教程使用 Microsoft SQL Server Always On 可用性组技术将源数据库(主数据库)连接到目标数据库(次要)。这项技术提供从主数据库到次要数据库的异步复制。由于主数据库位于 Amazon EC2 中,而次要数据库位于 Compute Engine 上的 Google Cloud 中,因此复制会涉及数据库迁移。通过异步复制迁移所有数据后,次要服务器会提升到主实例,以便客户端重新连接到新的主实例以继续处理。
此方法支持通过对测试目标数据库进行测试复制来明确测试:您可以启动复制,让测试运行一段时间,然后停止复制。测试目标数据库处于一致的状态,您可以使用它测试应用。测试完成后,您可以删除测试目标数据库,然后启动对活跃数据库的复制。
多云端数据库迁移架构
下图显示了多云端数据库迁移的整体部署架构:
上图显示了 AWS 中的源(主)SQL Server 数据库作为 Amazon EC2 实例。该图还显示了 Google Cloud 中的目标数据库(辅助)。数据库通过 Always On 可用性组连接。AWS 和 Google Cloud 之间的网络连接假定为安全的 HA VPN 连接。
设置多云端 Microsoft SQL Server 可用性组
在以下部分中,您设置了两个节点 Always On 可用性组,其中主节点位于 AWS 中,辅助节点位于 Google Cloud 中。本文档前面的多云端数据库迁移架构中介绍了此配置。
下表汇总了您在本教程中设置的节点和 IP 地址。对于每个数据库虚拟机,除了主要 IP 地址之外,您还需要分配两个 IP 地址:一个用于 Windows Server 故障切换集群 (WSFC) 的 IP 地址,可用性组监听器分配一个 IP 地址。
提供方 | 实例 | 主要 IP | WSFC 和可用性组监听器 IP | WSFC | 可用性组 |
---|---|---|---|---|---|
AWS | cluster-sql1 |
192.168.1.4 |
192.168.1.5
|
Name: cluster-dbclus
|
Name: cluster-ag
|
Google Cloud | cluster-sql2 |
10.1.1.4 |
10.1.1.5
|
提供方 | 实例 | 主要 IP | — |
---|---|---|---|
AWS |
dc-windows |
192.168.1.100 |
Domain controller |
说明使用这些名称和 IP 地址作为示例。如果您要使用自己的名称和 IP 地址,请替换说明中的示例值。
AWS 的前提条件
在 AWS 上,您应该有两个虚拟机:一个运行网域控制器,另一个运行 SQL Server。本教程中用作示例的网域控制器具有以下配置:
Domain : dbeng.com
Domain controller : Name: dc-windows
Private IP: 192.168.1.100
VPC Subnet : 192.168.1.0/24
SQL Server service account: dbeng\sql_service
本教程中使用的 SQL Server 虚拟机是 Amazon EC2 中 Windows Active Directory 网域的一部分。服务器有两个可供 WSFC 和可用性组监听器使用的次要 IP 地址。SQL Server 虚拟机具有以下配置:
VM Instance : Name: cluster-sql1
Private IP: 192.168.1.4
Secondary Private IPs: 192.168.1.5, 192.168.1.6
VPC Subnet : 192.168.1.0/24
您可以使用服务账号 NT SERVICE\MSSQLSERVER
作为 SQL Server 服务账号。在 Always On 可用性组设置过程中,您可以向机器账号(dbeng\cluster-sql1$
、dbeng\cluster-sql2$
)而不是网域账号授予访问权限。以下部分提供了配置可用性组的命令。
AWS 和 Google Cloud 之间连接的前提条件
如需将您的 AWS 项目与 Google Cloud 项目关联,请设置以下网络连接:
- 在相应的项目中设置 Google 虚拟私有云和 AWS VPC,并在 VPC 之间配置 VPN。如需了解如何在 Google Cloud 和 AWS 之间设置 VPN,请参阅多云端 VPN 和多地区子网 - 多云端数据库部署的网络设置。
在 Cloud Shell 中,在要在其中创建 SQL Server 实例的 Google Cloud 项目中创建子网。如果您已拥有子网,则可以使用该子网,但务必在下一步中设置防火墙规则。
gcloud compute networks create demo-vpc --subnet-mode custom gcloud compute networks subnets create demo-subnet1 \ --network demo-vpc --region us-east4 --range 10.1.1.0/24
本教程使用以下值:
- VPC:
demo-vpc
- 子网:
demo-subnet1; 10.1.1.0/24
该子网显示在 Google Cloud 控制台的 VPC 网络页面上。
- VPC:
在 Google Cloud 项目中,创建防火墙规则,打开 Google Cloud 子网和 AWS 子网之间的所有流量:
gcloud compute firewall-rules create allow-vpn-ports \ --network demo-vpc --allow tcp:1-65535,udp:1-65535,icmp \ --source-ranges 10.1.1.0/24,192.168.1.0/24
防火墙规则显示在 Google Cloud 控制台的防火墙政策页面上。
在 AWS 项目中,在安全组中创建一个防火墙规则,用于打开 Google Cloud 子网和 AWS 子网之间的所有流量,如以下屏幕截图所示:
在生产环境中,您可以考虑仅打开所需的 TCP/UDP 端口。仅打开必要的端口会限制潜在的有害流量并遵循最低必要的原则。
在 Google Cloud 中为 Always On 可用性组创建实例
本教程支持以下 Microsoft SQL Server 版本和功能:
- 版本:
- Microsoft SQL Server 2016 Enterprise Edition 或
- Microsoft SQL Server 2017 Enterprise Edition 或
- Microsoft SQL Server 2019 Enterprise Edition 或
- Microsoft SQL Server 2022 Enterprise Edition 或
- Microsoft SQL Server 2016 Standard Edition
- Microsoft SQL Server 2017 Standard Edition
- Microsoft SQL Server 2019 Standard Edition 或
- Microsoft SQL Server 2022 Standard Edition
- 功能:Always On 可用性组
以下说明使用 Microsoft SQL Server 2019 Enterprise 版本的映像:sql-ent-2019-win-2019
。如果要安装 Microsoft SQL Server 2017、2016 或 2022 Enterprise 版本,请分别改用 sql-ent-2017-win-2019
、sql-ent-2016-win-2019
、sql-ent-2022-win-2019
。如需查看所有映像的列表,请参阅 Compute Engine 操作系统详细信息页面。
在以下步骤中,您将在 Google Cloud 中为可用性组创建 SQL Server 实例。该实例使用以下 IP 地址配置和别名 IP 地址:
VM Instance: Name: cluster-sql2
Private IP: 10.1.1.4
Secondary Private IPs: 10.1.1.5, 10.1.1.6
您可以通过公共 SQL Server 映像创建一个名为 cluster-sql2
的实例,该实例启动磁盘大小达到 200 GB,机器类型为 n1-highmem-4。与网域控制器实例相比,SQL Server 实例通常需要更多的计算资源。如果您日后需要额外的计算资源,可以更改这些实例的机器类型。如果您需要额外的存储空间,请添加一个磁盘或调整永久性启动磁盘的大小。在较大的可用性组中,您可以创建多个实例。
以下步骤还包括在实例创建期间运行 Microsoft PowerShell 命令的 --metadata sysprep-specialize-script-ps1
标志,以安装故障切换集群功能。
在 Cloud Shell 中,在 Google Cloud 中创建使用与 AWS 相同操作系统版本的 SQL Server 实例:
gcloud compute instances create cluster-sql2 --machine-type n1-highmem-4 \ --boot-disk-type pd-ssd --boot-disk-size 200GB \ --image-project windows-sql-cloud --image-family sql-ent-2019-win-2019 \ --zone us-east4-a \ --network-interface "subnet=demo-subnet1,private-network-ip=10.1.1.4,aliases=10.1.1.5;10.1.1.6" \ --can-ip-forward \ --metadata sysprep-specialize-script-ps1="Install-WindowsFeature Failover-Clustering -IncludeManagementTools;"
在连接到实例之前,设置 Windows 用户名和密码。
使用笔记本电脑的远程桌面协议 (RDP) 时,请创建允许访问实例的防火墙规则。
使用 RDP 连接到 Google Cloud 实例,并打开提升权限的 PowerShell(以管理员身份运行)。
在本教程中,您将本地 DNS 配置为使用 AWS (
192.168.1.100
) 中的网域控制器,以避免在 Google Cloud 中创建另一个虚拟机。对于生产工作负载,我们建议您使用 Google Cloud 中的网域控制器(主要或次要)来避免通过 VPN 隧道进行身份验证。在提升权限的 PowerShell 中,您应能对网域控制器
192.168.1.100
执行 ping 操作:ping 192.168.1.100
如果 ping 失败,请确保如本文前面的连接先决条件中所述,正确配置 AWS 与 Google Cloud 之间的防火墙和 VPN 隧道。
由于服务器最初使用 DHCP 进行设置,请将实例更改为使用静态 IP 地址:
netsh interface ip set address name=Ethernet static 10.1.1.4 255.255.255.0 10.1.1.1 1
运行上述命令后,您的连接会断开。在 RDP 中重新连接。
将本地 DNS 配置为使用 AWS 中的网域控制器,并为 SQL Server 打开本地防火墙端口。打开防火墙端口,让 SQL Server 连接到远程 SQL Server。
netsh interface ip set dns Ethernet static 192.168.1.100 netsh advfirewall firewall add rule name="Open Port 5022 for Availability Groups" dir=in action=allow protocol=TCP localport=5022 netsh advfirewall firewall add rule name="Open Port 1433 for SQL Server" dir=in action=allow protocol=TCP localport=1433
将实例添加到 Windows 网域:
Add-Computer -DomainName "dbeng.com" -Credential "dbeng.com\Administrator" -Restart -Force
该命令会提示您输入网域管理员凭据。当命令运行完毕后,实例会重启。
如果该命令未运行,请确保以管理员身份运行。
使用
dbeng\Administrator
账号通过 RDP 重新连接您的实例。设置 SQL Server 服务账号:
- 打开 SQL Server 2019 配置管理器。
- 在 SQL Server Services 标签页中,右键点击 SQL Server (MSSQLSERVER),然后点击属性。
- 为
dbeng\sql_service
设置账号和密码。 - 重新启动 SQL Server。
重命名 SQL Server 实例以匹配计算机名称并重启 SQL Server:
Invoke-Sqlcmd -Query "EXEC sp_dropserver @@SERVERNAME, @droplogins='droplogins'" Invoke-Sqlcmd -Query "EXEC sp_addserver '$env:COMPUTERNAME', local" Stop-Service -Name "MSSQLServer" -Force Start-Service -Name "MSSQLServer"
接下来,您将在 AWS 中配置该实例。
在 AWS 中配置实例
本教程假定您已在 AWS 中配置以下内容:
- SQL Server 实例是 Active Directory 网域的一部分。
- 本地 DNS 正常运行,Google Cloud 中远程服务器的名称(
cluster-sql2.dbeng.com)
可以转换为 IP 地址)。 - 防火墙规则在 AWS 和 Google Cloud 上的子网之间打开。
如需在 AWS 中配置 cluster-sql1
,请执行以下操作:
- 使用 RDP(
cluster-sql1
)连接到 AWS。 - 打开提升权限的 PowerShell(以管理员身份运行)。
若其尚未安装,则安装 Windows 故障切换集群。
Install-WindowsFeature Failover-Clustering -IncludeManagementTools
如果没有安装此功能,则需要重新启动此命令。重启后,请继续执行下一步操作。
在 AWS 中打开 SQL Server 实例的本地防火墙端口:
netsh advfirewall firewall add rule name="Open Port 5022 for Availability Groups" dir=in action=allow protocol=TCP localport=5022 netsh advfirewall firewall add rule name="Open Port 1433 for SQL Server" dir=in action=allow protocol=TCP localport=1433 netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol="icmpv4:8,any" dir=in action=allow
重命名 SQL Server 实例以匹配计算机名称并重启 SQL Server:
Invoke-Sqlcmd -Query "EXEC sp_dropserver @@SERVERNAME, @droplogins='droplogins'" Invoke-Sqlcmd -Query "EXEC sp_addserver '$env:COMPUTERNAME', local" Stop-Service -Name "MSSQLServer" -Force Start-Service -Name "MSSQLServer"
验证 AWS 中使用远程实例名称时可连接至 Google Cloud 中实例的实例。如需测试连接,请从已授予 SQL Server 连接访问权限的网域账号运行以下命令。
测试网络连接:
ping -4 cluster-sql2.dbeng.com
输出如下所示:
RESULTS: Pinging cluster-sql2.dbeng.com [10.1.1.4] with 32 bytes of data: Reply from 10.1.1.4: bytes=32 time=3ms TTL=127 Reply from 10.1.1.4: bytes=32 time=2ms TTL=127 Reply from 10.1.1.4: bytes=32 time=2ms TTL=127 Reply from 10.1.1.4: bytes=32 time=2ms TTL=127
测试远程服务器的 Windows 身份验证:
sqlcmd -E -S cluster-sql2.dbeng.com -Q "SELECT 'CONNECTED'"
输出如下所示:
RESULTS: -------------------------------------------------------------------------- CONNECTED (1 rows affected)
如果您无法连接,请确保 DNS 正常运行,并且 AWS 和 Google Cloud 子网之间打开了防火墙规则。
验证 Google Cloud 实例已准备好加入可用性组
- 使用
dbeng\Administrator
账号通过 RDP (cluster-sql2
) 连接到 Google Cloud 实例。 - 打开提升权限的 PowerShell(以管理员身份运行)。
验证 Google Cloud 中的实例在使用实例名称时可连接到 AWS 中的实例。如需测试连接,请从已授予 SQL Server 连接访问权限的网域账号运行以下命令。
测试网络连接:
ping -4 cluster-sql1.dbeng.com
输出如下所示:
RESULTS: Pinging CLUSTER-SQL1.dbeng.com [192.168.1.4] with 32 bytes of data: Reply from 192.168.1.4: bytes=32 time=3ms TTL=127 Reply from 192.168.1.4: bytes=32 time=2ms TTL=127 Reply from 192.168.1.4: bytes=32 time=3ms TTL=127 Reply from 192.168.1.4: bytes=32 time=2ms TTL=127
测试远程服务器的 Windows 身份验证:
sqlcmd -E -S cluster-sql1 -Q "SELECT 'CONNECTED'"
输出如下所示:
RESULTS: ------------------------------------------------------------ CONNECTED (1 rows affected)
如果您无法连接,请确保 DNS 正常运行,并且 AWS 和 Google Cloud 子网之间打开了防火墙规则。
在
C:\SQLData
和C:\SQLLog
中创建文件夹。数据库数据和日志文件使用这些文件夹。New-Item "C:\SQLData" –type directory New-Item "C:\SQLLog" –type directory
在
C:\SQLBackup
处创建一个文件夹,并在\\cluster-sql2\SQLBackup
中创建一个 Windows 共享,以便从 AWS 实例传输备份。您可以使用适用于这两个服务器的任何其他网络共享。New-Item "C:\SQLBackup" –type directory New-SmbShare -Name "SQLBackup" -Path "C:\SQLBackup" -FullAccess "dbeng.com\cluster-sql1$","dbeng.com\cluster-sql2$","NT SERVICE\MSSQLSERVER","authenticated users","dbeng.com\sql_service"
现已为可用性组创建了实例。由于您只有两个实例,在下一部分中,您将配置文件共享见证,提供尝试投票和仲裁。
创建文件共享见证
为了在故障切换情景中提供决定性投票权,实现仲裁,您需要创建一个充当见证者的文件共享。在本教程中,您将在网域控制器虚拟机上创建文件共享见证。在生产环境中,您可以在 Active Directory 网域内的任何服务器上创建文件共享见证。
- 使用 RDP 通过
dbeng\Administrator
连接到网域控制器虚拟机dc-windows
。 - 打开提升权限的 PowerShell(以管理员身份运行)。
创建见证文件夹:
New-Item "C:\QWitness" –type directory
共享该文件夹:
New-SmbShare -Name "QWitness" -Path "C:\QWitness" -Description "SQL File Share Witness" -FullAccess "dbeng.com\Administrator", "dbeng.com\cluster-sql1$", "dbeng.com\cluster-sql2$"
使用
dbeng.com\Administrator
通过 RDP 连接到cluster-sql1
和cluster-sql2
。确认您可以通过这两个服务器访问共享目录:
dir \\dc-windows\QWitness
如果您无法访问共享目录,请尝试更改节点上的网络连接,以将 WINS 服务器设置为与网域服务器匹配。更改网络连接可能需要几秒钟的时间。以下屏幕截图显示了更新后的 WINS 设置:
现在,可用性组已准备就绪。接下来,您需要配置故障切换集群。
配置故障切换集群
在本部分中,您将为两个实例配置 WSFC 并启用 Always On 高可用性。在 AWS 中,从该实例运行以下所有配置命令。
- 使用 RDP 连接到 AWS 实例(
cluster-sql1
)。 - 打开提升权限的 PowerShell(以管理员身份运行)。
设置反映您集群环境的变量。对于此示例,请设置以下变量:
$node1 = "cluster-sql1.dbeng.com" $node2 = "cluster-sql2.dbeng.com" $nameWSFC = "cluster-dbclus" #Name of cluster $ipWSFC1 = "192.168.1.5" #IP address of cluster in subnet 1 (AWS) $ipWSFC2 = "10.1.1.5" #IP address of cluster in subnet 2 (Google Cloud)
创建故障切换集群(运行此命令可能需要一些时间):
New-Cluster -Name $nameWSFC -Node $node1, $node2 -NoStorage -StaticAddress $ipWSFC1, $ipWSFC2 Set-ClusterQuorum -FileShareWitness \\dc-windows\QWitness
在节点 1 上启用 Always On 高可用性。如果您之前未启用 Always On,则这些命令会强制 SQL Server 重启。
Enable-SqlAlwaysOn -ServerInstance $node1 -Force
在节点 2 上启用 Always On 高可用性。在启用 SQL Always On 之前,这些命令会停止 SQL Server 服务,因此,您可以忽略错误:
Enable-SqlAlwaysOn : StopService failed for Service 'MSSQLSERVER'
。Get-Service -ComputerName $node2 -Name "MSSQLServer" | Stop-Service -Force Enable-SqlAlwaysOn -ServerInstance $node2 -Force Get-Service -ComputerName $node2 -Name "MSSQLServer" | Start-Service
在
C:\SQLData
和C:\SQLLog
中创建文件夹。将 TestDB 文件夹用于数据库数据和日志文件。如果您的服务器已有具有此文件夹结构的数据库,则可以跳过此步骤。如果不确定,请运行命令并忽略有关现有文件夹的所有错误消息。New-Item "C:\SQLData" –type directory New-Item "C:\SQLLog" –type directory
故障切换集群管理器已配置完毕。接下来,创建可用性组。
创建可用性组
在本部分中,您将在 AWS (cluster-sql1
) 中创建测试数据库,并将其配置为使用新的可用性组。或者,您也可以为可用性组指定现有数据库。
- 使用 RDP 连接到 AWS 实例(
cluster-sql1
)。 - 打开提升权限的 PowerShell(以管理员身份运行)。
在
C:\SQLBackup
中创建一个文件夹来存储数据库的备份。在新数据库上设置可用性组之前,需要备份。New-Item "C:\SQLBackup" –type directory
如果您尚未配置数据库,请运行 SQL Server Management Studio 并在 AWS 实例 (
cluster-sql1
) 中创建测试数据库:CREATE DATABASE TestDB ON PRIMARY (NAME = 'TestDB_Data', FILENAME='C:\SQLData\TestDB_Data.mdf', SIZE = 256MB, MAXSIZE = UNLIMITED, FILEGROWTH = 256MB ) LOG ON (NAME = 'TestDB_Log', FILENAME='C:\SQLLog\TestDB_Log.ldf', SIZE = 256MB, MAXSIZE = UNLIMITED, FILEGROWTH = 256MB ) GO USE [TestDB] Exec dbo.sp_changedbowner @loginame = 'sa', @map = false; ALTER DATABASE [TestDB] SET RECOVERY FULL; GO BACKUP DATABASE TestDB to disk = 'C:\SQLBackup\TestDB-backup.bak' WITH INIT GO
在 Microsoft SQL Server Management Studio 中,选择查询 > SQLCMD Mode。
SQL Server Management Studio 提供用于创建可用性组的向导。在本教程中,您将使用 SQL 命令,从而更轻松地调试在不同云提供商连接时可能遇到的问题。如果您愿意,可以运行可用性组向导并跳到后续步骤验证可用性组是否正在同步。
在 SQLCMD 模式下运行以下查询。如果您使用的是现有数据库,请将
TestDB
替换为您的数据库名称。在第一个节点中创建端点,并向端点授予权限:
:Connect CLUSTER-SQL1 IF NOT EXISTS (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint') BEGIN CREATE ENDPOINT [Hadr_endpoint] AS TCP (LISTENER_PORT = 5022) FOR DATA_MIRRORING (ROLE = WITNESS, ENCRYPTION = REQUIRED ALGORITHM AES) END GO IF (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint') <> 0 BEGIN ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED END GO use [master] GO IF SUSER_ID('DBENG\sql_service') IS NULL CREATE LOGIN [DBENG\sql_service] FROM WINDOWS GO GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [DBENG\sql_service] GO
在第一个节点中启用
AlwaysOn_health
扩展事件会话。可用性组需要扩展事件会话。:Connect CLUSTER-SQL1 IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health') BEGIN ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON); END IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health') BEGIN ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START; END GO
在第二个节点中创建端点,并向端点授予权限:
:Connect CLUSTER-SQL2 IF NOT EXISTS (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint') BEGIN CREATE ENDPOINT [Hadr_endpoint] AS TCP (LISTENER_PORT = 5022) FOR DATA_MIRRORING (ROLE = WITNESS, ENCRYPTION = REQUIRED ALGORITHM AES) END GO IF (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint') <> 0 BEGIN ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED END GO use [master] GO IF SUSER_ID('DBENG\sql_service') IS NULL CREATE LOGIN [DBENG\sql_service] FROM WINDOWS GO GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [DBENG\sql_service] GO
在第二个节点中启用
AlwaysOn_health
扩展事件会话。可用性组需要扩展事件会话。:Connect CLUSTER-SQL2 IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health') BEGIN ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON); END IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health') BEGIN ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START; END GO
在第一个节点中创建可用性组:
:Connect CLUSTER-SQL1 USE [master] GO --DROP AVAILABILITY GROUP [cluster-ag]; GO CREATE AVAILABILITY GROUP [cluster-ag] WITH (AUTOMATED_BACKUP_PREFERENCE = SECONDARY, DB_FAILOVER = OFF, DTC_SUPPORT = NONE) FOR DATABASE [TestDB] REPLICA ON N'CLUSTER-SQL1' WITH (ENDPOINT_URL = N'TCP://CLUSTER-SQL1.dbeng.com:5022', FAILOVER_MODE = MANUAL, AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = MANUAL), N'CLUSTER-SQL2' WITH (ENDPOINT_URL = N'TCP://cluster-sql2.dbeng.com:5022', FAILOVER_MODE = MANUAL, AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = MANUAL); GO
将第二个节点加入新创建的可用性组:
:Connect CLUSTER-SQL2 ALTER AVAILABILITY GROUP [cluster-ag] JOIN; GO
在第一个节点中创建数据库备份:
:Connect CLUSTER-SQL1 BACKUP DATABASE [TestDB] TO DISK = N'\\CLUSTER-SQL2\SQLBackup\TestDB.bak' WITH COPY_ONLY, FORMAT, INIT, SKIP, REWIND, NOUNLOAD, COMPRESSION, STATS = 5 GO
在第二个节点上恢复数据库备份:
:Connect CLUSTER-SQL2 RESTORE DATABASE [TestDB] FROM DISK = N'\\CLUSTER-SQL2\SQLBackup\TestDB.bak' WITH NORECOVERY, NOUNLOAD, STATS = 5 GO
在第一个节点中创建事务日志备份:
:Connect CLUSTER-SQL1 BACKUP LOG [TestDB] TO DISK = N'\\CLUSTER-SQL2\SQLBackup\TestDB.trn' WITH NOFORMAT, INIT, NOSKIP, REWIND, NOUNLOAD, COMPRESSION, STATS = 5 GO
在第二个节点中恢复事务日志备份:
:Connect CLUSTER-SQL2 RESTORE LOG [TestDB] FROM DISK = N'\\CLUSTER-SQL2\SQLBackup\TestDB.trn' WITH NORECOVERY, NOUNLOAD, STATS = 5 GO
为了确保同步中没有错误,请运行以下查询并确保列
connected_state_desc
的值为CONNECTED
::Connect CLUSTER-SQL2 select r.replica_server_name, r.endpoint_url, rs.connected_state_desc, rs.last_connect_error_description, rs.last_connect_error_number, rs.last_connect_error_timestamp from sys.dm_hadr_availability_replica_states rs join sys.availability_replicas r on rs.replica_id=r.replica_id where rs.is_local=1
如果
connected_state_desc
列包含错误消息An error occurred while receiving data: '24(The program issued a command but the command length is incorrect)'
,请运行以下命令以尝试清除错误::Connect CLUSTER-SQL1 IF SUSER_ID('DBENG\CLUSTER-SQL2$') IS NULL CREATE LOGIN [DBENG\CLUSTER-SQL2$] FROM WINDOWS GO GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [DBENG\CLUSTER-SQL2$] GO :Connect CLUSTER-SQL2 IF SUSER_ID('DBENG\CLUSTER-SQL1$') IS NULL CREATE LOGIN [DBENG\CLUSTER-SQL1$] FROM WINDOWS GO GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [DBENG\CLUSTER-SQL1$] GO
重新运行上一个查询以确保不再发生同步错误。您可能需要等待几分钟,以便清除错误。如果错误仍然存在,请参阅对 Always On 可用性组配置 (SQL Server) 进行问题排查。
完成可用性组设置:
:Connect CLUSTER-SQL2 ALTER DATABASE [TestDB] SET HADR AVAILABILITY GROUP = [cluster-ag] GO ALTER DATABASE [TestDB] SET HADR RESUME; GO
验证可用性组是否正在同步:
在 SQL Server Management Studio 的 Always On 高可用性 > 可用性组下,右键点击可用性组,然后选择显示信息中心。
验证主同步状态是否为已同步,辅助同步状态为同步,如以下屏幕截图所示:
要添加监听器,请在 Always On 高可用性 > 可用性组 >
cluster-ag (Primary)
> 可用性组监听器下,右键点击可用性组名称,然后选择添加监听器。在新建可用性组监听器对话框中,指定监听器的以下参数:
- 监听器 DNS 名称:
ag-listener
。 - 端口:
1433
- 网络模式:
Static IP
- 监听器 DNS 名称:
添加两个子网和 IP 地址字段。对于此示例,使用以下子网和 IP 地址对。这些对是除了您在 SQL 服务实例虚拟机上的主要 IP 地址以外创建的 IP 地址:
- 对于第一个键值对,请输入以下值:
- 子网:
192.168.1.0/24
- IPv4 地址:
192.168.1.6
- 子网:
- 对于第二对,请输入以下值:
- 子网:
10.1.1.0/24
- IPv4 地址:
10.1.1.6
- 子网:
- 对于第一个键值对,请输入以下值:
添加子网和 IP 地址对后,点击确定。
使用
ag-listener.dbeng.com
作为 SQL Server 数据库名称(而不是实例名称)连接到 SQL Server。此连接指向当前活跃的实例。- 在 Object Explorer 中,点击连接,然后选择数据库引擎。
- 在连接到服务器对话框的服务器名称字段中,输入监听器
ag-listener.dbeng.com
。 添加服务器名称后,点击连接。Object Explorer 会显示新的连接,如以下屏幕截图所示:
如果您使用 RDP 连接到
cluster-sql2
,则可以选择重复执行此步骤以建立连接。
添加测试数据
在本部分中,您将向 cluster-sql1
中的 TestDB 数据库添加一个测试表和一些测试数据,然后验证数据复制。
在
cluster-sql1
中创建名为Persons
的表::Connect CLUSTER-SQL1 USE TestDB; CREATE TABLE Persons ( PersonID int, LastName varchar(255), FirstName varchar(255), PRIMARY KEY (PersonID) );
插入几行:
:Connect CLUSTER-SQL1 USE TestDB; INSERT INTO Persons (PersonId, LastName, FirstName) VALUES (1, 'Velasquez', 'Ava'); INSERT INTO Persons (PersonId, LastName, FirstName) VALUES (2, 'Delaxcrux', 'Paige');
如果您使用的是企业版,请启用读取副本的读取访问权限 (
cluster-sql2
),以便验证是否进行了复制。标准版不支持对只读副本的只读权限。如果您使用的是标准版,请跳到下一部分执行切换至 Google Cloud 部分。:Connect CLUSTER-SQL1 ALTER AVAILABILITY GROUP [cluster-ag] MODIFY REPLICA ON N'CLUSTER-SQL2' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL)) GO
在企业版中,查询
cluster-sql2
中的表以验证表内容是否已复制::Connect CLUSTER-SQL2 SELECT * FROM TestDB.dbo.Persons;
现在,数据已从 cluster-sql1
复制到 cluster-sql2
,而由您执行切换。如果您只想执行复制,则可以跳过以下部分,而不执行切换或回退操作。如果您不想保留用于执行复制的资源,则可以按照本教程末尾的清理步骤来避免产生费用。
执行到 Google Cloud 的切换
为了确保数据集具有一致性,必须停止向 cluster-sql1
写入数据的客户端,以便在执行切换之前将所有数据复制到 cluster-sql2
。
为确保一致性,必须完整复制所有数据。在本部分中,您将可用性模式更改为 SYNCHRONOUS_COMMIT
以完成数据复制。此更改可确保将 cluster-sql1
的完整复制到 cluster-sql2
。
如需将两个节点的可用性模式更改为同步提交,请在
cluster-sql1
中运行以下 SQL 命令。确保两个节点均设为同步提交是确保不会丢失任何数据的唯一方法。:Connect CLUSTER-SQL1 ALTER AVAILABILITY GROUP [cluster-ag] MODIFY REPLICA ON N'CLUSTER-SQL1' WITH (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT) GO ALTER AVAILABILITY GROUP [cluster-ag] MODIFY REPLICA ON N'CLUSTER-SQL2' WITH (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT) GO
现在可以将
Cluster-sql2
设置为主节点了。连接到cluster-sql2
并将其设置为主节点::Connect CLUSTER-SQL2 ALTER AVAILABILITY GROUP [cluster-ag] FAILOVER; GO
在两个节点中将可用性模式更改为异步提交。由于
cluster-sql2
是主节点,因此请在cluster-sql2
中运行以下 SQL 命令::Connect CLUSTER-SQL2 ALTER AVAILABILITY GROUP [cluster-ag] MODIFY REPLICA ON N'CLUSTER-SQL1' WITH (AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT) GO ALTER AVAILABILITY GROUP [cluster-ag] MODIFY REPLICA ON N'CLUSTER-SQL2' WITH (AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT) GO
现在,您可以使用
cluster-sql2
作为应用的主节点了。cluster-sql1
是异步复制的辅助实例。现在,
cluster-sql2
是主节点,查询cluster-sql2
中的表以验证表内容是否已复制::Connect CLUSTER-SQL2 SELECT * FROM TestDB.dbo.Persons;
输出与您在本教程前面表中插入的测试数据相匹配。
如需执行进一步的复制验证,您可以创建一个新表并在新主实例上插入一行。当表及其行显示在二级时,您就知道复制正在进行。
后备操作
有时,您可能需要从新的主实例恢复到原始主实例。在本教程中,当您提前完成切换到 Google Cloud,您已将之前二级主实例 (cluster-sql1
) 指向新的主实例(cluster-sql2
)。
要完成回退过程,请按照执行切换到 Google Cloud 过程操作,并替换以下值:
- 将原始主实例 (
cluster-sql1
) 替换为新的主实例 (cluster-sql2
)。 - 将原始次要地址 (
cluster-sql2
) 替换为新的次要地址 (cluster-sql1
)。
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请执行以下操作:
删除 Google Cloud 中的项目
- 在 Google Cloud 控制台中,进入管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关闭以删除项目。
删除 AWS 中的项目
由于您在 AWS 中创建和使用资源,因此这些资源将继续产生费用。为避免进一步增加费用,请在 AWS 上删除这些资源。
后续步骤
- 浏览更多 SQL Server 文档和解决方案。
- 探索有关 Google Cloud 的参考架构、图表和最佳实践。查看我们的 Cloud Architecture Center。