diff options
Diffstat (limited to 'src/backend/access')
-rw-r--r-- | src/backend/access/heap/heapam.c | 18 | ||||
-rw-r--r-- | src/backend/access/heap/visibilitymap.c | 11 |
2 files changed, 19 insertions, 10 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index ce52e2dd48e..2d81383ae8a 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2149,15 +2149,6 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, &vmbuffer, NULL); page = BufferGetPage(buffer); - if (PageIsAllVisible(page)) - { - all_visible_cleared = true; - PageClearAllVisible(page); - visibilitymap_clear(relation, - BufferGetBlockNumber(buffer), - vmbuffer); - } - /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); @@ -2172,6 +2163,15 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, RelationPutHeapTuple(relation, buffer, heaptup); } + if (PageIsAllVisible(page)) + { + all_visible_cleared = true; + PageClearAllVisible(page); + visibilitymap_clear(relation, + BufferGetBlockNumber(buffer), + vmbuffer); + } + /* * XXX Should we set PageSetPrunable on this page ? See heap_insert() */ diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c index 5696abe4d2a..9152c7d1511 100644 --- a/src/backend/access/heap/visibilitymap.c +++ b/src/backend/access/heap/visibilitymap.c @@ -293,6 +293,13 @@ visibilitymap_set(Relation rel, BlockNumber heapBlk, XLogRecPtr recptr, * relation. On return, *buf is a valid buffer with the map page containing * the bit for heapBlk, or InvalidBuffer. The caller is responsible for * releasing *buf after it's done testing and setting bits. + * + * NOTE: This function is typically called without a lock on the heap page, + * so somebody else could change the bit just after we look at it. In fact, + * since we don't lock the visibility map page either, it's even possible that + * someone else could have changed the bit just before we look at it, but yet + * we might see the old value. It is the caller's responsibility to deal with + * all concurrency issues! */ bool visibilitymap_test(Relation rel, BlockNumber heapBlk, Buffer *buf) @@ -327,7 +334,9 @@ visibilitymap_test(Relation rel, BlockNumber heapBlk, Buffer *buf) map = PageGetContents(BufferGetPage(*buf)); /* - * We don't need to lock the page, as we're only looking at a single bit. + * A single-bit read is atomic. There could be memory-ordering effects + * here, but for performance reasons we make it the caller's job to worry + * about that. */ result = (map[mapByte] & (1 << mapBit)) ? true : false; |