memcached / memcached/memcached

mg: E (new CAS) flag ignored when modifying an existing item

Open
#1,301 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
14.3k
Forks
3.3k
PR merge metrics
No merged PRs in 30d

Description

Describe the bug
Meta Get (mg) documents the E(token) flag as "use token as new CAS value if item is modified"(doc/protocol.txt:558, in the metaget flag list). In practice E is applied only when mg autovivifies a new item (N flag); when mg modifies an existing item — e.g. touches its TTL with T — the E override is parsed and then silently dropped, and the item keeps its old CAS. Either the modify path is missing the override, or E should not be listed for mg in the docs.

To Reproduce
Against a default instance (memcached -p 11311 -l 127.0.0.1), over nc. use_cas is on (default). Sequence and actual responses:

set foo 0 0 3
bar
STORED
mg foo c t
HD c2 t-1 // baseline: CAS=2, no TTL
mg foo T90 E555 c t
HD c2 t90 // T applied (TTL→90) but CAS is STILL 2, not 555
mg foo c t
HD c2 t90 // confirms CAS unchanged

// contrast — E IS honored when N autovivifies a NEW key:
mg newkey N90 E555 c t
HD c555 t90 W // created; CAS set to 555 by E
mg newkey c t
HD c555 t90 Z // confirms CAS=555

Expected: because T90 modified foo, E555 should set its CAS to 555, so the second mg foo c t should report c555. Actual: CAS stays c2 on the modify path; E works only on autovivify-create.

Versions affected: reproduced on 1.6.44 (latest at time of writing). The relevant code (E parsed for all meta cmds, applied only on the mg autovivify do_item_link, with no case 'E' in the existing-item flag loop) appears unchanged for many prior releases, so likely long-standing — not an upgrade regression.

Root cause pointer (in case useful): E is parsed into of.cas_id_in at proto_parser.c:593; applied on autovivify via do_item_link(it, hv, of.has_cas_in ? of.cas_id_in : get_cas_id()); but the existing-item flag loop in process_mget handles T/N/R/s/t/c/f with no case 'E', so no ITEM_set_cas on the modify path. The parser comment at proto_parser.c:593 scopes E to // ms, md, ma, which suggests the doc listing E under metaget may be the error.

System Information

  • OS/Distro: Ubuntu
  • Version of OS/distro: 24.04.4 LTS (kernel 6.17.0-35-generic, x86_64)
  • Version of memcached: 1.6.44
  • Hardware detail: 13th Gen Intel Core i7-1360P (16 cores)

Detail (please include!)
No crash/segfault — addr2line/core dump N/A.
Fresh default instance. Relevant stats settings:
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
stats (post-repro, otherwise idle): version 1.6.44, pointer_size 64, curr_items 2, total_items 2, cmd_set 1. Full stats / stats items / stats slabs are all defaults and available on request.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with proto_parser.c:593 to confirm how E is parsed, then inspect the existing-item flag loop in process_mget and the autovivify path using do_item_link. Reproduce the issue with the provided nc sequence against memcached, and verify that modifying foo with T90 E555 reports CAS 555 afterward, or that the documentation no longer advertises E for mg if that is the intended resolution.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.