mg: 修改现有项目时忽略 E (新 CAS) 标志
**描述错误** meta get (mg) 将 E(token) 标志定义为"如果项被修改,则使用 token 作为新的 CAS 值"(doc/protocol.txt:558,在 meta get 标志列表中)。实际上,只有在 mg 自动生成新项时才会应用 E(使用 N 标志);当 mg 修改现有项时 — — 例如,使用 T 修改其 TTL 时,则会解析 E 覆盖,然后默默丢弃,且项保留其原 CAS 值。要么修改路径中缺少覆盖,要么在文档中不应将 E 列入 mg。 **要重现此问题** 对于默认实例 (memcached -p 11311 -l 127.0.0.1),使用 nc。 use_cas 设置为开启(默认)。序列和实际响应: set foo 0 0 3 bar STORED mg foo c t HD c2 t90 // 基线: CAS=2,没有 TTL mg foo T90 E555 c t HD c2 t90 // T 修改了 foo,但 CAS 仍然是 2,而不是 555 mg foo c t HD c2 t90 // 确认 CAS 未变化 // 与 E 相比 — — 当 N 自动生成新键时, E 将被尊重: mg newkey N90 E555 c t HD c555 t90 W // 创建; E 将 CAS 设置为 555 mg newkey c t HD c555 t90 Z // 确认 CAS=555 预期: 由于 T90 修改了 foo, E555 应将其 CAS 设置为 555,因此第二个 mg foo c t 应报告 c555。实际: CAS 在修改路径上保持 c2; E 仅在自动生成创建时有效。受影响的版本: 在 1.6.44 中重现(在撰写本文时的最新版本)。相关代码(在 proto_parser.c 中,对所有 meta 命令进行解析,仅在 mg 自动生成 do_item_link 时应用,在现有项标志循环中没有"E"情况)在许多早期版本中似乎没有变化,因此可能是长期存在的问题 — — 不是升级回归。在根本原因指针(如果有用)中: E 在 proto_parser.c:593 中被解析为 of.cas_id_in;在 do_item_link(it, hv, of.has_cas_in ? of.cas_id_in : get_cas_id()) 中通过自动生成应用,但 process_mget 中的现有项标志循环处理 T/N/R/s/t/c/f 并没有"E"情况,因此修改路径上没有 ITEM_set_cas。proto_parser.c:593 中的解析器注释表明 E 适用于 // ms, md, ma,这表明在 meta get 中列出 E 可能是错误。 **系统信息** - 操作系统/发行版: Ubuntu - 操作系统/发行版的版本: 24.04.4 LTS (内核 6.17.0-35-generic, x86_64) - memcached 的版本: 1.6.44 - 硬件详细信息: 第 13 代 Intel Core i7-1360P (16 核) **详细信息(请包含!)** 没有崩溃/段错误 — addr2line/core dump N/A。 新的默认实例。相关统计设置: STAT cas_enabled yes STAT maxbytes 67108864 STAT item_size_max 1048576 STAT num_threads 4 STAT binding_protocol auto-negotiate STAT hashpower_init 0 STAT verbosity 0 统计信息(后续重现,否则处于空闲状态): 版本 1.6.44,指针大小 64,当前项 2,总项 2,命令集 1。完整的统计信息/统计项/统计块均为默认值,可根据要求获取。
内容来源: memcached/memcached