SQLServer 数据源为您提供读取和写入 SQLServer 的双向通道数据集成能力,实现不同数据源与 SQLServer 之间进行数据传输。本文为您介绍 DataSail 的 SQLServer 数据同步的能力支持情况。
已完成 SQLServer 数据源配置操作,详见配置 SQLServer 数据源。
使用实时整库同步解决方案前,请确保已完成以下配置:
在正式启动实时同步任务之前,请逐项确认以下清单:
| | | | | \
| 序号 | 检查项 | 验证方式 | 期望结果 |
|---|---|---|---|
| 1 | SQL Server 版本 | SELECT @@VERSION |
≥ 2016 SP1 |
| 2 | 数据库 CDC 已启用 | SELECT is_cdc_enabled FROM sys.databases WHERE name = DB_NAME() |
返回 1 |
| 3 | 表 CDC 已启用 | SELECT is_tracked_by_cdc FROM sys.tables WHERE name = 'your_table' |
返回 1 |
| 4 | Agent 运行状态 | SQL Server Configuration Manager | 状态为 Running |
| 5 | CDC 作业正常 | EXEC sys.sp_cdc_help_jobs |
作业状态正常 |
| 6 | 同步账号权限 | SELECT * FROM fn_my_permissions(NULL, 'DATABASE') |
包含 SELECT、VIEW DATABASE STATE |
| 7 | 网络连通 | 数据源注册 > 测试连通性 | 连通成功 |
| 8 | CDC 保留期 | EXEC sys.sp_cdc_help_jobs |
retention ≥ 业务需求 |
常见高级参数说明如下表所示。
| | | | \
| 参数 | 说明 | 默认值 |
|---|---|---|
snapshot.mode |
快照模式:initial(含全量)/ schema_only(仅增量) |
initial |
poll.interval.ms |
CDC 轮询间隔(毫秒) | 1000 |
max.batch.size |
每次轮询返回的最大变更事件数 | 2048 |
database.history.retention.hours |
Schema 历史保留时长(小时) | 168 |
方案提交后,可以在解决方案列表查看运行状态,支持以下运维操作:
SQLServer 数据源测试连通性成功后,进入到数据开发界面,开始新建 SQLServer 相关通道任务。
新建任务方式详见离线数据同步、流式数据同步。
任务创建成功后,您可根据实际场景,配置 SQLServer 批式读、SQLServer 批式写或 SQLServer 流式写等通道任务。
数据来源选择 SQLServer,并完成以下相关参数配置:
其中参数名称前带 * 的为必填参数,名称前未带 * 的为可选填参数。
| | | \
参数 |
说明 |
|---|---|
| *数据源类型 | 下拉选择 SQLServer 数据源类型。 |
| *数据源名称 | 已在数据源管理中注册成功的 SQLServer 数据源,下拉可选。 |
| 若还未建立相应数据源,可单击数据源管理按钮,前往创建 SQLServer 数据源。 | |
| *Schema 目录 | 数据库下已有的 Schema 目录信息,下拉可选。 |
| *数据表 | 选择需要采集的数据表名称信息,目前单个任务只支持将单表的数据采集到一个目标表中。 |
| 数据过滤 | 支持您将需要同步的数据进行筛选条件设置,只同步符合过滤条件的数据,可直接填写关键词 where 后的过滤 SQL 语句,例如:create_time > '${date}',表示只同步 create_time 大于等于 ${date} 的数据,不需要填写 where 关键字。 |
| :::tip | |
| * 该过滤语句通常用作增量同步,暂时不支持 limit 关键字过滤,其 SQL 语法需要和选择的数据源类型对应。 | |
| * 如果不配置过滤条件,默认会同步全量数据。 | |
| ::: | |
| 切分建 | 根据配置的字段进行数据分片,建议使用主键或有索引的列作为切分键: |
| * 如果表没有主键或者索引列,可以不配置该字段,同步任务不会进行分片,并以单并发的方式同步所有的数据; | |
| * 建议使用主键或有索引的列作为切分键,切分键配置没有索引的列同步任务会比较慢; | |
| :::tip | |
| 目前仅支持类型为整型或字符串的字段作为切分建。 | |
| ::: |

数据目标端选择 SQLServer,并完成以下相关参数配置:
| | | \
参数 |
说明 |
|---|---|
| *目标类型 | 数据去向目标类型选择 SQLServer。 |
| *数据源名称 | 已在数据源管理界面注册的 SQLServer 数据源,下拉可选。 |
| 若还未建立相应数据源,可单击数据源管理按钮,前往创建 SQLServer 数据源。 | |
| *Schema 目录 | 数据库下已有的 Schema 目录信息,下拉可选。 |
| *数据表 | 数据源下所属需数据写入的表名,下拉可选。 |
| 写入前准备语句 | 在执行该数据集成任务前,需要率先执行的 SQL 语句,通常是为了使任务重跑时支持幂等。 |
例如您可以通过填写语句,清空表中的某些旧数据,清空完成后,再执行集成任务写入新的数据。如删除 date='${date}' 的数据:delete from table_name where date='${date}' |
|
| 语句填写完成后,您可单击右侧的校验按钮,进行语句校验是否符合逻辑。 | |
| :::tip | |
| 可视化通道任务配置中只允许执行一条写入前准备语句。 | |
| ::: | |
| 写入后准备语句 | 执行数据同步任务之后执行的 SQL 语句。例如写入完成后插入某条特殊的数据,标志导入任务执行结束。 |
| 语句填写完成后,您可单击右侧的校验按钮,进行语句校验是否符合逻辑。 | |
| :::tip | |
| 可视化通道任务配置中只允许执行一条写入后准备语句。 | |
| ::: | |
| *数据写入方式 | 下拉选择数据写入 SQLServer 的方式: |
| * insert into: 当主键/唯一性索引冲突时会无法写入冲突的行,任务会运行失败。 | |
| :::tip | |
如果希望主键/唯一索引冲突时任务正常执行,可以添加高级参数: job.writer.is_insert_ignore 设置为 true |
|
| ::: |
支持可视化方式配置流式写入 SQLServer 单表。SQLServer Writer 通过 JDBC 远程连接 SQLServer 数据库,并执行相应的 SQL 语句,将数据写入 SQLServer。流式写入 SQLServer 配置方式如下:

数据目标端选择 SQLServer,并完成以下相关参数配置:
其中参数名称前带 * 的为必填参数,名称前未带 * 的为可选填参数。
| | | \
参数 |
说明 |
|---|---|
| *目标类型 | 数据去向目标类型选择 SQLServer。 |
| *数据源名称 | 已在数据源管理界面注册的 SQLServer 数据源,下拉可选。 |
| 若还未建立相应数据源,可单击数据源管理按钮,前往创建 SQLServer 数据源。 | |
| *Schema 目录 | 数据库下已有的 Schema 目录信息,下拉可选。 |
| *数据表 | 数据源下所属需数据写入的表名,下拉可选。 |
数据来源和目标端配置完成后,需要指定来源和目标端的字段映射关系。根据字段映射关系,数据集成任务将源端字段中的数据,写入到目标端对应字段中。
您可通过以下三种方式操作字段映射关系:
自动添加:单击自动添加按钮,根据两端数据表信息,可以自动填充来源和目标的字段信息。
手动添加:单击手动添加按钮,可以手动编辑来源和目标的字段信息,可以逐个添加。
:::tip
来源端字段信息支持输入数据库函数和常量配置,单击手动添加按钮,在源表字段中输入需添加的值,并选择函数或常量类型,例如:
getdate()、current_timestamp() 等 SQLServer 数据库支持的函数。'123'、'${DATE}'、'${hour}' 等,输入值两侧需要加上英文单引号,支持结合时间变量参数使用。移动\删除字段:可以根据需要移动字段映射顺序或删除字段。
SQLServer 数据源支持使用脚本模式(DSL)的方式进行配置。在某些复杂场景下,或当数据源类型暂不支持可视化配置时,可通过任务脚本的方式,按照统一的 JSON 格式编写数据集成任务。
进入 DSL 模式操作流程,可详见配置 MySQL 任务的3.3.1 进入 DSL 模式。
以下为完整可运行的 SQLServer 批式读脚本示例:
{
"version": "0.2",
"type": "batch",
"reader": {
"type": "sql_server",
"datasource_id": 12345,
"parameter": {
"table_schema": "dbo",
"table_name": "your_table",
"columns": [
{"name": "id", "type": "int"},
{"name": "name", "type": "varchar"},
{"name": "created_at", "type": "datetime"},
{"name": "amount", "type": "decimal"}
],
"filter": "created_at >= '${date}'",
"split_pk": "id"
}
},
"writer": {},
"common": {
"parameter": {}
}
}
Reader 参数说明如下表所示,其中参数名称前带 * 的为必填参数,名称前未带 * 的为可选填参数:
| | | | \
| 参数名 | 描述 | 默认值 |
|---|---|---|
| *type | 数据源类型,对于 SQLServer 类型,填写:sql_server | 无 |
| *datasource_id | 注册的 SQLServer 数据源 ID。可以在项目控制台 > 数据源管理界面中查找。 | 无 |
| *table_schema | 填写 SQLServer 数据库中的 Schema 名称。 | 无 |
| *table_name | 需要同步的数据表名称,目前单个任务只支持将单表的数据采集到一个目标表中。 | 无 |
| filter | 同步数据的筛选条件,同步数据时只会同步符合过滤条件的数据,直接填写关键词 where 后的过滤 SQL 语句。 | \ |
| \ | ||
* 如将过滤条件指定为:date>=${date} ,表示只同步 date 大于等于 ${date}。 |
\ | |
| * 过滤条件可以有效地进行业务增量同步。如果不配置,默认会同步全量数据。 | 无 | |
| split_pk | 根据配置的字段进行数据分片,建议使用主键或有索引的列作为切分键,同步任务会启动并发任务进行数据同步,提高同步速率: | \ |
| \ | ||
| * 如果表没有主键或者索引列,可以不配置该字段,同步任务不会进行分片,并以单并发的方式同步所有的数据; | \ | |
| * 建议使用主键或有索引的列作为切分键,切分键配置没有索引的列同步任务会比较慢; | \ | |
| \ | ||
| :::tip | \ | |
| 目前仅支持类型为整型或字符串的字段作为切分建。 | \ | |
| ::: | 无 | |
| *columns | 所配置的表中,需要同步的列名集合,使用 JSON 的数组描述字段信息。 | \ |
| \ | ||
| * 支持列裁剪:列可以挑选部分列进行导出。 | \ | |
| * 支持列换序:列可以不按照表 Schema 信息顺序进行导出。 | \ | |
| * column 必须显示指定同步的列集合,不允许为空。 | \ | |
| * 支持函数、常量形式添加列: | \ | |
| * 函数:SQLServer Reader 支持您输入 getdate()、current_timestamp() 等 SQLServer 数据库支持的函数。 | \ | |
| * 常量:SQLServer Reader 支持您自定义输入常量值,如 '123'、'${DATE}'、'${hour}' 等,输入值两侧需要加上英文单引号,支持结合时间变量参数使用。 | 无 |
以下为完整可运行的 SQLServer 批式写脚本示例:
{
"version": "0.2",
"type": "batch",
"reader": {
"type": "xx",
"datasource_id": null,
"parameter": {}
},
"writer": {
"type": "sql_server",
"datasource_id": 12345,
"parameter": {
"table_schema": "dbo",
"table_name": "your_target_table",
"pre_sql_list": [
"DELETE FROM [dbo].[your_target_table] WHERE date = '${date}'"
],
"post_sql_list": [],
"write_mode": "directlyInsert",
"columns": [
{"name": "id", "type": "int"},
{"name": "name", "type": "varchar"},
{"name": "created_at", "type": "datetime"},
{"name": "amount", "type": "decimal"}
]
}
},
"common": {
"parameter": {}
}
}
Writer 参数说明如下表所示,其中参数名称前带 * 的为必填参数,名称前未带 * 的为可选填参数:
| | | | \
| 参数名 | 描述 | 默认值 |
|---|---|---|
| *type | 数据源类型,对于 SQLServer 类型,填写:sql_server | 无 |
| *datasource_id | 注册的 SQLServer 数据源 ID。可以在项目控制台 > 数据源管理界面中查找。 | 无 |
| *table_schema | 填写 SQLServer 数据库中的 Schema 名称。 | |
| *table_name | 填写需要同步的数据表名称,一个数据集成任务只能同步数据到一张目标表。 | 无 |
| pre_sql_list | 写入前准备语句:在执行数据集成任务前,率先执行的 SQL 语句。此语句通常是为了使任务重跑时支持幂等。 | \ |
例如执行前清空表中的某些旧数据,清空完成后,在执行集成任务写入新的数据,例如删除 date='${date}' 的数据:["delete from table_name where date='${date}'", "xxx"] |
\ | |
| :::tip | \ | |
| DSL 模式支持配置多条写入前准备语句,多条语句之间用英文逗号分隔。 | \ | |
| ::: | 无 | |
| post_sql_list | 写入后准备语句:执行数据同步任务后执行的 SQL 语句。例如数据写入完成后,插入某条特殊的数据,标志导入任务执行结束。 | \ |
示例:["insert into table_name (col1,col2..) values(values1,values2)", "xxx"] |
\ | |
| :::tip | \ | |
| DSL 模式支持配置多条写入后准备语句,多条语句之间用英文逗号分隔。 | \ | |
| ::: | 无 | |
| *write_mode | 数据导入模式,支持 insert into 模式: | \ |
| insert into:当主键/唯一性索引冲突时会写不进去冲突的行,任务会运行失败。 | \ | |
| \ | ||
* 使用该模式时,请将 write_mode 设置为 directlyInsert |
\ | |
* 如果希望主键/唯一索引冲突时任务正常执行,可以在 writer.parameter 参数下添加高级参数 job.writer.is_insert_ignore:true |
无 | |
| *columns | 所配置的表中需要同步的列名集合,使用 JSON 的数组描述字段信息。 | \ |
| \ | ||
| * 支持列裁剪:列可以挑选部分列进行导出。 | \ | |
| * 支持列换序:列可以不按照表 Schema 信息顺序进行导出。 | \ | |
| * column 必须显示指定同步的列集合,不允许为空。 | \ | |
| * column 必须与导入的源端列集合对齐,不允许多列或少列。 | 无 |
job.reader. 前缀,写参数需要加上 job.writer. 前缀,如下图所示:reader.parameter 下,写参数请配置到 writer.parameter 下,直接输入参数名称和参数值。如下图所示:
| | | | \
| 参数名 | 描述 | 默认值 |
|---|---|---|
| init_sql | 读取数据前执行的 SQL 语句。对于视图的查询可能需要使用 init SQL 语句初始化环境 | 无 |
| reader_fetch_size | 每次拉取的数据条数,只在准确分片中有效。 | 10000 |
| shard_split_mode | 分片模式,支持准确分片、并发分片、不分片三种模式: | \ |
| \ | ||
| * 准确分片(默认):根据配置的分片键将数据拆分为不同的区间,除下最后一个区间外,每个区间精准的有 reader_fetch_size 条数。 | \ | |
| * 适用场景:通用场景。 | \ | |
| :::tip | \ | |
| 拉取数据量很大的表或者分片键不是主键或者索引键时,该分片模式分片时间会比较长。 | \ | |
| ::: | \ | |
| * 支持的分片键类型:整型、字符串; | \ | |
* 配置方式:将该参数配置为 accurate。 |
\ | |
| * 并发分片:根据表的最大最小值,将所有的数据按照并发数进行区间分片。 | \ | |
| * 适用场景:整型主键的大表; | \ | |
| * 支持的分片键类型:仅整型; | \ | |
* 配置方式:将该参数配置为 parallelism。 |
\ | |
| * 不分片:不进行分片,单并发读取。 | \ | |
| * 适用场景:适用于没有主键、索引键的表。 | \ | |
* 配置方式:将该参数配置为 nosplit 或者不配置 split_pk 。 |
准确分片 | |
| customized_sql | 自定义查询读取 SQL 语句。filter 过滤配置项不足以描述所筛选的条件,可通过该配置项来自定义执行较复杂的查询 SQL。 | \ |
例如:需要进行多表 join 后同步数据,使用select a,b from table_a join table_b on table_a.id = table_b.id。 |
\ | |
| :::tip | \ | |
| 配置该高级参数项后,数据同步任务仍需配置 table_name、column 、split_pk 、shard_split_mode 等必填配置项。然而,在执行同步时,系统将忽略这些配置项信息,直接使用该高级参数项中配置的内容进行数据查询和筛选。 | \ | |
| ::: | 无 |
| | | | \
参数名 |
描述 | 默认值 |
|---|---|---|
| is_insert_ignore | insert into 模式时,主键或者唯一键冲突时任务失败还是忽略冲突。 | false |
| write_batch_interval | 一次性批量提交的数据条数,该值可以减少与 SQLServer 网络的交互次数并提升整体吞吐量。如果该值设置过大可能会导致数据同步进程 OOM。 | 100 |
| write_retry_times | SQLServer 写入失败时重试次数。 | 3 |
| retry_interval_seconds | 写入失败后两次重试的时间间隔,单位秒。 | write_batch_interval / 10 |
| | | | \
| 对比维度 | CDC 实时同步 | 离线查询增量 |
|---|---|---|
| 延迟 | 秒级~分钟级 | 依赖调度周期 |
| 完整性 | 捕获所有变更(含删除) | 仅捕获过滤条件匹配的数据 |
| 服务端开销 | 需要 CDC + Agent,有一定开销 | 查询开销,对大表可能较重 |
| 配置复杂度 | 需配置 CDC、Agent、权限 | 仅需读权限 |
| 版本要求 | ≥ 2016 SP1 | 所有版本 |
| 推荐场景 | 实时数仓、数据湖、跨库复制 | 报表同步、定期抽取 |
在离线写入场景中,任务重跑时需要保证幂等性(重复执行结果一致)。推荐以下方式:
方式一:写入前清理目标分区数据(推荐)
-- 在写入前准备语句中清除当日数据
DELETE FROM [dbo].[target_table] WHERE date = '${date}';
方式二:使用 MERGE 语句实现 Upsert
目前 DataSail 的 SQLServer Writer 仅支持 insert into 模式。如需 Upsert 能力,可考虑以下替代方案:
post_sql_list 执行 MERGE 语句。is_insert_ignore: true 跳过主键冲突行。
-- 查看 CDC 捕获作业的最新 LSN
USE [your_database];
SELECT
ct.capture_instance,
ct.start_lsn,
ct.end_lsn,
sys.fn_cdc_map_lsn_to_time(ct.start_lsn) AS start_time
FROM cdc.lsn_time_mapping ct
ORDER BY ct.tran_end_time DESC;
CDC 变更数据存储在系统表中,如果不及时清理会占用大量空间。
-- 查看 CDC 变更表的空间占用
SELECT
OBJECT_NAME(object_id) AS table_name,
SUM(reserved_page_count) * 8 / 1024 AS size_mb
FROM sys.dm_db_partition_stats
WHERE OBJECT_NAME(object_id) LIKE 'dbo_%_CT'
GROUP BY object_id
ORDER BY size_mb DESC;
| | | | \
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| CDC 变更数据未更新 | SQL Server Agent 未运行 | 启动 Agent 服务 |
| CDC 数据丢失 | 保留期过短,清理作业已删除 | 调大 retention 参数 |
| 性能下降 | CDC 变更表过大 | 及时清理历史变更数据 |
| 新增表未同步 | 新表未启用 CDC | 执行 sp_cdc_enable_table |
| 同步账号权限不足 | 权限配置不完整 | 授权,相关操作请参见2.1 账号与权限。 |
write_batch_interval,推荐 100~1000。poll.interval.ms。