Skip to content

persistit: stale step-visibility from Volume.getTree() after restart until CleanupManager prunes #264

Description

@vharseko

Summary

After a crash/restart, Volume.getTree(name, false) (and step-based MVCC visibility checks generally) can return a stale answer until background maintenance happens to run. Recovery itself completes synchronously inside Persistit.initialize(), but two maintenance tasks are asynchronous after it:

  • the TransactionIndex active-transaction-cache updater thread;
  • CleanupManager's pruneTimelyResources(), which fires only on its poll timer (default ~1 s).

Until those run, residual tree-version state from before the crash can leak into step-based visibility — e.g. a tree created at transaction step 1 is reported visible at step 0.

How it was found

TreeTransactionalLifetimeTest.createRemoveByStep failed intermittently on CI (ComparisonFailure: expected:<0[],...> but was:<0[:],...> — a tree visible at step 0 that should not be). The test-side fix (#260) forces getTransactionIndex().updateActiveTransactionCache() + pruneTimelyResources() after initialize(), mirroring what sibling tests in the class already do before asserting.

Raised during review of #257: an application calling Volume.getTree(name, false) shortly after initialize() hits the same window — it has no way to know it must wait for internal maintenance timers.

Repro sketch

// createRemoveByStepHelper-style sequence:
txn.begin();
txn.setStep(1);
volume.getTree(treeName, true);        // create at step 1
...
persistit.checkpoint();
persistit.crash();                     // or close()

persistit = new Persistit(config);
persistit.initialize();
// Immediately after initialize(), on a step-0 view:
volume.getTree(treeName, false);       // may report the tree visible at step 0
// After updateActiveTransactionCache() + pruneTimelyResources(): correct answer

Intermittent — depends on whether the CleanupManager timer fired between restart and the query.

Question

Should initialize() settle this state before returning (update the active-transaction cache and prune timely resources at the end of recovery), so applications get correct step visibility immediately rather than depending on an internal timer? The cost is bounded (one ATC update plus one prune pass at startup).

Refs: #257 (review discussion), #260 (test-side workaround).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions