ScyllaDB 实验性 CDC 升级指南:从 4.2 平滑迁移到正式版 Change Data Capture ScyllaDB 实验性 CDC 升级指南从 4.2 平滑迁移到正式版 Change Data Capture【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb导读本文面向在 ScyllaDB 4.2 及更早版本中使用**实验性 CDCChange Data Capture**功能、并计划升级到 4.3 的用户。文章完整梳理升级必须执行的额外步骤——禁用 CDC、升级、重新启用、运行nodetool checkAndRepairCdcStreams——并结合仓库源码与配套文档解释这些步骤背后的 CDC 流世代stream generation机制帮助你理解报错原因、避免升级后 CDC 数据丢失或不可用。一、为什么 4.2 升级到 4.3 需要特殊处理CDC 在 ScyllaDB 4.2 及更早版本中作为实验性功能存在4.3 起正式化。两个版本之间CDC 的内部机制发生了根本性变化正式版引入了CDC 流世代CDC stream generations概念——一组随时间更替的流 IDstream ID集合用于决定写入日志表时使用哪个流。如果直接在启用实验性 CDC 的情况下升级集群节点间关于当前应该使用哪一代 CDC 流的信息可能不一致进而出现日志中反复报错、写入失败等情况详见下文常见错误日志解读。因此从实验性 CDC 升级到正式版时必须先禁用 CDC、完成升级、再重新启用并运行修复命令让流信息与集群拓扑对齐。二、升级前停止写入并禁用 CDC根据 docs/kb/cdc-experimental-upgrade.rst 的说明升级前需要按顺序执行以下操作停止对该表的所有写入。前提是你在某个表上启用了 CDC即建表时使用了with cdc { ... }选项。禁用 CDC执行alter table ks.t with cdc {enabled: false};⚠️ 重要警告该操作会删除与该表关联的 CDC 日志表——在本例中即ks.t_scylla_cdc_log。日志表中的历史变更数据将随之清除请务必在操作前评估数据保留需求。官方文档强调上述命令即使在已经完成升级的集群上执行也有效但最佳实践是在升级前对所有启用 CDC 的表统一禁用以避免升级窗口期内出现流信息不一致的报错窗口。三、完成升级并重新启用 CDC禁用 CDC 并完成版本升级后即可安全地重新启用 CDCalter table ks.t with cdc {enabled: true};重新启用后ScyllaDB 会为该表重新创建 CDC 日志表并基于当前集群拓扑生成新的 CDC 流。四、运行 nodetool checkAndRepairCdcStreams 修复流信息升级流程的最后一步也是关键一步是运行nodetool checkAndRepairCdcStreams该命令的作用是检查 CDC 流是否反映当前集群拓扑如果未反映则重新生成它们见 checkandrepaircdcstreams.rst。4.1 使用注意事项官方命令文档给出了明确警告Do not use this operation while performing other administrative tasks, such as bootstrapping or decommissioning a node.即禁止在节点 bootstrap加入集群或 decommission退出集群等管理操作进行期间执行本命令否则可能干扰拓扑变更流程。4.2 命令的底层实现链路从源码可以完整追溯该命令的执行路径nodetool 命令注册在 tools/scylla-nodetool.cc#L4062-L4076 中checkAndRepairCdcStreams被注册为 nodetool 操作描述与文档一致并附带同样的不要与其他管理任务并发执行警告。REST API 入口nodetool 通过 HTTP POST 调用/storage_service/cdc_streams_check_and_repair接口接口定义见 api/api-doc/storage_service.json#L661处理器见 api/storage_service.cc#L768。核心实现真正的工作在 service/storage_service.cc#L2949 的storage_service::check_and_repair_cdc_streams()中完成最终走raft_check_and_repair_cdc_streams()service/storage_service.cc#L3569通过 Raft 拓扑变更机制刷新拓扑并重新生成 CDC 世代。自动化测试佐证测试 test/nodetool/test_check_and_repair_cdc_streams.py#L10-L13 验证了 nodetool 命令会正确触发POST /storage_service/cdc_streams_check_and_repair请求。4.3 运行后的预期效果运行该命令后集群会为当前拓扑生成新的 CDC 世代。此前周期性出现的 CDC 流检索错误应当消失如果错误仍然出现官方文档建议提交 issue报告。五、常见错误日志解读升级过程中或在尚未运行修复命令之前ScyllaDB 日志中可能周期性地出现如下错误cdc - Could not retrieve CDC streams with timestamp {...} upon gossip event. Reason: std::runtime_error (Could not find CDC generation with timestamp ... in distributed system tables (current time: ...), even though some node gossiped about it.). Action: not retrying.这条日志的含义是某个节点通过 gossip 收到了关于某个 CDC 世代的时间戳但在分布式系统表中找不到对应的世代数据世代可能已被垃圾回收或该节点尚未得知新世代因此无法为写入选择正确的流。从源码层面可以进一步印证这类错误的产生条件。cdc/metadata.cc#L131-L135 中当节点找不到适用于写入时间戳的 CDC 世代时会抛出cdc::metadata::get_stream: could not find any CDC stream for timestamp {}. Are we in the middle of a cluster upgrade?该错误信息明确提示是否正处于集群升级过程中——这正是本文场景的典型表现。运行checkAndRepairCdcStreams后节点重新生成并与拓扑对齐的世代此类错误即不再出现。六、深入理解CDC 流世代为何需要修复要真正理解修复命令的价值需要明白 CDC 流世代的工作方式详见 cdc-stream-changes.rst。6.1 什么是 CDC 流世代在基于 vnode 的 keyspace 中一个CDC 世代generation由三部分组成时间戳描述该世代开始运作的时间点一组流 IDtoken 集合到流 ID 集合的映射这是写入时选择流 ID 的依据是整个集群的全局属性与具体表无关。世代遵循一个重要不变式给定基表写入的分区键pk其日志表条目的分区键s_id的 token 与pk的 token 位于同一个 vnode。当新节点加入集群导致 vnode 被拆分时原流 ID 通常不再满足该不变式因此必须更换流 ID——这就是世代更替的根本原因也是升级后需要手动修复的原因。6.2 世代存储在何处世代时间戳存储在system_distributed.cdc_generation_timestamps表单分区表所有时间戳位于key timestamps分区世代包含的流 ID 存储在system_distributed.cdc_streams_descriptions_v2表。可通过 CQL 查询当前已知的世代SELECT time FROM system_distributed.cdc_generation_timestamps WHERE key timestamps;6.3 需要注意的时间语义首个世代的开始时间戳由第一个启动的节点生成取节点当前时钟向前平移约一分钟。这意味着新集群启动后无法立即向启用 CDC 的表写入——因为此刻还没有任何世代开始运作。若强行写入会得到ServerError: cdc::metadata::get_stream: could not find any CDC stream (current time: ...). Are we in the middle of a cluster upgrade?看到该报错不一定代表故障等待约一分钟让首个世代开始运作即可。同理从旧版本不支持 CDC滚动升级时必须在所有节点完成升级后再开始 CDC 写入——因为需要某个节点负责创建首个世代并通知其他节点。七、升级 Checklist 总结阶段操作命令/要点升级前停止写入停止对启用 CDC 表的写入流量升级前禁用 CDCalter table ks.t with cdc {enabled: false};注意会删除对应日志表ks.t_scylla_cdc_log升级中执行版本升级滚动升级集群至 4.3升级后重新启用 CDCalter table ks.t with cdc {enabled: true};升级后修复流信息nodetool checkAndRepairCdcStreams勿与其他拓扑管理操作并发验证观察日志确认Could not retrieve CDC streams...类错误不再出现延伸阅读CDC 流变化详解世代机制、vnode 与 tablets 场景nodetool checkAndRepairCdcStreams 命令文档CDC 模块源码目录checkAndRepairCdcStreams 命令注册源码CDC 世代查询与报错逻辑源码REST API 处理器源码【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考