教程:在 Azure SQL 托管实例和 SQL Server 之间配置事务复制
适用于:Azure SQL 托管实例
通过事务复制可以将数据从一个数据库复制到 SQL Server 或 Azure SQL 托管实例中托管的另一个数据库。 SQL 托管实例可以是复制拓扑中的发布服务器、分发服务器或订阅服务器。 有关可用配置,请参阅事务复制配置。
在本教程中,你将了解如何执行以下操作:
- 将托管实例配置为复制发布服务器。
- 将托管实例配置为复制分发服务器。
- 将 SQL Server 配置为订阅服务器。
本教程适用于经验丰富的受众,并假定用户熟悉如何在 Azure 中部署和连接到这两个托管实例和 SQL Server VM。
注意
本文介绍了如何在 Azure SQL 托管实例中使用事务复制。 它与故障转移组无关,这是一项 Azure SQL 托管实例功能,可用于创建单个实例的完整可读副本。 配置故障转移组的事务复制时还有其他注意事项。
先决条件
若要完成本教程,请确保具备以下先决条件:
- 一个 Azure 订阅。
- 尝试在同一虚拟网络中部署两个托管实例。
- 本地或 Azure VM 上的 SQL Server 订阅服务器。 本教程使用 Azure VM。
- SQL Server Management Studio (SSMS) 18.0 或更高版。
- 最新版本的 Azure PowerShell。
- 端口 445 和 1433 允许 Azure 防火墙和 Windows 防火墙上的 SQL 流量。
创建资源组
使用以下 PowerShell 代码片段创建新的资源组:
# set variables
$ResourceGroupName = "SQLMI-Repl"
$Location = "China East 2"
# Create a new resource group
New-AzResourceGroup -Name $ResourceGroupName -Location $Location
创建两个托管实例
使用“Azure 门户”在此新资源组中创建两个托管实例。
发布服务器托管实例的名称应为
sql-mi-publisher
(带有用于随机化的几个字符),虚拟网络的名称应该为vnet-sql-mi-publisher
。分发服务器托管实例的名称应为
sql-mi-distributor
(带有用于随机化的几个字符),并且应在发布服务器托管实例所在的虚拟网络中。
有关创建托管实例的详细信息,请参阅在门户中创建托管实例。
注意
为简单起见,因为这是最常见的配置,所以本教程建议将分发服务器托管实例放置在发布服务器所在的虚拟网络中。 但是,可以在单独的虚拟网络中创建分发服务器。 为此,需要在发布服务器和分发服务器的虚拟网络之间配置 VNet 对等互连,然后在分发服务器和订阅服务器的虚拟网络之间配置 VNet 对等互连。
创建 SQL Server VM
使用 Azure 门户创建 SQL Server 虚拟机。 SQL Server 虚拟机应具有以下特征:
- 名称:
sql-vm-sub
- 映像:SQL Server 2016 或更高版本
- 资源组:与托管实例相同
- 虚拟网络:
sql-vm-sub-vnet
有关将 SQL Server VM 部署到 Azure 的详细信息,请参阅 快速入门:创建 SQL Server VM。
配置 VNet 对等互连
配置 VNet 对等互连,以便在两个托管实例的虚拟网络和 SQL Server 的虚拟网络之间启用通信。 为此,请使用以下 PowerShell 代码片段:
# Set variables
$SubscriptionId = '<SubscriptionID>'
$resourceGroup = 'SQLMI-Repl'
$pubvNet = 'sql-mi-publisher-vnet'
$subvNet = 'sql-vm-sub-vnet'
$pubsubName = 'Pub-to-Sub-Peer'
$subpubName = 'Sub-to-Pub-Peer'
$virtualNetwork1 = Get-AzVirtualNetwork `
-ResourceGroupName $resourceGroup `
-Name $pubvNet
$virtualNetwork2 = Get-AzVirtualNetwork `
-ResourceGroupName $resourceGroup `
-Name $subvNet
# Configure VNet peering from publisher to subscriber
Add-AzVirtualNetworkPeering `
-Name $pubsubName `
-VirtualNetwork $virtualNetwork1 `
-RemoteVirtualNetworkId $virtualNetwork2.Id
# Configure VNet peering from subscriber to publisher
Add-AzVirtualNetworkPeering `
-Name $subpubName `
-VirtualNetwork $virtualNetwork2 `
-RemoteVirtualNetworkId $virtualNetwork1.Id
# Check status of peering on the publisher VNet; should say connected
Get-AzVirtualNetworkPeering `
-ResourceGroupName $resourceGroup `
-VirtualNetworkName $pubvNet `
| Select PeeringState
# Check status of peering on the subscriber VNet; should say connected
Get-AzVirtualNetworkPeering `
-ResourceGroupName $resourceGroup `
-VirtualNetworkName $subvNet `
| Select PeeringState
建立 VNet 对等互连后,请通过以下方式测试连接:在 SQL Server 上启动 SQL Server Management Studio (SSMS),并连接到这两个托管实例。 有关使用 SSMS 连接到托管实例的详细信息,请参阅使用 SSMS 连接到 SQL 托管实例。
创建专用 DNS 区域
专用 DNS 区域允许在托管实例和 SQL Server 之间进行 DNS 路由。
创建专用 DNS 区域
登录到 Azure 门户。
选择“+ 创建资源”,创建新的 Azure 资源。
在 Azure 市场中搜索
private dns zone
。选择 Microsoft 发布的“专用 DNS 区域”资源,然后选择“创建”以创建 DNS 区域。
从下拉项中选择订阅和资源组。
为 DNS 区域提供任意名称,如
repldns.com
。选择“查看 + 创建”。 查看专用 DNS 区域的参数,然后选择“创建”以创建资源。
创建 A 记录
转到新的“专用 DNS 区域”并选择“概述”。
选择“+ 记录集”以创建新的 A 记录。
提供 SQL Server VM 的名称以及专用内部 IP 地址。
选择“确定”以创建记录。
链接虚拟网络
转到“专用 DNS 区域”并选择“虚拟网络链接” 。
选择“+ 添加”。
提供链接的名称,如
Pub-link
。从下拉列表中选择订阅,然后选择发布服务器托管实例的虚拟网络。
选中“启用自动注册”旁边的框。
选择“确定”以链接虚拟网络。
重复这些步骤,为订阅服务器虚拟网络添加一个链接,并对其命名,例如
Sub-link
。
创建 Azure 存储帐户
为工作目录创建 Azure 存储帐户,并在存储帐户中创建文件共享。
复制采用 \\storage-account-name.file.core.chinacloudapi.cn\file-share-name
格式的文件共享路径
示例: \\replstorage.file.core.chinacloudapi.cn\replshare
按以下格式复制存储访问密钥连接字符串:DefaultEndpointsProtocol=https;AccountName=<Storage-Account-Name>;AccountKey=****;EndpointSuffix=core.chinacloudapi.cn
示例: DefaultEndpointsProtocol=https;AccountName=replstorage;AccountKey=dYT5hHZVu9aTgIteGfpYE64cfis0mpKTmmc8+EP53GxuRg6TCwe5eTYWrQM4AmQSG5lb3OBskhg==;EndpointSuffix=core.chinacloudapi.cn
有关详细信息,请参阅管理存储帐户访问密钥。
创建数据库
在发布服务器托管实例上创建新数据库。 为此,请执行下列步骤:
- 在 SQL Server 上启动 SQL Server Management Studio。
- 连接到
sql-mi-publisher
托管实例。 - 打开“新建查询”窗口,并执行以下 T-SQL 查询以创建数据库。
-- Create the databases
USE [master]
GO
-- Drop database if it exists
IF EXISTS (SELECT * FROM sys.sysdatabases WHERE name = 'ReplTutorial')
BEGIN
DROP DATABASE ReplTutorial
END
GO
-- Create new database
CREATE DATABASE [ReplTutorial]
GO
-- Create table
USE [ReplTutorial]
GO
CREATE TABLE ReplTest (
ID INT NOT NULL PRIMARY KEY,
c1 VARCHAR(100) NOT NULL,
dt1 DATETIME NOT NULL DEFAULT getdate()
)
GO
-- Populate table with data
USE [ReplTutorial]
GO
INSERT INTO ReplTest (ID, c1) VALUES (6, 'pub')
INSERT INTO ReplTest (ID, c1) VALUES (2, 'pub')
INSERT INTO ReplTest (ID, c1) VALUES (3, 'pub')
INSERT INTO ReplTest (ID, c1) VALUES (4, 'pub')
INSERT INTO ReplTest (ID, c1) VALUES (5, 'pub')
GO
SELECT * FROM ReplTest
GO
配置分发
建立连接并具有示例数据库后,可以在 sql-mi-distributor
托管实例上配置分发。 为此,请执行下列步骤:
在 SQL Server 上启动 SQL Server Management Studio。
连接到
sql-mi-distributor
托管实例。打开“新建查询”窗口,并运行以下 Transact-SQL 代码,在分发服务器托管实例上配置分发:
EXEC sp_adddistributor @distributor = 'sql-mi-distributor.b6bf57.database.chinacloudapi.cn', @password = '<distributor_admin_password>' EXEC sp_adddistributiondb @database = N'distribution' EXEC sp_adddistpublisher @publisher = 'sql-mi-publisher.b6bf57.database.chinacloudapi.cn', -- primary publisher @distribution_db = N'distribution', @security_mode = 0, @login = N'azureuser', @password = N'<publisher_password>', @working_directory = N'\\replstorage.file.core.chinacloudapi.cn\replshare', @storage_connection_string = N'<storage_connection_string>' -- example: @storage_connection_string = N'DefaultEndpointsProtocol=https;AccountName=replstorage;AccountKey=dYT5hHZVu9aTgIteGfpYE64cfis0mpKTmmc8+EP53GxuRg6TCwe5eTYWrQM4AmQSG5lb3OBskhg==;EndpointSuffix=core.chinacloudapi.cn'
注意
请确保对 @working_directory 参数仅使用反斜杠(
\
)。 在连接到文件共享时使用正斜杠(/
)可能会导致错误。连接到
sql-mi-publisher
托管实例。打开“新建查询”窗口,并运行以下 Transact-SQL 代码,从而在发布服务器上注册分发服务器:
Use MASTER EXEC sys.sp_adddistributor @distributor = 'sql-mi-distributor.b6bf57.database.chinacloudapi.cn', @password = '<distributor_admin_password>'
创建发布
配置分发后,现在可以创建发布。 为此,请执行下列步骤:
在 SQL Server 上启动 SQL Server Management Studio。
连接到
sql-mi-publisher
托管实例。在“对象资源管理器”中,展开“复制”节点,然后右键单击“本地发布”文件夹 。 单击“新建发布...”。
选择“下一步”,离开“欢迎”页。
在“发布数据库”页上,选择之前创建的
ReplTutorial
数据库。 选择“下一页”。在“发布类型”页上,选择“事务发布” 。 选择“下一页”。
在“项目”页上,选中“表”旁边的框 。 选择“下一页”。
在“筛选器表行”页上,选择“下一步”而不添加任何筛选器 。
在“快照代理”页上,选中“立即创建快照并使快照保持可用状态,以初始化订阅”旁边的框 。 选择“下一页”。
在“代理安全性”页上,选择“安全设置…” 。提供要用于快照代理的 SQL Server 登录凭据,并连接到发布服务器。 选择“确定”以关闭“快照代理安全性”页 。 选择“下一页”。
在“向导操作”页上,选择“创建发布”并(视情况)选择“生成包含创建发布的步骤的脚本文件”(如果要保存此脚本以供以后使用) 。
在“完成向导”页上,将发布命名为
ReplTest
并选择“下一步”以创建发布 。创建发布后,请刷新“对象资源管理器”中的“复制”节点,并展开“本地发布”查看新发布 。
创建订阅
创建发布后,可以创建订阅。 为此,请执行下列步骤:
- 在 SQL Server 上启动 SQL Server Management Studio。
- 连接到
sql-mi-publisher
托管实例。 - 打开“新建查询”窗口,并运行以下 Transact-SQL 代码,以添加订阅和分发代理。 使用 DNS 作为订阅服务器名称的一部分。
use [ReplTutorial]
exec sp_addsubscription
@publication = N'ReplTest',
@subscriber = N'sql-vm-sub.repldns.com', -- include the DNS configured in the private DNS zone
@destination_db = N'ReplSub',
@subscription_type = N'Push',
@sync_type = N'automatic',
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0
exec sp_addpushsubscription_agent
@publication = N'ReplTest',
@subscriber = N'sql-vm-sub.repldns.com', -- include the DNS configured in the private DNS zone
@subscriber_db = N'ReplSub',
@job_login = N'azureuser',
@job_password = '<Complex Password>',
@subscriber_security_mode = 0,
@subscriber_login = N'azureuser',
@subscriber_password = '<Complex Password>',
@dts_package_location = N'Distributor'
GO
测试复制
配置复制后,可对其进行测试,方法是:在发布服务器上插入新项并监视更改传播到订阅服务器。
运行以下 T-SQL 代码片段以查看订阅服务器上的行:
Use ReplSub
select * from dbo.ReplTest
运行以下 T-SQL 代码片段以在发布服务器上插入附加的行,然后再次在订阅服务器上检查这些行。
Use ReplTutorial
INSERT INTO ReplTest (ID, c1) VALUES (15, 'pub')
清理资源
- 在 Azure 门户中导航到资源组。
- 选择托管实例,然后选择“删除”。 在文本框中键入
yes
以确认你要删除该资源,然后选择“删除”。 此过程可能需要一段时间才能在后台完成,在完成之前,你将无法删除“虚拟群集”或任何其他从属资源。 监视“活动”选项卡中的“删除”,确认已删除托管实例。 - 删除托管实例后,请将虚拟群集删除,方法是:在资源组中选择“虚拟群集”,然后选择“删除”。 在文本框中键入
yes
以确认你要删除该资源,然后选择“删除”。 - 删除任何剩余资源。 在文本框中键入
yes
以确认你要删除该资源,然后选择“删除”。 - 删除资源组,方法是:选择“删除资源组”,键入资源组的名称
myResourceGroup
,然后选择“删除” 。
已知错误
不支持 Windows 登录名
Exception Message: Windows logins are not supported in this version of SQL Server.
代理是使用 Windows 登录名配置的,需要改用 SQL Server 登录名。 使用“发布属性”的“代理安全性”页,将登录凭据更改为 SQL Server 登录名 。
未能连接到 Azure 存储
Connecting to Azure Files Storage '\\replstorage.file.core.chinacloudapi.cn\replshare' Failed to connect to Azure Storage '' with OS error: 53.
2019-11-19 02:21:05.07 获取了用于 replstorage 的 Azure 存储连接字符串 2019-11-19 02:21:05.07 正在连接到 Azure 文件存储 '\replstorage.file.core.chinacloudapi.cn\replshare' 2019-11-19 02:21:31.21 无法连接到 Azure 存储 '' 并显示 OS 错误:53。
这很可能是因为在 Azure 防火墙和/或 Windows 防火墙中关闭了端口 445。
Connecting to Azure Files Storage '\\replstorage.file.core.chinacloudapi.cn\replshare' Failed to connect to Azure Storage '' with OS error: 55.
在文件共享的文件路径中使用正斜杠而不是反斜杠会导致此错误。
- 这没关系:
\\replstorage.file.core.chinacloudapi.cn\replshare
- 这可能会导致 OS 55 错误:
'\\replstorage.file.core.chinacloudapi.cn/replshare'
无法连接到订阅服务器
The process could not connect to Subscriber 'SQL-VM-SUB
Could not open a connection to SQL Server [53].
A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections.
可能的解决方法:
- 确保端口 1433 处于打开状态。
- 确保在订阅服务器上启用 TCP/IP。
- 确认在创建订阅服务器时使用了 DNS 名称。
- 验证虚拟网络是否已正确链接到专用 DNS 区域。
- 验证是否已正确配置 A 记录。
- 验证是否正确配置了 VNet 对等互连。
没有可以订阅的发布
使用“新建订阅”向导添加新订阅时,你可能会发现没有作为可用选项列出的数据库和发布,并且可能会看到以下错误消息 :
There are no publications to which you can subscribe, either because this server has no publications or because you do not have sufficient privileges to access the publications.
虽然此错误消息可能是准确的,但实际上连接到的发布服务器上没有可用的发布,或者你缺少足够权限,此错误也可能是由较旧版本的 SQL Server Management Studio 所致。 尝试升级到 SQL Server Management Studio 18.0 或更高版本,以排除这是根本原因。
后续步骤
启用安全功能
请参阅什么是 Azure SQL 托管实例?一文,全面了解保护数据库的各种方式。 此文介绍了以下安全功能:
SQL 托管实例功能
有关托管实例功能的完整概述,请参阅: