通过事务复制可以将数据从一个数据库复制到 SQL Server 或 Azure SQL 托管实例中托管的另一个数据库。 SQL 托管实例可以是复制拓扑中的发布服务器、分发服务器或订阅服务器。 有关可用配置,请参阅事务复制配置。
在本教程中,你将了解如何执行以下操作:
- 将 SQL 托管实例配置为复制发布服务器。
- 将 SQL 托管实例配置为复制分发服务器。
- 将 SQL Server 配置为订阅服务器。
本教程面向经验丰富的受众,假定用户熟悉在 Azure 中部署和连接到 SQL 托管实例和 SQL Server VM。
注意
本文介绍了如何在 Azure SQL 托管实例中使用事务复制。 它与故障转移组无关,这是一项 Azure SQL 托管实例功能,可用于创建单个实例的完整可读副本。 配置故障转移组的事务复制时还有其他注意事项。
先决条件
若要完成本教程,请确保具备以下先决条件:
- 一个 Azure 订阅。
- 体验在同一虚拟网络中部署两个 SQL 托管实例。
- 本地或 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
创建两个 SQL 托管实例
使用 Azure 门户在此新资源组中创建两个 SQL 托管实例。
发布服务器 SQL 托管实例的名称应为
sql-mi-publisher
(以及用于随机化的几个字符),虚拟网络的名称应为vnet-sql-mi-publisher
。分发服务器 SQL 托管实例的名称应为
sql-mi-distributor
(以及用于随机化的几个字符),它应 与发布服务器 SQL 托管实例位于同一虚拟网络中。
有关创建 SQL 托管实例的详细信息,请参阅 门户中的“创建 SQL 托管实例”。
注意
为了简单起见,由于它是最常见的配置,本教程建议将分发服务器 SQL 托管实例放置在与发布服务器相同的虚拟网络中。 但是,可以在单独的虚拟网络中创建分发服务器。 为此,需要在发布服务器和分发服务器的虚拟网络之间配置 VNet 对等互连,然后在分发服务器和订阅服务器的虚拟网络之间配置 VNet 对等互连。
创建 SQL Server VM
使用 Azure 门户创建 SQL Server 虚拟机。 SQL Server 虚拟机应具有以下特征:
- 名称:
sql-vm-subscriber
- 图像:SQL Server 2016 或更高版本
- 资源组:与 SQL 托管实例相同
- 虚拟网络:
sql-vm-subscriber-vnet
有关将 SQL Server VM 部署到 Azure 的详细信息,请参阅 快速入门:创建 SQL Server VM。
配置 VNet 对等互连
配置 VNet 对等互连以启用两个 SQL 托管实例的虚拟网络与 SQL Server 的虚拟网络之间的通信。 为此,请使用以下 PowerShell 代码片段:
# Set variables
$SubscriptionId = '<SubscriptionID>'
$resourceGroup = 'SQLMI-Repl'
$pubvNet = 'sql-mi-publisher-vnet'
$subvNet = 'sql-vm-subscriber-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)并连接到这两个 SQL 托管实例来测试连接。 有关使用 SSMS 连接到 SQL 托管实例的详细信息,请参阅 使用 SSMS 连接到 SQL 托管实例。
创建专用 DNS 区域
专用 DNS 区域允许 SQL 托管实例和 SQL Server 之间的 DNS 路由。
创建专用 DNS 区域
登录到 Azure 门户。
选择“+ 创建资源”,创建新的 Azure 资源。
在 Azure 市场中搜索
private dns zone
。选择Microsoft发布的 专用 DNS 区域 资源,然后选择“ 创建 ”以创建 DNS 区域。
从下拉列表中选择订阅和资源组。
为 DNS 区域提供任意名称,如
repldns.com
。选择“查看 + 创建”。 查看专用 DNS 区域的参数,然后选择“ 创建 ”以创建资源。
创建 A 记录
转到新的“专用 DNS 区域”并选择“概述”。
选择+记录集以创建新的A记录。
提供 SQL Server VM 的名称以及专用内部 IP 地址。
选择“确定”以创建 A 记录。
链接虚拟网络
转到“专用 DNS 区域”并选择“虚拟网络链接” 。
选择“+ 添加”。
提供链接的名称,如
Pub-link
。从下拉列表中选择订阅,然后选择发布者 SQL 托管实例的虚拟网络。
选中“启用自动注册”旁边的框。
选择“确定”以链接虚拟网络。
重复这些步骤,为订阅服务器虚拟网络添加一个链接,并对其命名,例如
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=123456789aBcDeFgHiJkLmNoPqRsTuVwXyZ==;EndpointSuffix=core.chinacloudapi.cn
有关详细信息,请参阅管理存储帐户访问密钥。
创建数据库
在发布服务器 SQL 托管实例上创建新数据库。 为此,请执行下列步骤:
- 在 SQL Server 上启动 SQL Server Management Studio。
- 连接到发布服务器 SQL 托管实例(
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 托管实例(sql-mi-distributor
)上配置分发。 为此,请执行下列步骤:
在 SQL Server 上启动 SQL Server Management Studio。
连接到分发服务器 SQL 托管实例(
sql-mi-distributor
)。打开 “新建查询” 窗口,并运行以下 Transact-SQL 代码,在分发服务器 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=123456789aBcDeFgHiJkLmNoPqRsTuVwXyZ==;EndpointSuffix=core.chinacloudapi.cn'
注意
请确保对
\
参数仅使用反斜杠(@working_directory
)。 在连接到文件共享时使用正斜杠(/
)可能会导致错误。连接到发布服务器 SQL 托管实例(
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 托管实例(
sql-mi-publisher
)。在“对象资源管理器”中,展开“复制”节点,然后右键单击“本地发布”文件夹 。 选择新建发布。
选择“下一步”,离开“欢迎”页。
在“发布数据库”页面上,选择您之前创建的 数据库。 选择“下一页”。
在发布类型页面上,选择事务性发布。 选择“下一页”。
在“项目”页上,选中“表”旁边的框。 选择“下一页”。
在“筛选器表行”页上,选择“下一步”而不添加任何筛选器 。
在“快照代理”页上,选中“立即创建快照并使快照保持可用状态,以初始化订阅”旁边的框 。 选择“下一页”。
在 “代理安全 ”页上,选择“ 安全设置...”。提供用于快照代理并连接到发布服务器的 SQL Server 登录凭据。 选择确定以关闭快照代理安全性页面。 选择“下一页”。
在“向导操作”页上,选择“创建发布”并(视情况)选择“生成包含创建发布的步骤的脚本文件”(如果要保存此脚本以供以后使用) 。
在 “完成向导 ”页上,为出版物
ReplTest
命名,然后选择“ 下一步 ”以创建出版物。创建发布后,请刷新“对象资源管理器”中的“复制”节点,并展开“本地发布”以查看您的新发布。
创建订阅
创建发布后,可以创建订阅。 为此,请执行下列步骤:
- 在 SQL Server 上启动 SQL Server Management Studio。
- 连接到发布服务器 SQL 托管实例(
sql-mi-publisher
)。 - 打开“新建查询”窗口,并运行以下 Transact-SQL 代码,以添加订阅和分发代理。 使用 DNS 作为订阅服务器名称的一部分。
use [ReplTutorial]
exec sp_addsubscription
@publication = N'ReplTest',
@subscriber = N'sql-vm-subscriber.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-subscriber.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 门户中导航到资源组。
- 选择 SQL 托管实例,然后选择“ 删除”。 键入
yes
文本框以确认要删除资源,然后选择“ 删除”。 此过程可能需要一些时间才能在后台完成,在完成之前,将无法删除 虚拟群集 或任何其他依赖资源。 监视 “活动 ”选项卡中的删除,以确认 SQL 托管实例已删除。 - 删除 SQL 托管实例后,请在资源组中选择 虚拟群集 ,然后选择 “删除”。 键入
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 Obtained Azure Storage Connection String for replstorage
2019-11-19 02:21:05.07 Connecting to Azure Files Storage '\\replstorage.file.core.chinacloudapi.cn\replshare'
2019-11-19 02:21:31.21 Failed to connect to Azure Storage '' with OS error: 53.
这可能是因为端口 445 在 Azure 防火墙、Windows 防火墙或两者中关闭。
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-SUBSCRIBER
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 或更高版本,以排除此问题作为根本原因。