etcd 版本维护指南:CHANGELOG 规范、生产版本推荐与 v3.5 数据损坏事件的技术复盘
etcd 仓库中的 CHANGELOG/README.md 看似简短,却集中定义了三件与生产运维直接相关的事:哪些 etcd 版本可以安全用于生产、v3.5 早期版本数据损坏问题的官方处置口径、以及项目撰写变更历史(changelog)的书写规则。本文以该文档为主线,结合仓库内的 changelog 文件、版本定义源码与损坏检测实现,帮你建立一套“选对版本、读懂变更、规避已知风险”的完整方法。
CHANGELOG 目录的组织方式:按 minor 版本归档
etcd 将每个 minor 版本族的变更历史单独归档在一个 Markdown 文件中。从 CHANGELOG/ 目录可以看到,仓库维护了从 v2.3 一直到 v4.0 的完整序列:
- CHANGELOG/CHANGELOG-2.3.md
- CHANGELOG/CHANGELOG-3.0.md
- CHANGELOG/CHANGELOG-3.1.md
- CHANGELOG/CHANGELOG-3.2.md
- CHANGELOG/CHANGELOG-3.3.md
- CHANGELOG/CHANGELOG-3.4.md
- CHANGELOG/CHANGELOG-3.5.md
- CHANGELOG/CHANGELOG-3.6.md
- CHANGELOG/CHANGELOG-3.7.md
- CHANGELOG/CHANGELOG-3.8.md
- CHANGELOG/CHANGELOG-4.0.md
这种“一个 minor 版本一个文件”的约定与下面的书写规则直接呼应:因为 patch 版本的 changelog 只记录相对上一个 patch 的增量,所以单个文件会随时间不断追加新条目。以 CHANGELOG/CHANGELOG-3.5.md 为例,文件开头就声明了“上一份变更历史请查看 CHANGELOG-3.4”,随后按 ## v3.5.34 (TBC)、## v3.5.33 (2026-07-23) 这样的版本小节倒序排列;每个版本小节内部再按 etcd server、etcdctl、Package clientv3、Dependencies 等组件分类,逐条列出修复项及其来源 PR。这种结构让“某个修复从哪个版本开始可用”这类问题可以直接在对应文件中线性检索到答案。
生产环境版本推荐:v3.4.22+ 与 v3.5.6+
CHANGELOG/README.md 给出的第一条硬性建议是:
生产环境推荐的最低 etcd 版本为 v3.4.22+ 和 v3.5.6+,更多细节参考官方的版本策略(versioning policy)。
这条推荐并非随意划定,它对应的是“每个 minor 版本维护到一定成熟度后才对外背书”的维护策略:v3.4 系列需要至少到 .22、v3.5 系列至少到 .6,之前的 patch 版本可能存在尚未回填的稳定性问题。对于运维人员,实际操作就是两条:
- 部署 v3.4 系时,镜像/二进制版本不得低于 v3.4.22;
- 部署 v3.5 系时,版本不得低于 v3.5.6。
仓库源码可以佐证“版本”在 etcd 中是一组被严格管理的数据。api/version/version.go 集中定义了版本常量,例如 MinClusterVersion(当前分支为 3.0.0,表示本二进制可兼容的最低集群版本)、当前开发版本号(本仓库为 3.8.0-alpha.0),以及按升序排列的 AllVersions(覆盖 3.0 至 4.0 的 semver 常量表)。集群侧则由 server/etcdserver/version/monitor.go 中的 Monitor 负责根据各成员上报的 server 版本、集群版本与降级状态来计算并推进 cluster version / storage version。也就是说,README 中的版本推荐对应到代码层面,就是一套“成员版本 → 集群版本 → 存储版本”的联动机制,选版不仅决定你跑的是哪个二进制,也决定了集群兼容性的边界。
v3.5 数据损坏问题:官方警告与升级要求
README 中专门用一个小节标注了 v3.5 的数据损坏问题,原文要点如下:
- 在高负载下运行 v3.5.2、v3.5.1、v3.5.0,可能出现数据损坏;
- 具体表现为:如果 etcd 进程被 kill,部分已提交的事务可能没有在所有成员上体现(committed transactions are not reflected on all the members);
- 官方建议升级到 v3.5.4+;
- 如果已经发生数据损坏,官方文档提供了专门的数据损坏修复指南(data corruption 文档)供排查与恢复。
根因:consistent index 丢失原子性
仓库内的 Documentation/postmortems/v3.5-data-inconsistency.md 对这一问题有完整的公开复盘,可以作为 README 警告的技术底注:
- 状态的双份存储:etcd v3 的状态在磁盘上以 WAL(写前日志)和数据库快照两种形式保存。数据库通过 consistent index(CI,一致索引)元数据记录“自己重放到 WAL 的哪一条”。
- 原子性要求:数据库状态与 CI 的更新必须是原子提交。若只更新 CI 而未落盘对应变更,重启后该批 WAL 条目会被跳过;若只落了变更而未更新 CI,则会被执行两次。
- 缺陷引入:v3.5.0 为简化 CI 管理引入了 backend hooks 机制(对应 PR #12855),在提交事务时自动把内存中的 CI 值写入数据库。问题在于内存中的 CI 是共享的:周期性提交(periodic commit)可能在 apply 流程“设置了新 CI、但尚未落盘变更”的窗口内先把 CI 存盘,从而形成一个“CI 前进了、变更却没应用”的空洞。
- 触发条件:恰好在这个窗口内进程崩溃。复盘记录了触发场景——etcd 在高请求压力、高内存压力(频繁 OOM)下被 SIGKILL 直接杀死,恢复时 etcd 会认为失败 apply 的变更“已经执行过”而跳过,导致该成员数据库缺数据。
该 postmortem 的时间线还记录了几个关键节点:问题代码于 2021-05 合入,随 v3.5.0(2021-06-16)发布,2021-12 起陆续有损坏报告,2022-03-25 由 maintainer 确认,修复版本(postmortem 记为 v3.5.3,发布时间 2022-04-24)随后发布——这也解释了 README 中“推荐升级到 v3.5.4+”的保守口径:它要求你跳过整个有问题的早期窗口,并且留出至少一个 patch 的余量。
损坏如何被检测:HashKV 与 corrupt check 实现
postmortem 指出:单成员集群中该问题完全不可检测(当时没有校验数据库与 WAL 是否一致的工具);多成员集群中,受损成员会对同一个 revision 算出不同的数据库哈希,可通过 HashKV gRPC 调用暴露差异。etcd 为此提供了两套检测入口:
--experimental-initial-corrupt-check:启动时对初始哈希与对端比对;--experimental-corrupt-check-time:周期性重复该检查。
其实现位于 server/etcdserver/corrupt.go:corruptionChecker.InitialCheck() 在对外提供 peer/client 流量前执行,先取本地 HashByRev(0) 的哈希与 revision,再通过 PeerHashByRev(rev) 收集对端在同一 revision 上的哈希逐一比较;PeriodicCheck() 则周期性执行同样的比对逻辑。检查周期由 server/embed/config.go 中的 CorruptCheckTime 字段(对应命令行标志 corrupt-check-time)控制。
postmortem 同时诚实地列出了检测机制的缺陷:HashKV 依赖所有成员都能提供目标 revision 的哈希,在成员很慢、或损坏已导致 revision 分叉时会失效,因此该检查只在“崩溃重启后刚启动”阶段最可靠。针对这类教训,CHANGELOG/CHANGELOG-4.0.md 记录了 v4.0 的规划方向:--experimental-initial-corrupt-check 与 --experimental-corrupt-check-time 被去实验化,改为 --initial-corrupt-check(默认 true)与 --corrupt-check-time(默认 12h),把损坏检测从“可选实验特性”变成默认开启的稳定性基线。如果你在规划 v4.0 升级,这类默认行为变化属于必读项。
Changelog 书写规则:两条增量原则
README 的第二部分是维护者撰写变更历史时必须遵守的规范,共两条,核心思想是“每条 changelog 只描述相对基线的新增内容,不做全量复述”:
- patch 规则:每个 patch 发布只包含相对上一个 patch 发布的变更。例如 v3.5.5 的 changelog 只应包含 v3.4.x 序列中 v3.5.4 之后新增的条目。
- 首个 minor/major 版本规则:每个 minor 或 major 版本的首个发布(如 3.4.0、3.5.0、3.6.0、4.0.0)只包含相对上一个 minor/major 首个发布的新增内容。例如 v3.5.0 只记录相对 v3.4.0 的新内容,v3.6.0 只记录相对 v3.5.0 的新内容。
这两条规则配合“一个 minor 一个 changelog 文件”的目录约定,形成了可追溯的增量链:读 v3.5.33 的小节只看到该 patch 的增量,而想了解 v3.5 相对 v3.4 的全部变化,就去看 v3.5.0 小节——它按规则只包含相对 v3.4.0 的增量,天然避免了跨版本条目重复。
从仓库实际内容看,这一规则执行得相当严格:CHANGELOG/CHANGELOG-3.5.md 中每个 patch 小节都以 ## vX.Y.Z (日期) 开头(未定日期则标注 TBC),条目按组件分类;CHANGELOG/CHANGELOG-4.0.md 作为 major 版本首发的 changelog,则集中列出 Breaking Changes(如移除 v2 proxy、--proxy* 标志弃用、v2 存储后端弃用、损坏检查标志转正等),符合“首个 major 版本 changelog 描述相对上一个 major 的全部新内容”的约定。
实操建议:把 README 的版本建议落到运维流程
结合上述内容,可以归纳出一条可执行的检查清单:
- 选型:对照 CHANGELOG/README.md 的最低推荐线(v3.4.22+ / v3.5.6+)选择二进制版本,不要停留在推荐线之下的早期 patch;
- 升级确认:若集群仍运行 v3.5.0–v3.5.2,参照 v3.5 数据损坏警告立即升级到 v3.5.4+,并参考 Documentation/postmortems/v3.5-data-inconsistency.md 了解该问题的触发条件与检测手段;
- 开启检测:确认部署配置中启用了损坏检查(
--corrupt-check-time/ initial corrupt check,见 server/embed/config.go),v4.0 环境下该检查将成为默认行为; - 跟踪变更:升级前通读目标版本在对应 CHANGELOG/ 文件中的增量小节,重点关注
etcd server分类下的行为变化与Dependencies分类下的依赖/工具链变更。
需要说明的是,以上版本推荐与损坏警告均以当前仓库 CHANGELOG/README.md 的原文为准;随着仓库演进(当前开发线已推进到 v3.8 alpha,v4.0 changelog 已在编写中),具体推荐版本与标志名称可能发生变化,部署前应以对应维护分支的最新 CHANGELOG 内容为准。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00