0001-Stamp-deleted-GIN-page-with-xid-v3.patch
application/octet-stream
Filename: 0001-Stamp-deleted-GIN-page-with-xid-v3.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v3-0001
Subject: Stamp deleted GIN page with xid v3
| File | + | − |
|---|---|---|
| src/backend/access/gin/ginutil.c | 6 | 1 |
| src/backend/access/gin/ginvacuum.c | 6 | 1 |
| src/backend/access/gin/ginxlog.c | 1 | 0 |
| src/include/access/gin_private.h | 3 | 0 |
| src/include/access/ginxlog.h | 1 | 0 |
From 0560b46f96e82c7082b8fcf434a3c6c9f46a94b8 Mon Sep 17 00:00:00 2001
From: Andrey <amborodin@acm.org>
Date: Mon, 10 Dec 2018 18:49:47 +0500
Subject: [PATCH] Stamp deleted GIN page with xid v3
---
src/backend/access/gin/ginutil.c | 7 ++++++-
src/backend/access/gin/ginvacuum.c | 7 ++++++-
src/backend/access/gin/ginxlog.c | 1 +
src/include/access/gin_private.h | 3 +++
src/include/access/ginxlog.h | 1 +
5 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index d7696a1ad0..5ce39d821b 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -314,7 +314,12 @@ GinNewBuffer(Relation index)
if (PageIsNew(page))
return buffer; /* OK to use, if never initialized */
- if (GinPageIsDeleted(page))
+ /*
+ * We should not reuse page until every transaction started before
+ * deletion is over
+ */
+ if (GinPageIsDeleted(page)
+ && TransactionIdPrecedes(GinPageGetDeleteXid(page), RecentGlobalXmin))
return buffer; /* OK to use */
LockBuffer(buffer, GIN_UNLOCK);
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index 3104bc12b6..75dc03f495 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -16,6 +16,7 @@
#include "access/gin_private.h"
#include "access/ginxlog.h"
+#include "access/transam.h"
#include "access/xloginsert.h"
#include "commands/vacuum.h"
#include "miscadmin.h"
@@ -157,6 +158,9 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
page = BufferGetPage(dBuffer);
rightlink = GinPageGetOpaque(page)->rightlink;
+ /* for each deleted page we remember last xid which could knew it's address */
+ GinPageSetDeleteXid(page, ReadNewTransactionId());
+
/*
* Any insert which would have gone on the leaf block will now go to its
* right sibling.
@@ -213,6 +217,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
data.parentOffset = myoff;
data.rightLink = GinPageGetOpaque(page)->rightlink;
+ data.deleteXid = GinPageGetDeleteXid(page);
XLogRegisterData((char *) &data, sizeof(ginxlogDeletePage));
@@ -742,7 +747,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
LockBuffer(buffer, GIN_SHARE);
page = (Page) BufferGetPage(buffer);
- if (PageIsNew(page) || GinPageIsDeleted(page))
+ if (PageIsNew(page) || (GinPageIsDeleted(page) && TransactionIdPrecedes(GinPageGetDeleteXid(page), RecentGlobalXmin)))
{
Assert(blkno != GIN_ROOT_BLKNO);
RecordFreeIndexPage(index, blkno);
diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c
index 7701a2d6bf..7821f69077 100644
--- a/src/backend/access/gin/ginxlog.c
+++ b/src/backend/access/gin/ginxlog.c
@@ -518,6 +518,7 @@ ginRedoDeletePage(XLogReaderState *record)
page = BufferGetPage(dbuffer);
Assert(GinPageIsData(page));
GinPageGetOpaque(page)->flags = GIN_DELETED;
+ GinPageSetDeleteXid(page, data->deleteXid);
PageSetLSN(page, lsn);
MarkBufferDirty(dbuffer);
}
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index 81bf8734ce..83d2621488 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -44,6 +44,9 @@ typedef struct GinOptions
#define GIN_SHARE BUFFER_LOCK_SHARE
#define GIN_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE
+#define GinPageGetDeleteXid(page) ( ((PageHeader) (page))->pd_prune_xid )
+#define GinPageSetDeleteXid(page, val) ( ((PageHeader) (page))->pd_prune_xid = val)
+
/*
* GinState: working data structure describing the index being worked on
diff --git a/src/include/access/ginxlog.h b/src/include/access/ginxlog.h
index 64a3c9e18b..d7f44d6b83 100644
--- a/src/include/access/ginxlog.h
+++ b/src/include/access/ginxlog.h
@@ -158,6 +158,7 @@ typedef struct ginxlogDeletePage
{
OffsetNumber parentOffset;
BlockNumber rightLink;
+ TransactionId deleteXid; /* last Xid which could see page in scan */
} ginxlogDeletePage;
#define XLOG_GIN_UPDATE_META_PAGE 0x60
--
2.17.2 (Apple Git-113)