Repository navigation
Share one LMDB environment per shard per process - #23746
Merged
Merged
Conversation
jgranstrom
marked this pull request as ready for review
November 2, 2026 16:51
LMDB forbids opening an environment twice in one process (lmdb.h, Caveats). A second open resets the shard's writer lock under the first when no other process has the shard open, and closing either copy drops the process's fcntl locks on lock.mdb, so the next opener resets it. Either way, two writers can then write the shard at once and damage it. A `--no-pantsd` run that garbage collects its bootstrap scheduler, and a test process with one RuleRunner per test, both did this. Stores now share each shard's environment through a process-wide registry keyed by the lock file's device and inode, and an environment is closed once no store holds it. A process forked from the one that owns the registry cannot open a store. A shared environment keeps its map size, and requesting a larger one is an error, so the options that size the store are now daemon options: changing one restarts pantsd.
jgranstrom
force-pushed
the
jg/lmdb-shared-env
branch
from
November 3, 2026 20:38
a5e1d6c to
5a74bf0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A pants process that opened the local store more than once and dropped one copy lost its LMDB locks while the other copy kept writing. So another process could write the same shard at the same time and corrupt it on disk.
--no-pantsdwith a bootstrap scheduler and test processes with oneRuleRunnerper test both did this.LMDB says to not open the store more than once in the same process for this reason
With this PR:
lock file's device and inode. An environment is closed once no store holds it.
process is an error, and
local_store_shard_countand thelocal_store_*_max_size_bytesoptions now restart pantsd. This is needed because the new scheduler is built before the old is released, and currently the old scheduler is also leaked anyways. So it's a larger change to first close it to open it with a new shard count or similar.
Tests added to cover the new path, and one of the tests fail on main by dropping one of the stores leaving the other without locks. Also tested end-to-end on MacOS with a debug-engine where a process that dropped a second store, writing beside a process with one
RuleRunnerper test, damaged a shard within seconds on main and ran 60 s without damage with this change.Since #23720, each process that opens the store runs
mdb_reader_check, which frees the readerslots of any process that holds no liveness lock, so a process that lost its locks also loses the
protection of its open read transactions. This change removes the lock loss.
Disclosure: Implemented and verified with Claude with human direction