Apache Seatunnel 抽取SQL server实时同步到Oracle(四)
前面文档已经测试seatunnel可以正常抽取SQL server数据库表,接下来我们来配置SQL server到Oracle的实时同步。
链接: Apache seatunel配置-数据同步测试(直接把采集数据打印到控制面板) - SQL server
关键说明与前置条件:
要实现从 SQL Server 到 Oracle 的实时同步,需要将 Source 从批处理的 Jdbc 换成 CDC 连接器 SqlServer-CDC,并将 job.mode 改为 STREAMING。Sink 端则使用 Oracle JDBC 连接器。
- 驱动依赖
SQL Server CDC 需要 mssql-jdbc 驱动,Oracle Sink 需要 ojdbc8 驱动(以及可选的 orai18n.jar 用于中文字符集)。两者都需要放在 ${SEATUNNEL_HOME}/lib/ 目录下。
- SQL Server 端开启 CDC
实时同步的前提是源库和表已启用 CDC。需要在 SQL Server 上执行类似以下命令(需 sysadmin 权限):
-- 对数据库启用 CDC
EXEC sys.sp_cdc_enable_db;
-- 对表 testtab 启用 CDC(需要 SQL Server Agent 运行)
EXEC sys.sp_cdc_enable_table
@source_schema = N'dbo',
@source_name = N'testtab',
@role_name = NULL;
- 关于 table-names 格式
SQL Server CDC 的 table-names 要求使用 三段式:数据库名.schema名.表名,例如 AMDBdatabase.dbo.testtab。这一点与批处理 Jdbc Source 中只写 dbo.testtab 不同。
- Oracle Sink 的 database 与 table
Oracle 中表默认属于当前用户对应的模式(Schema)。如果你用 ogg_cdc 或专用用户连接 Oracle,database 填该用户对应的模式名即可。表名 TESTTAB 在 Oracle 中默认是大写(未加引号创建时),这里保持一致。
- 主键
CDC 同步要求源表有主键,否则无法正确处理更新和删除事件。你的 testtab 已有 id 主键,符合要求。
调整conf配置文件
说明:目标不需要提前创建tab2表结构
如果存在则先删除
SQL> drop table tab2 purge;
Table dropped.
cat .../config/demo_mssql_to_oracle.conf
env {
job.mode = "STREAMING"
parallelism = 1
# 实时作业需要 checkpoint 来保证断点续传和一致性
checkpoint.interval = 10000
}
source {
SqlServer-CDC {
base-url = "jdbc:sqlserver://192.168.56.122:1433;databaseName=AMDBdatabase;encrypt=false"
username = "ogg_cdc"
password = "Bai_yun123"
# 监控的数据库名,需要与 base-url 中的库名一致
database-names = ["AMDBdatabase"]
# 表名格式为:数据库名.schema名.表名
table-names = ["AMDBdatabase.dbo.tab2"]
# 启动模式:initial 表示先全量快照,再持续增量
startup.mode = "initial"
}
}
sink {
Jdbc {
driver = "oracle.jdbc.OracleDriver"
# 请替换为你的 Oracle 实际地址、端口和服务名
url = "jdbc:oracle:thin:@//192.168.56.123:1521/orcl"
username = "amdb"
password = "amdb"
# 使用 database + table 让连接器自动生成写入 SQL
generate_sink_sql = true
database = "amdb"
table = "TAB2"
# 指定主键,CDC 的更新/删除操作依赖它
primary_keys = ["id"]
#表不存在时自动创建表结构
schema_save_mode = "CREATE_SCHEMA_WHEN_NOT_EXIST"
data_save_mode = "APPEND_DATA"
# 写入批次与重试参数(按需调整)
batch_size = 1000
max_retries = 3
}
}
启动同步进程
--cluster方式启动任务
nohup /seatunnel_3.0/apache-seatunnel-3.0.0/bin/seatunnel.sh \
--config /seatunnel_3.0/apache-seatunnel-3.0.0/config/demo_mssql_to_oracle.conf \
-m cluster \
-cn seatunnel \
-n sqlserver_to_oracle \
> /seatunnel_3.0/apache-seatunnel-3.0.0/logs/demo_mssql_to_oracle.out 2>&1 &
[root@db1 bin]# nohup /seatunnel_3.0/apache-seatunnel-3.0.0/bin/seatunnel.sh --config /seatunnel_3.0/apache-seatunnel-3.0.0/config/demo_mssql_to_oracle.conf -m cluster -cn seatunnel -n sqlserver_to_oracle > /seatunnel_3.0/apache-seatunnel-3.0.0/logs/demo_mssql_to_oracle.out 2>&1 &
[2] 12432
[root@db1 bin]#
查看任务
/seatunnel_3.0/apache-seatunnel-3.0.0/bin/seatunnel.sh -l
[root@db1 bin]# /seatunnel_3.0/apache-seatunnel-3.0.0/bin/seatunnel.sh -l
2026-10-19 06:35:22,461 INFO [c.h.i.c.AbstractConfigLocator ] [main] - Loading configuration '/seatunnel_3.0/apache-seatunnel-3.0.0/config/seatunnel.yaml' from System property 'seatunnel.config'
2026-10-19 06:35:22,463 INFO [c.h.i.c.AbstractConfigLocator ] [main] - Using configuration file at /seatunnel_3.0/apache-seatunnel-3.0.0/config/seatunnel.yaml
2026-10-19 06:35:22,465 INFO [o.a.s.e.c.c.SeaTunnelConfig ] [main] - seatunnel.home is /seatunnel_3.0/apache-seatunnel-3.0.0/bin
2026-10-19 06:35:22,547 INFO [amlSeaTunnelDomConfigProcessor] [main] - Dynamic slot is enabled, the schedule strategy is set to REJECT
2026-10-19 06:35:22,547 INFO [c.h.i.c.AbstractConfigLocator ] [main] - Loading configuration '/seatunnel_3.0/apache-seatunnel-3.0.0/config/hazelcast.yaml' from System property 'hazelcast.config'
2026-10-19 06:35:22,547 INFO [c.h.i.c.AbstractConfigLocator ] [main] - Using configuration file at /seatunnel_3.0/apache-seatunnel-3.0.0/config/hazelcast.yaml
2026-10-19 06:35:22,846 INFO [c.h.i.c.AbstractConfigLocator ] [main] - Loading configuration '/seatunnel_3.0/apache-seatunnel-3.0.0/config/hazelcast-client.yaml' from System property 'hazelcast.client.config'
2026-10-19 06:35:22,847 INFO [c.h.i.c.AbstractConfigLocator ] [main] - Using configuration file at /seatunnel_3.0/apache-seatunnel-3.0.0/config/hazelcast-client.yaml
2026-10-19 06:35:23,083 INFO [.c.i.s.ClientInvocationService] [main] - hz.client_1 [seatunnel] [5.1] Running with 2 response threads, dynamic=true
2026-10-19 06:35:23,129 INFO [c.h.c.LifecycleService ] [main] - hz.client_1 [seatunnel] [5.1] HazelcastClient 5.1 (20220228 - 21f20e7) is STARTING
2026-10-19 06:35:23,130 INFO [c.h.c.LifecycleService ] [main] - hz.client_1 [seatunnel] [5.1] HazelcastClient 5.1 (20220228 - 21f20e7) is STARTED
2026-10-19 06:35:23,155 INFO [.c.i.c.ClientConnectionManager] [main] - hz.client_1 [seatunnel] [5.1] Trying to connect to cluster: seatunnel
2026-10-19 06:35:23,160 INFO [.c.i.c.ClientConnectionManager] [main] - hz.client_1 [seatunnel] [5.1] Trying to connect to [localhost]:5801
2026-10-19 06:35:23,191 INFO [c.h.c.LifecycleService ] [main] - hz.client_1 [seatunnel] [5.1] HazelcastClient 5.1 (20220228 - 21f20e7) is CLIENT_CONNECTED
2026-10-19 06:35:23,191 INFO [.c.i.c.ClientConnectionManager] [main] - hz.client_1 [seatunnel] [5.1] Authenticated with server [localhost]:5801:4c285204-6317-43f0-8aa4-cfea6cff782b, server version: 5.1, local address: /127.0.0.1:15875
2026-10-19 06:35:23,192 INFO [c.h.i.d.Diagnostics ] [main] - hz.client_1 [seatunnel] [5.1] Diagnostics disabled. To enable add -Dhazelcast.diagnostics.enabled=true to the JVM arguments.
2026-10-19 06:35:23,204 INFO [c.h.c.i.s.ClientClusterService] [hz.client_1.event-3] - hz.client_1 [seatunnel] [5.1]
Members [1] {
Member [localhost]:5801 - 4c285204-6317-43f0-8aa4-cfea6cff782b [master node]
}
2026-10-19 06:35:23,240 INFO [.c.i.s.ClientStatisticsService] [main] - Client statistics is enabled with period 5 seconds.
Job ID Job Name Job Status Submit Time Start Time Finished Time
------------------- ------------- ---------- ----------------------- ----------------------- -----------------------
1164512069689540609 SeaTunnel_Job RUNNING 2026-10-19 06:35:13.747 2026-10-19 06:35:14.018
2026-10-19 06:35:23,535 INFO [c.h.c.LifecycleService ] [main] - hz.client_1 [seatunnel] [5.1] HazelcastClient 5.1 (20220228 - 21f20e7) is SHUTTING_DOWN
2026-10-19 06:35:23,539 INFO [.c.i.c.ClientConnectionManager] [main] - hz.client_1 [seatunnel] [5.1] Removed connection to endpoint: [localhost]:5801:4c285204-6317-43f0-8aa4-cfea6cff782b, connection: ClientConnection{alive=false, connectionId=1, channel=NioChannel{/127.0.0.1:15875->localhost/127.0.0.1:5801}, remoteAddress=[localhost]:5801, lastReadTime=2026-10-19 06:35:23.423, lastWriteTime=2026-10-19 06:35:23.364, closedTime=2026-10-19 06:35:23.536, connected server version=5.1}
2026-10-19 06:35:23,539 INFO [c.h.c.LifecycleService ] [main] - hz.client_1 [seatunnel] [5.1] HazelcastClient 5.1 (20220228 - 21f20e7) is CLIENT_DISCONNECTED
2026-10-19 06:35:23,545 INFO [c.h.c.LifecycleService ] [main] - hz.client_1 [seatunnel] [5.1] HazelcastClient 5.1 (20220228 - 21f20e7) is SHUTDOWN
2026-10-19 06:35:23,547 INFO [.s.a.m.MetadataProviderManager] [main] - MetadataProvider closed
2026-10-19 06:35:23,547 INFO [s.c.s.s.c.ClientExecuteCommand] [main] - Closed SeaTunnel client......
[root@db1 bin]#
[root@db1 bin]#
取消任务
/seatunnel_3.0/apache-seatunnel-3.0.0/bin/seatunnel.sh \
-can 1164512069689540609 \
-cn seatunnel
暂停一个任务
/seatunnel_3.0/apache-seatunnel-3.0.0/bin/seatunnel.sh -s 1164512069689540609
恢复任务
/seatunnel_3.0/apache-seatunnel-3.0.0/bin/seatunnel.sh \
-c /seatunnel_3.0/apache-seatunnel-3.0.0/config/demo_2tables_mysql.conf \
-r 1164512069689540609 \
-m cluster
-cn seatunnel \
-n sqlserver_to_oracle \
> /seatunnel_3.0/apache-seatunnel-3.0.0/logs/demo_mssql_to_oracle.out 2>&1 &
DML测试
源端插入数据

目标端查看数据没有正常同步。经过AI分析,在源端:强制刷新并验证 后数据同步到目标库
--强制扫描
EXEC sys.sp_cdc_scan @maxtrans = 500, @maxscans = 10, @continuous = 1;
--在 SQL Server 中执行以下命令,查看捕获作业的状态:
EXEC sys.sp_cdc_help_jobs;
执行 EXEC sys.sp_cdc_help_jobs; 却返回了空结果集。

这说明 SQL Server 的 CDC 机制存在一个很关键的配置漏洞:数据库和表的 CDC 虽然已经启用,但底层的 CDC 捕获作业(Capture Job)根本没有运行,或者不存在。
为什么这是致命问题?
SQL Server 的 CDC 捕获机制依赖 SQL Server Agent 运行两个后台作业(cdc.你的数据库名_capture 和 cdc.你的数据库名_cleanup)。如果没有这个 capture 作业,事务日志中发生的变更就不会被写入 cdc.dbo_tab2_CT 表。SeaTunnel 读取不到 _CT 表的新记录,自然也就无法同步到 Oracle。这也就解释了为什么之前的截图里 cdc.dbo_tab2_CT 的最新记录时间停留在几个小时前,而你刚才插入的数据完全没有出现在里面。
系统通常会自动创建:按照 SQL Server 的默认机制,在数据库中为第一张表启用 CDC 时,系统会自动创建 cleanup 作业和 capture 作业。只有在作业被显式删除后,才需要用 sp_cdc_add_job 手动重建。
cleanup 不影响数据同步:cleanup 作业的唯一作用是根据保留策略(默认 72 小时)定期删除 _CT 变更表中的过期历史记录。它既不扫描事务日志,也不往 _CT 表里写新数据。SeaTunnel 读取数据靠的是 capture 作业,而不是 cleanup 作业
启用后系统自动生成内容
启用表 CDC 后 SQL Server 会自动生成:
CDC 捕获作业:cdc._capture
CDC 清理作业:cdc._cleanup
更改表:如 cdc.dbo_YourTable_CT
修复步骤
- 手动添加 CDC 捕获作业
既然作业不存在,可以直接在 SQL Server 中执行命令来创建它。请在你的 AMDBdatabase 库上下文中执行以下语句:
USE AMDBdatabase;
GO
EXEC sys.sp_cdc_add_job @job_type = N'capture';
GO


再次运行EXEC sys.sp_cdc_help_jobs;,可以查询到记录了。

但是插入数据仍然没有自动同步到目标端。
强制重启 Capture 作业
USE AMDBdatabase;
GO
EXEC sys.sp_cdc_stop_job @job_type = N'capture';
EXEC sys.sp_cdc_start_job @job_type = N'capture';
执行完这两句后,绝对不要再去手动运行 sp_cdc_scan。
再次插入数据,可以正常自动同步了。

目标端

源端更新测试

目标端查询

源端删除测试

目标端查询

至此数据验证同步正常。