本教程介绍了如何将数据从在 Compute Engine 上运行的 Microsoft SQL Server 2017 Enterprise 迁移到 Cloud SQL for SQL Server 2017 Enterprise。如果您是系统管理员、开发者、工程师、数据库管理员或 DevOps 工程师,那么本教程非常适合您。本教程介绍如何设置 SQL Server Distributor,如何使用 SQL Server Agent 将快照复制到 Cloud SQL for SQL Server 2017 并验证数据已成功导入。
在本教程中,您将使用快照复制让源和目标保持同步。快照复制会向订阅者发送每篇文章(即已发布的数据库对象)的完整副本。Cloud SQL 还支持仅发送增量数据的事务副本。事务副本的限制是表必须具有主键。如需详细了解 SQL Server 副本类型,请参阅 SQL Server 文档。
为简单起见,本教程使用源 SQL Server 托管 Distributor。在生产场景中,如果从 Google Cloud 外部复制数据,您可能更倾向于将 Distributor 托管在 Compute Engine 实例上的 Google Cloud 端。
本教程假定您熟悉以下内容:
- SQL Server
- Microsoft PowerShell
- Compute Engine
- Cloud SQL for SQL Server
目标
- 在 Compute Engine 上创建 SQL Server 虚拟机实例以托管示例数据库。
- 填充示例数据库。
- 创建 Cloud SQL for SQL Server 实例。
- 创建 Distributor。
- 设置发布和订阅。
- 启动从 SQL Server 复制到 Cloud SQL。
- 验证导入的数据。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
- Compute Engine
- Cloud SQL
- Cloud Storage
- SQL Server (premium with Compute Engine)
准备工作
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud SQL Admin and Compute Engine API APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud SQL Admin and Compute Engine API APIs.
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
- 安装您选择的任何远程桌面协议 (RDP) 客户端。如需了解详情,请参阅 Microsoft 远程桌面客户端。如果您已安装 RDP 客户端,则可以跳过此任务。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
创建 SQL Server 虚拟机
第一步是在 Compute Engine 上的 Windows 2016 虚拟机上创建一个 SQL Server 2017 实例,并使用 RDP 连接到该实例。
在 Cloud Shell 中,在 Windows Server 2016 上创建 SQL Server 2017 Standard 版实例。源数据库必须是 SQL Server Standard 版或 Enterprise 版数据库,因为较低层级没有数据库发布者功能。
gcloud compute instances create sqlserver --machine-type=n1-standard-4 \ --boot-disk-size=100GB \ --image-project=windows-sql-cloud \ --image-family=sql-std-2017-win-2016 \ --zone=us-central1-f \ --scopes=https://www.googleapis.com/auth/cloud-platform
在本教程中,您将在
us-central1-f
区域创建启动磁盘大小为 100 GB 的实例。如需了解详情,请参阅 Cloud 位置。生成 Windows 密码:
gcloud compute reset-windows-password sqlserver --zone=us-central1-f
在 Google Cloud 控制台中,转到虚拟机实例页面。
在 Google Cloud 控制台的 Compute Engine 部分中,点击 RDP 下拉列表,然后选择下载 RDP 文件选项以下载实例的 RDP 文件。
使用此文件通过 RDP 客户端连接到实例。如需了解详情,请参阅 Microsoft 远程桌面客户端。
在用户名和密码字段中,输入您为 SQL Server 虚拟机实例创建的用户名和密码。将网域字段留空,然后点击确定以连接到 SQL Server 虚拟机。
出现提示时,接受证书。
如果您接受条款,请点击继续。
在实例中,将所有窗口最小化,在 Windows 任务栏上点击开始,输入
PowerShell
,然后右键点击 Windows PowerShell 应用,并选择以管理员身份运行。在 PowerShell 提示符下,创建一个目录结构来存储此数据库:
mkdir c:\sql-server-data\adventureworks
创建和填充示例数据库
现在,您可以下载 Microsoft 的 AdventureWorks 数据库备份文件,并将其恢复到 SQL Server 实例中。此数据库模拟您要迁移的生产数据库。
从 PowerShell 命令行将
AdventureWorksLT2017.bak
备份文件下载到 C 盘:bitsadmin /transfer sampledb /dynamic /download /priority FOREGROUND "https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorksLT2017.bak " C:\sql-server-data\AdventureWorksLT2017.bak
恢复数据库:
osql -E -Q "USE [master] RESTORE DATABASE [AdventureWorksLT2017] FROM DISK = N'C:\sql-server-data\AdventureWorksLT2017.bak' WITH FILE = 1, MOVE N'AdventureWorksLT2012_Data' TO N'C:\sql-server-data\adventureworks\AdventureWorksLT2012.mdf', MOVE N'AdventureWorksLT2012_Log' TO N'C:\sql-server-data\adventureworks\AdventureWorksLT2012_log.ldf', NOUNLOAD, STATS = 5"
通过查询
Customer
表中的行数来验证新恢复的数据库。输出为 847 行。osql -E -Q "select count(*) from AdventureWorksLT2017.SalesLT.Customer"
准备 Cloud SQL 实例
在 Cloud Shell 中,创建 Cloud SQL for SQL Server 2017 Enterprise 版实例:
gcloud sql instances create target-sqlserver \ --database-version=SQLSERVER_2017_STANDARD \ --cpu=4 \ --memory=15 \ --storage-size=100 \ --root-password=sqlserver12@ \ --zone=us-central1-f
root 用户是
sqlserver
,其密码是sqlserver12@
。另请记下 SQL Server IP 地址。将源 SQL Server 虚拟机的 IP 地址存储在环境变量中:
sql_source_ip=$(gcloud compute instances describe sqlserver \ --zone=us-central1-f | grep natIP | awk '{print $2}') echo $sql_source_ip
将包含 Cloud SQL 实例的 SQL Server 虚拟机 IP 地址添加到许可名单(白名单):
gcloud sql instances patch target-sqlserver --authorized-networks=$sql_source_ip
创建目标数据库:
gcloud sql databases create AdventureWorksTarget --instance=target-sqlserver
在以管理员身份启动的 PowerShell 命令行中,检查与 Cloud SQL for SQL Server 的连接:
$cloud_sql_server_ip=gcloud sql instances describe target-sqlserver --format='value(ipAddresses.ipAddress)' osql -S $cloud_sql_server_ip -U sqlserver -P sqlserver12@ -Q "select 'test'"
该命令会输出
'test'
。
启动从虚拟机到 Cloud SQL 的复制
通过使用 SQL Server 快照复制,创建一个作业,以将数据库快照复制到 Cloud SQL 中。
设置 Distributor
现在,您将 SQL Server 虚拟机配置为 SQL Server Distributor。在实际应用中,Distributor 可以在单独的机器上运行,但在本教程中,在同一个虚拟机上运行它。
从以管理员身份启动的 PowerShell 命令行中,更新 SQL Server 本地实例名称以与虚拟机主机名相匹配:
$servername=hostname osql -E -Q "sp_dropserver 'INST-INSTALL-SQ';" osql -E -Q "sp_addserver '$servername', local;" Restart-Service -F MSSQLServer mkdir c:\sql-server-data\repldata
如果您收到
Cannot open MSSQLServer service on computer '.'.
错误,可能是您没有以管理员身份运行 PowerShell 命令行。验证实例名称现在是否为
"sqlserver"
:osql -E -Q "select @@servername;"
指定分发数据库:
$servername=hostname osql -E -Q "use master; exec sp_adddistributor @distributor = N'$servername', @password = N'';" osql -E -Q "exec sp_adddistributiondb @database = N'distribution', @data_folder = N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Data', @log_folder = N'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Data', @log_file_size = 2, @min_distretention = 0, @max_distretention = 72, @history_retention = 48, @deletebatchsize_xact = 5000, @deletebatchsize_cmd = 2000, @security_mode = 1"
配置分发数据库:
osql -E -Q " use [distribution] if (not exists (select * from sysobjects where name = 'UIProperties' and type = 'U ')) create table UIProperties(id int) if (exists (select * from ::fn_listextendedproperty('SnapshotFolder', 'user', 'dbo', 'table', 'UIProperties', null, null))) exec sp_updateextendedproperty N'SnapshotFolder', N'c:\sql-server-data\repldata', 'user', dbo, 'table', 'UIProperties' else exec sp_addextendedproperty N'SnapshotFolder', N'c:\sql-server-data\repldata', 'user', dbo, 'table', 'UIProperties' "
将 SQL Server 虚拟机与 Distributor 注册为发布者:
osql -E -Q "exec sp_adddistpublisher @publisher = N'$servername', @distribution_db = N'distribution', @security_mode = 1, @working_directory = N'c:\sql-server-data\repldata', @trusted = N'false', @thirdparty_flag = 0, @publisher_type = N'MSSQLSERVER'"
设置发布
分发现已设置完毕,您可以配置要发布哪些表了。
在 PowerShell 命令行中,启用并启动 SQL Server Agent:
Set-Service -Name SQLServerAgent -StartupType Automatic Start-Service -Name SQLServerAgent
为
AdventureWorksLT2017
数据库创建发布:$servername=hostname osql -E -Q " use [AdventureWorksLT2017] exec sp_replicationdboption @dbname = N'AdventureWorksLT2017', @optname = N'publish', @value = N'true'" osql -E -Q "use [AdventureWorksLT2017] exec sp_addpublication @publication = N'advn-pub3', @description = N'Snapshot publication of database ''AdventureWorksLT2017'' from Publisher ''$servername''.', @sync_method = N'native', @retention = 0, @allow_push = N'true', @allow_pull = N'true', @allow_anonymous = N'true', @enabled_for_internet = N'false', @snapshot_in_defaultfolder = N'true', @compress_snapshot = N'false', @ftp_port = 21, @ftp_login = N'anonymous', @allow_subscription_copy = N'false', @add_to_active_directory = N'false', @repl_freq = N'snapshot', @status = N'active', @independent_agent = N'true', @immediate_sync = N'true', @allow_sync_tran = N'false', @autogen_sync_procs = N'false', @allow_queued_tran = N'false', @allow_dts = N'false', @replicate_ddl = 1"
配置发布,以将源的快照发送到 Cloud SQL,每小时发送一次:
osql -E -Q " use [AdventureWorksLT2017] exec sp_addpublication_snapshot @publication = N'advn-pub3', @frequency_type = 4, @frequency_interval = 1, @frequency_relative_interval = 1, @frequency_recurrence_factor = 0, @frequency_subday = 8, @frequency_subday_interval = 1, @active_start_time_of_day = 0, @active_end_time_of_day = 235959, @active_start_date = 0, @active_end_date = 0, @job_login = null, @job_password = null, @publisher_security_mode = 1"
将文章(表)添加到发布。虽然
AdventureWorksLT2017
数据库包含许多表,但为了简单起见,您只复制三个表:Address
、Customer
和CustomerAddress
。osql -E -Q " use [AdventureWorksLT2017] exec sp_addarticle @publication = N'advn-pub3', @article = N'Address', @source_owner = N'SalesLT', @source_object = N'Address', @type = N'logbased', @description = null, @creation_script = null, @pre_creation_cmd = N'drop', @schema_option = 0x000000000803509D, @identityrangemanagementoption = N'manual', @destination_table = N'Address', @destination_owner = N'SalesLT', @vertical_partition = N'false' " osql -E -Q " use [AdventureWorksLT2017] exec sp_addarticle @publication = N'advn-pub3', @article = N'Customer', @source_owner = N'SalesLT', @source_object = N'Customer', @type = N'logbased', @description = null, @creation_script = null, @pre_creation_cmd = N'drop', @schema_option = 0x000000000803509D, @identityrangemanagementoption = N'manual', @destination_table = N'Customer', @destination_owner = N'SalesLT', @vertical_partition = N'false' " osql -E -Q " use [AdventureWorksLT2017] exec sp_addarticle @publication = N'advn-pub3', @article = N'CustomerAddress', @source_owner = N'SalesLT', @source_object = N'CustomerAddress', @type = N'logbased', @description = null, @creation_script = null, @pre_creation_cmd = N'drop', @schema_option = 0x000000000803509D, @identityrangemanagementoption = N'manual', @destination_table = N'CustomerAddress', @destination_owner = N'SalesLT', @vertical_partition = N'false' "
手动创建文章的快照。如果您不这样做,则调度程序创建初始快照可能需要长达一小时的时间。
osql -E -Q "use [AdventureWorksLT2017] exec sp_startpublication_snapshot @publication = N'advn-pub3'"
设置订阅
现在,您可以创建订阅以将已发布数据发送到 Cloud SQL。
从 PowerShell 命令行中,创建订阅以将发布快照发送到 Cloud SQL:
$cloud_sql_server_ip=gcloud sql instances describe target-sqlserver --format='value(ipAddresses.ipAddress)' $cloud_sql_user="sqlserver" $cloud_sql_password="sqlserver12@" $target_db_name="AdventureWorksTarget" osql -E -Q " use [AdventureWorksLT2017] exec sp_addsubscription @publication = N'advn-pub3', @subscriber = N'$cloud_sql_server_ip', @destination_db = N'$target_db_name', @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'advn-pub3', @subscriber = N'$cloud_sql_server_ip', @subscriber_db = N'$target_db_name', @job_login = null, @job_password = null, @subscriber_security_mode = 0, @subscriber_login = N'$cloud_sql_user', @subscriber_password = N'$cloud_sql_password', @frequency_type = 64, @frequency_interval = 0, @frequency_relative_interval = 0, @frequency_recurrence_factor = 0, @frequency_subday = 0, @frequency_subday_interval = 0, @active_start_time_of_day = 0, @active_end_time_of_day = 235959, @active_start_date = 20200408, @active_end_date = 99991231, @enabled_for_syncmgr = N'False', @dts_package_location = N'Distributor' "
验证 Cloud SQL 实例中是否有该数据:
osql -S $cloud_sql_server_ip -U $cloud_sql_user -P $cloud_sql_password -Q "select count(*) from [AdventureWorksTarget].[SalesLT].[CustomerAddress] UNION select count(*) from [AdventureWorksTarget].[SalesLT].[Customer] UNION Select count(*) from [AdventureWorksTarget].[SalesLT].[Address]"
该命令会输出
417
、450
和847
清理
完成本教程后,您可以清理您创建的资源,让它们停止使用配额,以免产生费用。以下部分介绍如何删除或关闭这些资源。
删除项目
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
后续步骤
- 了解如何使用备份文件将数据从 SQL Server 2017 迁移到 Cloud SQL for SQL Server。
- 了解如何使用备份文件将数据从 SQL Server 2008 迁移到 Cloud SQL for SQL Server。
- 探索有关 Google Cloud 的参考架构、图表和最佳实践。查看我们的 Cloud 架构中心。