摘要
active、notInService、notReady是代理能够返回的现状;createAndGo、createAndWait、destroy则是管理器提交的动作,读取时永远不会作为行的状态出现。- 管理器负责提出索引和值,MIB 负责定义条件,代理负责判断转换能否成立。因此,一行可以先存在而未就绪,也可以已经就绪却仍未投入服务。
早期的“表”,并不是数据库承诺
在 MIB 中,对象标识符加上实例索引,很自然地形成表格外观。管理器可以逐列读写,工具也可以把结果画成一行。但 RFC 1212 特意称它们为“概念表”和“概念行”:列之间的关系是一种应用约定,并不是 SNMP 自带的关系数据库机制。
当时的 MIB 可以用一个整数状态表示删除,也可以允许 SetRequest 指向尚不存在的实例,由代理决定接受创建还是拒绝。DEFVAL 还能为未提交的列提供默认值。问题在于,每个 MIB 都要自行解释:什么时候算创建成功,缺少哪些字段仍可保留,设备什么时候可以真正使用这行配置。
如果只有设备自己生成只读数据,含糊尚且可控。一旦多个管理站都能创建动态配置,索引归谁、半成品是否可见、第二个管理器能否接手,就变成了协议协作问题。
RMON 先把“正在创建”写进状态
RFC 1271 的远程网络监测 MIB 提供了直接前身。EntryStatus 包含 createRequest、underCreation、valid 和 invalid。管理器先取得某个索引,逐步补全,再把条目设为有效;多个管理器争用同一索引时,只有第一个成功创建者能够取得它,后来的请求会报错。
RMON 还定义了 OwnerString,帮助协作中的管理站识别条目创建者、避免无意冲突。不过 RFC 明确说明,它不是访问控制。一个不合作的管理器仍可能修改或删除别人的条目。署名提供来源线索,却没有产生排他权。
这个限制很重要。状态机可以把意图和现状说清楚,但它不能替代认证、授权和组织纪律。
六个值,其实分成两类
RFC 1443 在 SNMPv2 中标准化了 RowStatus;RFC 2579 保存了现行定义。它有六个数值,但不是六个性质相同的状态。
读取一行时,代理只会返回三种结果。active(1) 表示该行可供受管设备使用。notInService(2) 表示行已经存在而且暂不使用,代理也已有足够信息去尝试激活;但它不保证内部一致、资源充足或激活必然成功。notReady(3) 表示行虽存在,却仍缺少投入服务所必需的列实例。
另外三个是写入动作。createAndGo(4) 请求创建后立即激活;createAndWait(5) 请求先创建但不投入服务;destroy(6) 请求删除属于该概念行的全部实例。
GET 不会返回后三个值,管理器也不能把一行写成 notReady。notReady 是代理对缺失信息的判断。于是,同一列在写入方向承载请求,在读取方向返回事实,命令与证据没有被伪装成同一件事。
createAndGo 不是“先存个草稿”
一次性创建时,管理器选择尚未使用的实例标识,在同一个 SetRequest 中提交所需列和值为 createAndGo 的状态列。代理可以用实现默认值补充其余内容。
若信息足够,代理创建该行,随后可读状态直接是 active。若缺少必要信息,操作以 inconsistentValue 失败,而且不会创建概念行。管理器不能假定失败后留下了可继续编辑的半成品。它必须找出要求,重新发送完整请求,或者改用代理支持的分阶段创建。
这种严格性使“一次完成”有清楚含义:创建和激活共同成功,或者两者都不成立。
createAndWait 允许半成品存在,但不允许它假装在服务
分阶段模式的第一步是写入 createAndWait。如果代理接受,该行已经存在,却不会供设备使用。缺少必要列时,读取结果是 notReady;把缺失列补上后,代理可自动把状态推进到 notInService。此时信息足以尝试激活,但还没有服务事实。
管理器随后写入 active。代理可以接受,也可以因值、资源或设备当前状态不一致而返回 inconsistentValue。就绪只是申请激活的条件,不是激活结果。
而且,代理可以不支持 createAndWait,以 wrongValue 拒绝并要求一次性完整创建。它也可能拒绝把正在使用的行退出服务,或拒绝立即删除。通用状态机并没有夺走本地实现与具体 MIB 的边界。
未投入服务的行仍会占用资源。RFC 2579 要求代理发现长时间停留在 notReady 或 notInService 的行并予以清理。状态列的 DESCRIPTION 应说明“异常长”的期限;如果没有说明,RFC 建议约五分钟,以容纳人的思考时间。这是默认建议,不是对所有产品计时器的实测结论。
真正的细则仍写在 MIB 描述里
RowStatus 没有统一决定 active 状态下能否修改其他列。有些表允许在线修改,有些表要求先退出服务。哪些字段必须在激活前有效、哪些字段能在 active 时改变,都必须由状态列或对应列的 DESCRIPTION 说清楚。
RFC 4181 后来把这些要求整理为 MIB 编写规范:支持管理应用动态创建和删除时,通常应有一个 read-create 的 RowStatus 列;还要说明重启后的持久性或 StorageType、代理自身何时创建或删除行,以及激活和在线修改的精确条件。
标准化的是状态语法,不是所有设备的配置政策。正因为具体规则仍需公开描述,共同语法才不会变成空洞标签。
“仿佛同时发生”只属于一个请求
创建行时,若干列和值为 RowStatus 的变量绑定往往放在同一个 SetRequest 中。RFC 3416 把处理概念上分成两阶段:先验证所有变量绑定;全部通过后才修改。该请求内的各项赋值,相对于彼此应当像同时发生一样。
如果修改阶段失败,实体尝试撤销其他修改并返回 commitFailed;若无法全部撤销,则返回 undoFailed。后一个错误本身就在提醒人们,不要把抽象语义夸大成无边界的完美事务。
这个保证只覆盖一个 SNMP 实体处理的一次请求。它不是跨路由器事务,不是分布式锁,不证明重启后仍保存,也不证明数据平面已经按意图运行。管理成功提供一项有限事实,业务效果需要另行测量。
这套设计的进步,是不再让“存在”冒充“运行”
RowStatus 把权责分在不同层。管理器提出期望;MIB 公布合同;代理验证名称、访问、值、资源与状态转换;正在运行的设备给出最后的操作事实。
一行可见,仍可能缺字段。一行完整,仍可能被留在服务之外。激活请求可能被拒绝。即使 active,也未必说明配置持久、链路通畅或安全政策正确。每个状态的价值,恰恰来自它没有越权回答下一层问题。
来源与边界
RFC 1212 和 RFC 1271 说明早期约定及 RMON 前身;RFC 1443 与 RFC 2579 定义六值生命周期;RFC 3416 给出 SetRequest 边界;RFC 4181 总结 MIB 编写义务。这些材料不能证明当代部署比例、厂商一致性、通用清理时间、安全性或数据平面效果。把 RowStatus 解读为意图、就绪与运行的分层,是从机制得到的分析。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限战略圈层会员
战略圈层
所有读者均可浏览。加入并登录后可解锁档案简报。
加入战略圈层仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance





