Trees removed inside transaction can automatically come back

Bug #1055557 reported by Nathan Williams
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Akiban Persistit
High
Peter Beaman

Bug Description

Persistit r369

As of the current revision (3.1.8-SNAPSHOT, r269) tree creation is documented as non-transactional and all elements within the tree as transactional.

Since trees lifetime is not handled by MVCC it seems reasonable an application might try to remove any created during a transaction to keep the volume in a known state. However, if a tree is removed inside of a transaction is aborted the tree will be recreated by the CleanupManager.

A distilled test case:
public void treeCheck(Volume v, String msg) throws PersistitException {
    System.out.println(msg);
    for(String tree : v.getTreeNames()) {
        System.out.println(" " + tree);
        Exchange ex = _persistit.getExchange(v, tree, false);
        ex.clear().append(Key.BEFORE);
        while(ex.hasNext()) {
            System.out.println(" " + ex.getKey());
        }
    }
}

@Test
public void resurrectedTrees() throws PersistitException {
    Volume v = _persistit.getVolume(UnitTestProperties.VOLUME_NAME);
    Transaction txn = _persistit.getTransaction();
    txn.begin();
    {
        Exchange ex = _persistit.getExchange(v, "new_tree1", true);
        ex.clear().append(1).store();
        ex.removeTree();
        _persistit.releaseExchange(ex);
    }
    txn.rollback();
    txn.end();

    treeCheck(v, "Tree Check 1");
    _persistit.getJournalManager().pruneObsoleteTransactions();
    treeCheck(v, "Tree Check 2");
}

This will output:
[main] WARNING Transaction <ts=273 tc=ABORTED mvv=1> pruning incomplete at JournalAddress 16,823{273} after rollback
Tree Check 1
Tree Check 2
  new_tree1

Note that the claim of the entries being handled correct is true (the scan did not find {1}), but the tree did come back after cleanup. I've not checked into the warning so that may be another bug (e.g. causing journal growth).

Related branches

Revision history for this message
Peter Beaman (pbeaman) wrote :

I think the mechanism is pretty straightforward: the proactive pruning logic uses a TransactionPlayer to read and prune transactions from the journal. TransactionPlayer#getExchange constructs an Exchange for this purpose and sets the create flag to true; this causes the tree to be created again.

A fix would be for the getExchange() method to know whether the exchange is passed to support pruning (in which case the tree should not be created) or reapplying a transaction in recovery (in which case it should be created).

Peter Beaman (pbeaman)
Changed in akiban-persistit:
status: New → Confirmed
importance: Undecided → High
assignee: nobody → Peter Beaman (pbeaman)
Peter Beaman (pbeaman)
Changed in akiban-persistit:
status: Confirmed → Fix Released
status: Fix Released → Fix Committed
Changed in akiban-persistit:
status: Fix Committed → Fix Released
milestone: none → 3.3.0
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers