反馈已提交

网络繁忙

实时管道中SQL Server DDL操作说明

  • 文档创建者:Wendy123456
  • 历史版本:2
  • 最近更新:Wendy123456 于 2026-04-10
  • 1. 新增字段

    SQL Server 数据源作为管道任务来源端时,目前 DDL 同步功能 不支持自动同步源端新增字段,若需要使用 DDL 进行新增字段的处理,请参见本文提供的方案。

    1.1 方案一:在线方案

    注:此方案如果源表在不停写入数据,源表新增字段之后,没有立刻创建新的 CDC 实例,那么在源表新增字段之后到新的 CDC 实例创建前的这段时间中,源表发生的数据修改是不会写入到新的 CDC 实例中的。这可能会导致部分数据丢失新增字段的数据,如果要完全避免这种情况,请采用离线处理方案。

    1)源表执行 DDL,新增一个字段。

    1742176192494540.png

    2)给源表新建一个 Capture Instance

    使用命令:

    EXEC sys.sp_cdc_enable_table
         @source_schema = N'Schema',
         @source_name = N'Table',
         @role_name = NULL, -- 如果要限制读取角色,可能需要设置
         @capture_instance = N'Schema_Table_newname'; -- 给一个新的名字

    注:Table 是数据表的名称(没有 schema)。

    3)等待 FineDataLink 检测到新的 Capture Instance 创建后,自动切换到新的 Capture Instance

    即可看到目标表中已经同步新增的字段,如下图所示:

    3.png

    4)可以手动把旧的 Capture Instance 删除。

    检查 change_tables 中旧的 Capture Instance 名称:

    USE database;
    GO

    EXECUTE sys.sp_cdc_help_change_data_capture;
    GO

    然后禁用该 Capture Instance ,示例命令:

    -- Disable a Capture Instance for a table
        EXEC sys.sp_cdc_disable_table
        @source_schema = N'Schema',
        @source_name   = N'Table',
        @capture_instance = N'Schema_Table'

    注:Table 是数据表的名称(没有 schema );Schema_Table 为需要删除的旧 Capture Instance 。

    然后使用如下命令检查 change_tables 里是否有这条记录,若没有则表示已经被删除,若有的话需要手动使用 SQL 命令删除。

    USE database;
    GO

    EXECUTE sys.sp_cdc_help_change_data_capture;
    GO

    1.2 方案二:离线处理方案

    1)源表停止写入,等待 FineDataLink 同步完源表所有的数据。

    2)停止管道任务。

    3)源表执行 DDL,新增一个字段:

    1742176322517298.png

    4)给源表新建一个 Capture Instance

    使用命令:

    EXEC sys.sp_cdc_enable_table
         @source_schema = N'Schema',
         @source_name = N'Table',
         @role_name = NULL, -- 如果要限制读取角色,可能需要设置
         @capture_instance = N'Schema_Table_newname'; -- 给一个新的名字

    5)恢复源表写入。

    6)启动管道任务。

    7)等待 FineDataLink 检测到新的 Capture Instance 创建后,自动切换到新的 Capture Instance

    即可看到目标表中已经同步新增的字段,如下图所示:

    6.png

    8)可以手动删除旧的 Capture Instance。

    注:如果没有按照正确顺序操作,可能造成部分有新字段的数据流入了旧的 CDC 实例,那么这部分新字段的数据就丢失了。

    2. 修改字段类型

    2.1 最佳实践建议

    SQL Server CDC 表在源表进行 DDL 变更时可能会因数据类型转换失败而停止工作。由于一个数据库只有一个 capture 作业,一个表的问题会影响所有表的 CDC 功能,会导致实时管道任务因 CDC 表数据停止更新而无法正常同步数据。

    针对上述问题,有以下建议:

    建议类型说明
    预防措施
    • 修改表结构前先关闭该表的 CDC,修改完成后再重新开启

    • 在进行类型变更前,确保 CDC 表中的数据都能兼容新类型

    • 不要放置 CDC 配置在临时目录(如/tmp)下,以避免系统重启后数据丢失

    监控措施
    • 定期检查 sys.dm_cdc_errors 表中的错误,特别是错误码 241

    • 设置自动告警机制,在 CDC 任务失败时及时通知

    • 通过企业微信群或邮箱发送告警信息

    2.2 CDC无效后的解决方案

    2.2.1 问题描述

    • SQL Server 的 CDC capture 任务突然停止运行。

    • 日志中显示错误:"数据类型值的转换失败"。

    • 管道任务因 CDC 表数据停止更新而无法正常同步数据。

    2.2.2 CDC工作原理简介

    SQL Server CDC(变更数据捕获)的工作原理如下:

    • 当对库和表开启 CDC 后,SQL Server 会创建一张与原表结构几乎相同的CDC表(以_CT结尾)。

    • SQL Server 会启动一个 capture 作业,定期解析数据库事务日志。

    • Capture 作业将事务日志中的变动数据(插入、更新、删除)记录到对应的 CDC 表中。

    • CDC 表默认保留 3 天的变动记录,超过时限的数据会被自动清理。

    • FDL 管道任务定时读取 CDC 表中的变动记录,将其同步到目标端。

    重要:一个数据库只有一个 capture 作业,如果一个表出现问题,所有表的 CDC 都会停止工作。

    2.2.3 直观模拟问题场景

    • 源表中有 varchar 类型字段 col1。

    • 对该表启用 CDC 后,在源表中插入一条带有"aa"字符串的数据,然后又删除了这条数据。

    • 此时源表中已经没有这条数据,但 CDC 表中会有两条记录(一条插入记录,一条删除记录)。

    • 源表字段改为 date 类型,操作成功(因为源表中没有不兼容的数据)。

    • SQL Server 自动尝试在 CDC 表应用此变更,但因"aa"无法转为日期,变更失败。

    • Capture 任务终止,所有表的 CDC 都停止工作。

    棘手的是:SQL Server 的错误信息不会明确指出是哪个表哪个字段导致了问题。

    2.2.5 解决方案

    提供两种解决方案,方案对比参考下表:

    方案一「推荐该方案」
    方案二
    优点:
    • 保留CDC配置和断点信息

    • Capture任务会继续从断点处解析事务日志

    • FDL管道任务无需重新配置,可继续正常同步

    • 不会丢失中间数据

    优点:

    • 彻底解决问题,相当于全新安装

    缺点:

    • 会丢失断点信息,从"此刻"开始解析日志

    • 中间的变动数据会丢失

    • FDL任务需要全部重新配置和重新同步

    方案一:Truncate CDC表+重启capture「推荐」

    1)以下是一个用于清空(Truncate)所有CDC表的存储过程,可以用来快速解决CDC因数据类型不匹配而停止的问题:

    CREATE PROCEDURE dbo.TruncateAllCDCTables
    AS
    BEGIN
        SET NOCOUNT ON;
         
        DECLARE @sql NVARCHAR(MAX) = N'';
        DECLARE @crlf NCHAR(2) = NCHAR(13) + NCHAR(10);
         
        -- 生成truncate所有CDC表的SQL语句
        SELECT @sql = @sql + 'TRUNCATE TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id))
                            + '.' + QUOTENAME(name) + ';' + @crlf
        FROM sys.tables
        WHERE OBJECT_SCHEMA_NAME(object_id) = 'cdc'
          AND name LIKE '%_CT';
           
        -- 打印生成的SQL(可选,用于调试)
        -- PRINT @sql;
         
        -- 停止CDC capture进程
        EXEC sys.sp_cdc_stop_job;
         
        -- 执行truncate操作
        EXEC sp_executesql @sql;
         
        -- 启动CDC capture进程
        EXEC sys.sp_cdc_start_job;
         
        PRINT '所有CDC表已清空,CDC capture进程已重启。';
    END

    2)执行存储过程

    -- 执行存储过程,清空所有CDC表并重启capture进程
    EXEC dbo.TruncateAllCDCTables;

    方案二:重建CDC

    • 关闭所有表的 CDC。

    • 重新开启所有表的 CDC。

    • 重新配置所有 FDL 管道任务


    附件列表


    主题: 数据管道
    • 有帮助
    • 没帮助
    • 只是浏览
    中文(简体)

    鼠标选中内容,快速反馈问题

    鼠标选中存在疑惑的内容,即可快速反馈问题,我们将会跟进处理。

    不再提示

    10s后关闭



    AI

    联系我们
    在线支持
    获取专业技术支持,快速帮助您解决问题
    工作日9:00-12:00,13:30-17:30在线
    页面反馈
    针对当前网页的建议、问题反馈
    售前咨询
    采购需求/获取报价/预约演示
    或拨打: 400-811-8890 转1
    qr
    热线电话
    咨询/故障救援热线:400-811-8890转2
    总裁办24H投诉:17312781526
    提交页面反馈
    仅适用于当前网页的意见收集,帆软产品问题请在 问答板块提问前往服务平台 获取技术支持