摘要

  • draft-ietf-netmod-yang-schema-comparison-09 同时比较解析模式与编译后的有效数据树,再把每项变化归为编辑性、向后兼容或非向后兼容。
  • 这些标签适合辅助修订审查、语义版本选择和数据转换规划;它们没有证明编译语境一致、迁移无损、实现互通、NACM 稳定、滚动顺序安全或运行状态已经收敛。

变更单最容易造成的误会,不是数据错误,而是结论提前。几十个 YANG 文件经过工具处理后只剩一页差异,“未发现非兼容变更”随后在审批单里变成“可以上线”,上线后又被仪表盘翻译成“升级成功”。真正关键的转换发生在措辞里:模式层面的判断被抬升成了系统层面的事实。

第 09 版草案为第一层判断提供了严谨基础。它于 2026 年 7 月 3 日发布,IETF Datatracker 目前将其列为 NETMOD 工作组的活跃 Internet-Draft,而非 RFC;当前页面的验证汇总是零错误、零警告。这说明文稿及相关验证工具的状态,不说明任何厂商已经采用算法,也不说明两个实现会给出相同结果,更不能替代真实升级记录。

先固定究竟比较了什么

草案区分解析模式和编译模式。解析模式接近装载后的语句树,很多引用和变换仍保留在原始表达层。编译模式则把模型展开成有效数据树:导入模块和子模块进入语境,uses 与 typedef 得到解析,augment、deviation、refine 产生作用,启用的 if-feature 决定哪些分支真实存在。

两者不能相互取代。一个 typedef 的短小变化可能影响许多叶节点;另一个模块中的 augment 可能把新节点放进当前模型;设备偏差可以在不改目标模块文本的情况下撤销约束。只看源文件会漏掉有效树,只看有效树又可能遗漏作者、导入者和审查者需要看到的语句层变化。

所以第 09 版先输出编译后数据节点的变化,再比较其他解析语句,并跳过已报告的数据节点以免重复。其编译身份还包括新旧模块名和修订号、包含的子模块、启用的 feature,以及递归导入的模块。这不是辅助元数据,而是实验边界。

一份空差异只能证明这一组精确输入没有产生已定义的差异。设备若换了导入版本、启用另一项 feature、应用厂商 deviation,或选择不同子模块修订,旧结果不能仅凭模块名称被继承。升级证据的第一步,应当是给完整源集合做哈希,并保存编译身份。

三种标签回答的是模式问题

所有变化被归为编辑性(ED)、向后兼容(BC)或非向后兼容(NBC)。编辑性变化不得改变合法数据值空间,也不得让导入模块失效;BC 可以扩大合法空间,但不能破坏导入者;其他变化均为 NBC,包括缩小合法空间或可能使导入失效的修改。

这套规则能够发现肉眼容易轻视的差异。把 uint32 换成 uint64 看起来只是扩大数值范围,但 RFC 7951 的 JSON 表示会从数字变为字符串。数学集合更大,客户端的输入类型却变了,因此草案可以把它归为 NBC。

部分语句采用保守默认值:pattern、when、must 的变化默认为 NBC;description、reference、presence 默认为 ED;扩展实例默认为 BC。作者还可用会延续到后续修订的 ed-change-at、bc-change-at 或 nbc-change-at 语义版本标记覆盖默认分类。

覆盖机制的意义是把判断暴露出来,而不是把判断变成测量事实。审查记录应区分固定规则、默认规则和人工覆盖,并保存理由与批准者。语义版本因此可以成为可追责的发布声明,却不能成为升级结果的预言。

向后兼容不等于行为未变

新增一个可选 leaf 可以正确归为 BC,因为旧数据仍然有效。但服务器可能开始填充它,客户端可能序列化或记录它,策略引擎可能读取它,界面也可能改变表现。默认值变化即使不修改存储配置,也会改变有效行为;when 与 must 会改变验证路径;feature 与 deviation 会改变某台设备真正暴露的模型表面。

模式比较不执行 RPC,不拿全部现存配置做验证,不比较默认值展开后的 datastore,更不会观察客户端。RFC 8525 的 YANG Library 能标识服务器所声明的模块集、feature 和 deviation,但 content-id 只标识模式库内容,不证明执行代码忠实实现了它们。

授权又是另一条轴。RFC 8341 的 NACM 决定某个主体能读取或修改哪些节点。模式差异可以为零,而组成员、规则或 default-deny 行为已经改变;某项 NBC 变化也可能对一个特定角色完全不可达。生产结论必须测试有效 NACM 矩阵,不能从模式标签推断权限稳定。

数据转换需要损失账本

草案指出,比较输出可以帮助工具把旧修订下合法的实例数据转换为适合新修订的数据。“帮助”是准确的力度,因为转换器仍要做决定:删除废弃节点、映射枚举、补入默认值、规范化表示、拆分字段,或拒绝无法保留的内容。

RFC 9195 为实例数据内容身份和来源提供了可借鉴的记录方式。一份可靠的转换收据应把旧实例哈希、旧模式身份、转换器版本与规则集绑定起来,再逐项记录被删除、补全、规范化、合成和拒绝的节点。输出必须做哈希,并对目标编译模式验证,同时声明做过哪些往返或语义不变量测试。

通过目标模式验证,只能证明输出符合语法和约束,不证明含义无损。如果两个旧状态映射为同一个新状态,或者默认值掩盖了一个原本缺失的选择,迁移可能合法,却仍然有损。是否接受这种损失,应由数据所有者决定,而不是由差异工具代替。

后续关口必须由可执行证据通过

差异审查和转换之后,是实现测试。需要互通时,至少比较两个独立解析器或服务器;重放代表性配置与 RPC;核对错误标签、默认处理、规范编码和 feature 协商;按角色覆盖所有受影响的 NACM 路径。二进制、模块集、参数和测试向量都应被固定,使绿色结果能够复现。

然后要测试发布顺序。滚动升级会制造混合版本窗口:旧客户端连接新服务器,新客户端连接旧服务器,相邻组件对 feature 或 deviation 集合理解不同。差异单不会替团队决定谁先升级,也没有证明遥测不断流,或旧版本能够读取新版本写入的数据并完成回滚。

最后才是运行观察。RFC 8342 把 running、intended 和 operational datastore 分开,因为配置、应用后的意图与观察到的状态并不相同。模式差异无法证明 intended 已经收敛到 operational,也不能证明告警、性能和用户结果符合预期。

第 09 版真正强大的地方,是让模式审查形成可重现、可归责的收据。只有拒绝让它冒充后续证据,这张收据才不会在审批链里失去精度。

资料来源

主要资料:YANG Schema Comparison 第 09 版、IETF Datatracker 条目、YANG 1.1:RFC 7950、YANG Library:RFC 8525、NMDA:RFC 8342、NACM:RFC 8341、YANG Instance Data:RFC 9195、YANG Semantic Versioning 第 28 版、YANG Module Versioning 第 16 版。 修订时间线见 Datatracker 历史记录。