diff options
author | Teodor Sigaev | 2018-05-04 08:27:50 +0000 |
---|---|---|
committer | Teodor Sigaev | 2018-05-04 08:27:50 +0000 |
commit | 0bef1c0678d94436f80450d562a866bb6fa5e509 (patch) | |
tree | fbcc3b758f520971188a8d9f6727e482f23afe02 /src/backend/access/gin/gindatapage.c | |
parent | 7d8679975f650d1150d706c8b6a5f04f08dcdd00 (diff) |
Re-think predicate locking on GIN indexes.
The principle behind the locking was not very well thought-out, and not
documented. Add a section in the README to explain how it's supposed to
work, and change the code so that it actually works that way.
This fixes two bugs:
1. If fast update was turned on concurrently, subsequent inserts to the
pending list would not conflict with predicate locks that were acquired
earlier, on entry pages. The included 'predicate-gin-fastupdate' test
demonstrates that. To fix, make all scans acquire a predicate lock on
the metapage. That lock represents a scan of the pending list, whether
or not there is a pending list at the moment. Forget about the
optimization to skip locking/checking for locks, when fastupdate=off.
2. If a scan finds no match, it still needs to lock the entry page. The
point of predicate locks is to lock the gabs between values, whether
or not there is a match. The included 'predicate-gin-nomatch' test
tests that case.
In addition to those two bug fixes, this removes some unnecessary locking,
following the principle laid out in the README. Because all items in
a posting tree have the same key value, a lock on the posting tree root is
enough to cover all the items. (With a very large posting tree, it would
possibly be better to lock the posting tree leaf pages instead, so that a
"skip scan" with a query like "A & B", you could avoid unnecessary conflict
if a new tuple is inserted with A but !B. But let's keep this simple.)
Also, some spelling fixes.
Author: Heikki Linnakangas with some editorization by me
Review: Andrey Borodin, Alexander Korotkov
Discussion: https://www.postgresql.org/message-id/[email protected]
Diffstat (limited to 'src/backend/access/gin/gindatapage.c')
-rw-r--r-- | src/backend/access/gin/gindatapage.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c index 59bf21744f5..aeaf8adab09 100644 --- a/src/backend/access/gin/gindatapage.c +++ b/src/backend/access/gin/gindatapage.c @@ -1812,8 +1812,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, blkno = BufferGetBlockNumber(buffer); /* - * Copy a predicate lock from entry tree leaf (containing posting list) to - * posting tree. + * Copy any predicate locks from the entry tree leaf (containing posting + * list) to the posting tree. */ PredicateLockPageSplit(index, BufferGetBlockNumber(entrybuffer), blkno); @@ -1864,7 +1864,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, return blkno; } -void +static void ginPrepareDataScan(GinBtree btree, Relation index, BlockNumber rootBlkno) { memset(btree, 0, sizeof(GinBtreeData)); @@ -1911,7 +1911,6 @@ ginInsertItemPointers(Relation index, BlockNumber rootBlkno, btree.itemptr = insertdata.items[insertdata.curitem]; stack = ginFindLeafPage(&btree, false, NULL); - GinCheckForSerializableConflictIn(btree.index, NULL, stack->buffer); ginInsertValue(&btree, stack, &insertdata, buildStats); } } |