Skip to content

[io] Do not serve unread blocks from the cache after a read error - #23832

Open
chrisburr wants to merge 2 commits into
root-project:masterfrom
chrisburr:io-cache-failed-readbuffers
Open

chrisburr wants to merge 2 commits into
root-project:masterfrom
chrisburr:io-cache-failed-readbuffers

Conversation

@chrisburr

Copy link
Copy Markdown
Contributor

Tangentially related to #23831 in that this has been found in response to seeing grid jobs in LHCb that allocate unreasonable amounts of memory. See https://gitlab.cern.ch/gaudi/Gaudi/-/work_items/348 for an example of the symptom I target in this PR.

It's hard to know exactly what is going on in the job however I do know that I see this when:

  • The job is reading data remotely with XRootD
  • Vector reads are being used
  • There is some kind of read error like a timeout

This led me to the first commit (47a4690) and it seems plausible that the cache would result in future reads consuming garbage data. Claude has written a test which seems like a reasonable way of mocking this failure mode and without the fix it reproduces the same error messages as shown in the Gaudi bug report.

Changes or fixes:

  • Reset cache when remote reads fail rather than caching that the read has been done.
  • In TTreeCacheUnzip only use the cached block if the read was successful. Falls back to trying the read a second time, else errors.

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

This PR (hopefully) fixes https://gitlab.cern.ch/gaudi/Gaudi/-/work_items/348

This PR was prepared with the assistance of Claude Code (Opus 5.5).

TFileCacheRead::ReadBufferExtNormal sorts the list of blocks to read,
which marks it as sorted, before reading them all into fBuffer with
TFile::ReadBuffers. When that read fails, e.g. on an XRootD socket
timeout, only the request that triggered it reports an error: the
following requests for blocks of the same list find them in the list
and are served from fBuffer, which still holds the blocks of the
previous list, or nothing at all.

The baskets of the rest of the cluster are thus unzipped and streamed
from unrelated data. Reading LHCb DSTs over XRootD, a single timeout
is followed by "Inconsistency found in header (nin=0, nbuf=0)" errors
and allocations of several GB from the bogus content.

Reset the list of blocks when reading them fails, so that subsequent
requests miss the cache and are read from the file.

Assisted-by: claude-code:claude-opus-5-5
TTreeCacheUnzip::GetUnzipBuffer reads the requested basket from the
file only when TTreeCache::ReadBufferExt reports a miss. When that
call itself fails to read the blocks of the cache, it returns -1, and
the basket is unzipped from whatever fCompBuffer holds: the previous
basket, or uninitialised memory.

This happens when learning prefill has filled the cache before the
first basket is requested. Treat a failure as a miss, so that the
basket is read from the file.

Assisted-by: claude-code:claude-opus-5-5
@chrisburr chrisburr changed the title Io cache failed readbuffers [io] Do not serve unread blocks from the cache after a read error Oct 24, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants