diff options
author | Kevin Grittner <kgrittn@postgresql.org> | 2016-04-08 14:36:30 -0500 |
---|---|---|
committer | Kevin Grittner <kgrittn@postgresql.org> | 2016-04-08 14:36:30 -0500 |
commit | 848ef42bb8c7909c9d7baa38178d4a209906e7c1 (patch) | |
tree | e15250d8dfd8f46b15e3ecfddfcad09799cc3866 /src/backend/access/gin/ginget.c | |
parent | 8b65cf4c5edabdcae45ceaef7b9ac236879aae50 (diff) |
Add the "snapshot too old" feature
This feature is controlled by a new old_snapshot_threshold GUC. A
value of -1 disables the feature, and that is the default. The
value of 0 is just intended for testing. Above that it is the
number of minutes a snapshot can reach before pruning and vacuum
are allowed to remove dead tuples which the snapshot would
otherwise protect. The xmin associated with a transaction ID does
still protect dead tuples. A connection which is using an "old"
snapshot does not get an error unless it accesses a page modified
recently enough that it might not be able to produce accurate
results.
This is similar to the Oracle feature, and we use the same SQLSTATE
and error message for compatibility.
Diffstat (limited to 'src/backend/access/gin/ginget.c')
-rw-r--r-- | src/backend/access/gin/ginget.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c index 33683278e10..b79ba1e62af 100644 --- a/src/backend/access/gin/ginget.c +++ b/src/backend/access/gin/ginget.c @@ -73,7 +73,7 @@ scanPostingTree(Relation index, GinScanEntry scanEntry, Page page; /* Descend to the leftmost leaf page */ - stack = ginScanBeginPostingTree(&btree, index, rootPostingTree); + stack = ginScanBeginPostingTree(&btree, index, rootPostingTree, snapshot); buffer = stack->buffer; IncrBufferRefCount(buffer); /* prevent unpin in freeGinBtreeStack */ @@ -146,7 +146,8 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack, if (moveRightIfItNeeded(btree, stack) == false) return true; - page = BufferGetPage(stack->buffer, NULL, NULL, BGP_NO_SNAPSHOT_TEST); + page = BufferGetPage(stack->buffer, snapshot, btree->index, + BGP_TEST_FOR_OLD_SNAPSHOT); itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, stack->off)); /* @@ -320,7 +321,7 @@ restartScanEntry: ginPrepareEntryScan(&btreeEntry, entry->attnum, entry->queryKey, entry->queryCategory, ginstate); - stackEntry = ginFindLeafPage(&btreeEntry, true); + stackEntry = ginFindLeafPage(&btreeEntry, true, snapshot); page = BufferGetPage(stackEntry->buffer, NULL, NULL, BGP_NO_SNAPSHOT_TEST); needUnlock = TRUE; @@ -385,7 +386,7 @@ restartScanEntry: needUnlock = FALSE; stack = ginScanBeginPostingTree(&entry->btree, ginstate->index, - rootPostingTree); + rootPostingTree, snapshot); entry->buffer = stack->buffer; /* @@ -627,7 +628,7 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry, entry->btree.itemptr.ip_posid++; } entry->btree.fullScan = false; - stack = ginFindLeafPage(&entry->btree, true); + stack = ginFindLeafPage(&entry->btree, true, snapshot); /* we don't need the stack, just the buffer. */ entry->buffer = stack->buffer; @@ -1335,8 +1336,8 @@ scanGetCandidate(IndexScanDesc scan, pendingPosition *pos) ItemPointerSetInvalid(&pos->item); for (;;) { - page = BufferGetPage(pos->pendingBuffer, NULL, - NULL, BGP_NO_SNAPSHOT_TEST); + page = BufferGetPage(pos->pendingBuffer, scan->xs_snapshot, + scan->indexRelation, BGP_TEST_FOR_OLD_SNAPSHOT); maxoff = PageGetMaxOffsetNumber(page); if (pos->firstOffset > maxoff) @@ -1516,8 +1517,8 @@ collectMatchesForHeapRow(IndexScanDesc scan, pendingPosition *pos) memset(datumExtracted + pos->firstOffset - 1, 0, sizeof(bool) * (pos->lastOffset - pos->firstOffset)); - page = BufferGetPage(pos->pendingBuffer, NULL, - NULL, BGP_NO_SNAPSHOT_TEST); + page = BufferGetPage(pos->pendingBuffer, scan->xs_snapshot, + scan->indexRelation, BGP_TEST_FOR_OLD_SNAPSHOT); for (i = 0; i < so->nkeys; i++) { @@ -1710,7 +1711,8 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids) *ntids = 0; LockBuffer(metabuffer, GIN_SHARE); - page = BufferGetPage(metabuffer, NULL, NULL, BGP_NO_SNAPSHOT_TEST); + page = BufferGetPage(metabuffer, scan->xs_snapshot, scan->indexRelation, + BGP_TEST_FOR_OLD_SNAPSHOT); blkno = GinPageGetMeta(page)->head; /* |