When using the SnapshottingRefDirectory, if a thread has read
packed-refs, then another actor updates packed-refs, the original
thread may create an update that is based on the old cached/snapshotted
packed-refs content. That update could effectively perform a forced
update unintentionally because it is unaware of the new content. This
seems particularly likely to happen in a scenario where a loose ref was
just packed. Our thread would otherwise see the non-snapshotted loose
ref value, but instead relies on its outdated packed-refs snapshot.
The problem is potentially related to the Gerrit Code Review Issue 309098227
where Gerrit multi-site plugin detected an in-memory split-brain where
two threads were trying to update the same ref, with one of the thread
having a stale cached data, which is compatible with the underlying
JGit issue.
The two threads trying to update the same ref did not have the same view of the underlying ref-db at the time of the ref-update execution.
Expected behavior
When two threads are reading concurrently a changing ref-db and starting to update a ref, they should have the same view of the ref-db which corresponds to the latest update performed on disk, regardless of the previously cached value.
Version
6.6.0 or later
Operating System
Linux/Unix, MacOS, Windows
Bug description
The Problem
When using the
SnapshottingRefDirectory
, if a thread has read packed-refs, then another actor updates packed-refs, the original thread may create an update that is based on the old cached/snapshotted packed-refs content. That update could effectively perform a forced update unintentionally because it is unaware of the new content. This seems particularly likely to happen in a scenario where a loose ref was just packed. Our thread would otherwise see the non-snapshotted loose ref value, but instead relies on its outdated packed-refs snapshot.The problem is potentially related to the Gerrit Code Review Issue 309098227 where Gerrit multi-site plugin detected an in-memory split-brain where two threads were trying to update the same ref, with one of the thread having a stale cached data, which is compatible with the underlying JGit issue.
In the case of the Gerrit Code Review Issue 309098227, disabling the use of
SnapshottingRefDirectory
solved the problem.Actual behavior
The two threads trying to update the same ref did not have the same view of the underlying ref-db at the time of the ref-update execution.
Expected behavior
When two threads are reading concurrently a changing ref-db and starting to update a ref, they should have the same view of the ref-db which corresponds to the latest update performed on disk, regardless of the previously cached value.
Relevant log output
No response
Other information
No response