agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Kyotaro Horiguchi <[email protected]>
Subject: [PATCH v26 5/6] Fix gistGetFakeLSN()
Date: Thu, 21 Nov 2019 16:12:03 +0900
GiST needs to set page LSN to monotically incresing numbers on updates
even if it is not WAL-logged at all. We use a simple counter for
UNLOGGESD/TEMP relations but the number must be smaller than the LSN
at the next commit for WAL-skipped relations. WAL-insertione pointer
works in major cases but we sometimes need to emit a WAL record to
generate an unique LSN for update. This patch adds a new WAL record
kind XLOG_GIST_ASSIGN_LSN, which conveys no substantial content and
emits it if needed.
---
src/backend/access/gist/gistutil.c | 38 ++++++++++++++++++--------
src/backend/access/gist/gistxlog.c | 21 ++++++++++++++
src/backend/access/rmgrdesc/gistdesc.c | 5 ++++
src/include/access/gist_private.h | 2 ++
src/include/access/gistxlog.h | 1 +
5 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c
index 66c52d6dd6..8347673c5e 100644
--- a/src/backend/access/gist/gistutil.c
+++ b/src/backend/access/gist/gistutil.c
@@ -1004,28 +1004,44 @@ gistproperty(Oid index_oid, int attno,
}
/*
- * Temporary and unlogged GiST indexes are not WAL-logged, but we need LSNs
- * to detect concurrent page splits anyway. This function provides a fake
- * sequence of LSNs for that purpose.
+ * Temporary, unlogged GiST and WAL-skipped indexes are not WAL-logged, but we
+ * need LSNs to detect concurrent page splits anyway. This function provides a
+ * fake sequence of LSNs for that purpose.
*/
XLogRecPtr
gistGetFakeLSN(Relation rel)
{
- static XLogRecPtr counter = FirstNormalUnloggedLSN;
-
- /*
- * XXX before commit fix this. This is not correct for
- * RELPERSISTENCE_PERMANENT, but it suffices to make tests pass.
- */
- if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP
- || rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+ if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
{
/*
* Temporary relations are only accessible in our session, so a simple
* backend-local counter will do.
*/
+ static XLogRecPtr counter = FirstNormalUnloggedLSN;
+
return counter++;
}
+ else if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+ {
+ /*
+ * WAL-logging on this relation will start after commit, so the LSN
+ * must be distinct numbers smaller than the LSN at the next
+ * commit. Emit a dummy WAL record if insert-LSN hasn't advanced after
+ * the last call.
+ */
+ static XLogRecPtr lastlsn = InvalidXLogRecPtr;
+ XLogRecPtr currlsn = GetXLogInsertRecPtr();
+
+ /* Shouldn't be called for WAL-logging relations */
+ Assert(!RelationNeedsWAL(rel));
+
+ /* No need for an actual record if we alredy have a distinct LSN */
+ if (!XLogRecPtrIsInvalid(lastlsn) && lastlsn == currlsn)
+ currlsn = gistXLogAssignLSN();
+
+ lastlsn = currlsn;
+ return currlsn;
+ }
else
{
/*
diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c
index 3b28f54646..ce17bc9dc3 100644
--- a/src/backend/access/gist/gistxlog.c
+++ b/src/backend/access/gist/gistxlog.c
@@ -449,6 +449,9 @@ gist_redo(XLogReaderState *record)
case XLOG_GIST_PAGE_DELETE:
gistRedoPageDelete(record);
break;
+ case XLOG_GIST_ASSIGN_LSN:
+ /* nop. See gistGetFakeLSN(). */
+ break;
default:
elog(PANIC, "gist_redo: unknown op code %u", info);
}
@@ -592,6 +595,24 @@ gistXLogPageDelete(Buffer buffer, FullTransactionId xid,
return recptr;
}
+/*
+ * Write an empty XLOG record to assign a distinct LSN.
+ */
+XLogRecPtr
+gistXLogAssignLSN(void)
+{
+ int dummy = 0;
+
+ /*
+ * Records other than SWITCH_WAL must have content. We use an integer 0 to
+ * follow the restriction.
+ */
+ XLogBeginInsert();
+ XLogSetRecordFlags(XLOG_MARK_UNIMPORTANT);
+ XLogRegisterData((char*) &dummy, sizeof(dummy));
+ return XLogInsert(RM_GIST_ID, XLOG_GIST_ASSIGN_LSN);
+}
+
/*
* Write XLOG record about reuse of a deleted page.
*/
diff --git a/src/backend/access/rmgrdesc/gistdesc.c b/src/backend/access/rmgrdesc/gistdesc.c
index eccb6fd942..48cda40ac0 100644
--- a/src/backend/access/rmgrdesc/gistdesc.c
+++ b/src/backend/access/rmgrdesc/gistdesc.c
@@ -80,6 +80,9 @@ gist_desc(StringInfo buf, XLogReaderState *record)
case XLOG_GIST_PAGE_DELETE:
out_gistxlogPageDelete(buf, (gistxlogPageDelete *) rec);
break;
+ case XLOG_GIST_ASSIGN_LSN:
+ /* No details to write out */
+ break;
}
}
@@ -104,6 +107,8 @@ gist_identify(uint8 info)
break;
case XLOG_GIST_PAGE_DELETE:
id = "PAGE_DELETE";
+ case XLOG_GIST_ASSIGN_LSN:
+ id = "ASSIGN_LSN";
break;
}
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index a409975db1..3455dd242d 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -455,6 +455,8 @@ extern XLogRecPtr gistXLogSplit(bool page_is_leaf,
BlockNumber origrlink, GistNSN oldnsn,
Buffer leftchild, bool markfollowright);
+extern XLogRecPtr gistXLogAssignLSN(void);
+
/* gistget.c */
extern bool gistgettuple(IndexScanDesc scan, ScanDirection dir);
extern int64 gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
diff --git a/src/include/access/gistxlog.h b/src/include/access/gistxlog.h
index e44922d915..1eae06c0fb 100644
--- a/src/include/access/gistxlog.h
+++ b/src/include/access/gistxlog.h
@@ -26,6 +26,7 @@
/* #define XLOG_GIST_INSERT_COMPLETE 0x40 */ /* not used anymore */
/* #define XLOG_GIST_CREATE_INDEX 0x50 */ /* not used anymore */
#define XLOG_GIST_PAGE_DELETE 0x60
+#define XLOG_GIST_ASSIGN_LSN 0x70 /* nop, assign an new LSN */
/*
* Backup Blk 0: updated page.
--
2.23.0
----Next_Part(Thu_Nov_28_20_56_20_2019_909)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v26-0006-Sync-files-shrinked-by-truncation.patch"
view thread (2+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v26 5/6] Fix gistGetFakeLSN()
In-Reply-To: <no-message-id-1883403@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox