如何通过查询/脚本配置本地SQL Server到Azure SQL的周期性定时迁移
本地SQL Server到Azure SQL 12小时定时同步实现方案
首先明确前提:Azure SQL侧的调度任务默认无法直接访问内网部署的本地SQL Server,必须先打通网络链路,否则后续任务配置完也会连不上源库。
一、前置网络与连通性配置
- 网络打通二选一即可:
- 方案1:配置站点到站点VPN,把本地SQL Server所在的内网和Azure虚拟网络打通,不需要暴露本地数据库的公网端口,安全性更高
- 方案2:给两台本地SQL Server开放公网访问端口(默认1433),在本地防火墙和SQL Server的访问规则里,放行Azure SQL服务对应的出口IP段
- 在Azure SQL数据库中创建指向两台本地SQL Server的链接服务器,创建后先手动验证连通性,示例T-SQL如下:
-- 创建指向第一台本地SQL Server的链接服务器 EXEC sp_addlinkedserver @server = N'Local_SQL_1', @srvproduct=N'SQL Server'; -- 配置链接服务器的访问凭据,使用本地库中具备只读权限的账号即可 EXEC sp_addlinkedsrvlogin @rmtsrvname = N'Local_SQL_1', @useself = N'FALSE', @locallogin = NULL, @rmtuser = N'本地库只读账号', @rmtpassword = '对应账号密码';
- 参照上述语句创建指向第二台本地SQL Server的链接服务器
Local_SQL_2,创建完成后执行测试查询SELECT TOP 1 * FROM [Local_SQL_1].[对应业务库名].[dbo].[任意业务表],能正常返回结果再进行后续操作。
二、适配现有迁移脚本为可调度的存储过程
- 把你已经写好的本地数据提取脚本做适配:所有访问本地表的路径,统一改成链接服务器的四部分命名格式:
[链接服务器名].[数据库名].[架构名].[表名],比如访问第一台本地库的用户表就要写成[Local_SQL_1].[TradeDB].[dbo].[Users] - 将适配完成的脚本封装为Azure SQL侧的存储过程,示例命名为
sp_SyncDataFromLocal,存储过程逻辑里建议加两块内容:- 同步前的数据清理逻辑(全量同步就清空目标表,增量同步就删除对应时间范围的旧数据,避免重复写入)
- 同步日志记录逻辑,把每次执行的时间、同步的数据行数、执行报错信息写入专门的同步日志表,方便后续排查问题
- 手动执行一次封装好的存储过程,确认数据能正常从本地拉取、写入Azure SQL的目标表,没有权限、语法、数据类型不匹配的报错。
三、配置每12小时一次的定时调度
根据你用的Azure SQL部署类型选对应的调度方式即可:
- 如果是Azure SQL单一数据库/弹性池:使用弹性作业实现调度
- 先创建作业代理和对应的作业存储数据库,把需要同步的目标Azure SQL库加入作业目标组
- 新建作业,添加作业步骤:步骤类型选T-SQL,执行内容为
EXEC sp_SyncDataFromLocal - 配置作业调度规则:设置重复周期为12小时,每日执行2次,选定首次执行时间后开启作业即可
- 如果是Azure SQL托管实例:直接使用内置的SQL Server代理配置定时任务,操作和本地SQL Server的Agent配置完全一致,新建作业后添加执行存储过程的步骤,设置调度周期为每12小时运行1次即可。
排查注意点
- 作业执行报连接错误时,优先检查网络链路是否正常、本地防火墙规则是否放通了Azure侧IP、链接服务器配置的账号权限是否足够
- 如果单次同步数据量超过10万行,建议在存储过程里加分批写入逻辑,避免长时间执行触发Azure SQL的超时限制
- 不要直接在调度任务里写零散的迁移脚本,全部封装到存储过程里,后续修改同步逻辑、调试都更方便
内容的提问来源于stack exchange,提问作者Kamlakar Pawar
相关产品推荐
相关产品推荐

