agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
31+ messages / 4 participants
[nested] [flat]

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping.
@ 2021-01-20 14:59 Kyotaro Horiguchi <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Kyotaro Horiguchi @ 2021-01-20 14:59 UTC (permalink / raw)

WAL-skipping optimization omits bumping page LSN when ALTER TABLE SET
TABLESPACE. Also heap_page_prune does the same.  However,
old_snapshot_threshold feature needs page LSN to be kept updated on
these operations so that TestForOldSnapshot properly find identify
whether a snapshot is invalidated.
---
 src/backend/access/heap/pruneheap.c | 14 ++++++++++++++
 src/backend/catalog/storage.c       |  8 ++++++++
 src/include/storage/bufmgr.h        |  3 ++-
 src/include/utils/rel.h             |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index e3a716a2a2..33c0841b36 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -70,6 +70,8 @@ static void heap_prune_record_redirect(PruneState *prstate,
 static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum);
 static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum);
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * Optionally prune and repair fragmentation in the specified page.
@@ -331,6 +333,18 @@ heap_page_prune(Relation relation, Buffer buffer,
 
 			PageSetLSN(BufferGetPage(buffer), recptr);
 		}
+		else if (relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+		{
+			XLogRecPtr	currlsn = GetXLogInsertRecPtr();
+			Page		page = BufferGetPage(buffer);
+
+			Assert(wal_level < WAL_LEVEL_REPLICA);
+
+			/* we need to update page LSN to notify reader of pruning */
+			if (PageGetLSN(page) == currlsn)
+				currlsn = gistXLogAssignLSN();
+			PageSetLSN(page, currlsn);
+		}
 	}
 	else
 	{
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index cba7a9ada0..488ac6f760 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -75,6 +75,8 @@ typedef struct PendingRelSync
 static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */
 HTAB	   *pendingSyncHash = NULL;
 
+/* XXXXXXXX tmporary modification */
+extern XLogRecPtr gistXLogAssignLSN(void);
 
 /*
  * AddPendingSync
@@ -414,6 +416,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	bool		copying_initfork;
 	BlockNumber nblocks;
 	BlockNumber blkno;
+	XLogRecPtr	fakepagelsn;
 
 	page = (Page) buf.data;
 
@@ -434,6 +437,9 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 	use_wal = XLogIsNeeded() &&
 		(relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork);
 
+	if (!use_wal)
+		fakepagelsn = gistXLogAssignLSN();
+
 	nblocks = smgrnblocks(src, forkNum);
 
 	for (blkno = 0; blkno < nblocks; blkno++)
@@ -460,6 +466,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 		 */
 		if (use_wal)
 			log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false);
+		else
+			PageSetLSN(page, fakepagelsn);
 
 		PageSetChecksumInplace(page, blkno);
 
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index e641174798..9ab9e7394c 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -19,6 +19,7 @@
 #include "storage/buf.h"
 #include "storage/bufpage.h"
 #include "storage/relfilenode.h"
+#include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/snapmgr.h"
 
@@ -289,7 +290,7 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
 		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC
 			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)
 		&& !XLogRecPtrIsInvalid((snapshot)->lsn)
-		&& (!XLogIsNeeded() || PageGetLSN(page) > (snapshot)->lsn))
+		&& PageGetLSN(page) > (snapshot)->lsn)
 		TestForOldSnapshot_impl(snapshot, relation);
 }
 
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f58d65cf28..35e53c8d74 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -618,8 +618,8 @@ typedef struct ViewOptions
  *		decoding snapshot.
  */
 #define RelationIsAccessibleInLogicalDecoding(relation) \
-	(XLogLogicalInfoActive() && \
-	 RelationNeedsWAL(relation) && \
+	(XLogLogicalInfoActive() &&											\
+	 (relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT &&	\
 	 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
-- 
2.27.0


----Next_Part(Thu_Jan_21_00_28_44_2021_003)----





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* optimize several list functions with SIMD intrinsics
@ 2023-03-08 00:25 Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
  0 siblings, 1 reply; 31+ messages in thread

From: Nathan Bossart @ 2023-03-08 00:25 UTC (permalink / raw)
  To: pgsql-hackers

I noticed that several of the List functions do simple linear searches that
can be optimized with SIMD intrinsics (as was done for XidInMVCCSnapshot in
37a6e5d).  The following table shows the time spent iterating over a list
of n elements (via list_member_int) one billion times on my x86 laptop.

      n   | head (ms) | patched (ms) 
    ------+-----------+--------------
        2 |      3884 |         3001
        4 |      5506 |         4092
        8 |      6209 |         3026
       16 |      8797 |         4458
       32 |     25051 |         7032
       64 |     37611 |        12763
      128 |     61886 |        22770
      256 |    111170 |        59885
      512 |    209612 |       103378
     1024 |    407462 |       189484

I've attached a work-in-progress patch that implements these optimizations
for both x86 and arm, and I will register this in the July commitfest.  I'm
posting this a little early in order to gauge interest.  Presumably you
shouldn't be using a List if you have many elements that must be routinely
searched, but it might be nice to speed up these functions, anyway.  This
was mostly a fun weekend project, and I don't presently have any concrete
examples of workloads where this might help.

-- 
Nathan Bossart
Amazon Web Services: https://aws.amazon.com


^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
@ 2023-03-08 00:54 ` David Rowley <[email protected]>
  2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 31+ messages in thread

From: David Rowley @ 2023-03-08 00:54 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: pgsql-hackers

On Wed, 8 Mar 2023 at 13:25, Nathan Bossart <[email protected]> wrote:
> I've attached a work-in-progress patch that implements these optimizations
> for both x86 and arm, and I will register this in the July commitfest.  I'm
> posting this a little early in order to gauge interest.

Interesting and quite impressive performance numbers.



^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
@ 2023-03-08 04:56   ` Nathan Bossart <[email protected]>
  2023-03-08 18:58     ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 31+ messages in thread

From: Nathan Bossart @ 2023-03-08 04:56 UTC (permalink / raw)
  To: David Rowley <[email protected]>; +Cc: pgsql-hackers

On Wed, Mar 08, 2023 at 01:54:15PM +1300, David Rowley wrote:
> Interesting and quite impressive performance numbers.

Thanks for taking a look.

> From having a quick glance at the patch, it looks like you'll need to
> take some extra time to make it work on 32-bit builds.

At the moment, the support for SIMD intrinsics in Postgres is limited to
64-bit (simd.h has the details).  But yes, if we want to make this work for
32-bit builds, additional work is required.

-- 
Nathan Bossart
Amazon Web Services: https://aws.amazon.com





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
  2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
@ 2023-03-08 18:58     ` Nathan Bossart <[email protected]>
  2023-03-11 09:41       ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
  0 siblings, 1 reply; 31+ messages in thread

From: Nathan Bossart @ 2023-03-08 18:58 UTC (permalink / raw)
  To: David Rowley <[email protected]>; +Cc: pgsql-hackers

cfbot's Windows build wasn't happy with a couple of casts.  I applied a
fix similar to c6a43c2 in v2.  The patch is still very much a work in
progress.

-- 
Nathan Bossart
Amazon Web Services: https://aws.amazon.com


^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
  2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 18:58     ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
@ 2023-03-11 09:41       ` Ankit Kumar Pandey <[email protected]>
  2023-03-11 10:58         ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
  2023-03-13 21:40         ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  0 siblings, 2 replies; 31+ messages in thread

From: Ankit Kumar Pandey @ 2023-03-11 09:41 UTC (permalink / raw)
  To: [email protected]; +Cc: Nathan Bossart <[email protected]>

The following review has been posted through the commitfest application:
make installcheck-world:  tested, passed
Implements feature:       not tested
Spec compliant:           not tested
Documentation:            not tested

Hello, 

Adding some review comments:

1. In list_member_ptr, will it be okay to bring `const ListCell *cell` from 
#ifdef USE_NO_SIMD
	const ListCell *cell;
#endif
to #else like as mentioned below? This will make visual separation between #if cases more cleaner
#else
      const ListCell *cell;

	foreach(cell, list)
	{
		if (lfirst(cell) == datum)
			return true;
	}

	return false;

#endif

2. Lots of duplicated
if (list == NIL) checks before calling  list_member_inline_internal(list, datum)
Can we not add this check in list_member_inline_internal itself?
3. if (cell)
		return list_delete_cell(list, cell) in list_delete_int/oid
can we change if (cell) to if (cell != NULL) as used elsewhere?
4. list_member_inline_interal_idx , there is typo in name.
5. list_member_inline_interal_idx and list_member_inline_internal are practically same with almost 90+ % duplication.
can we not refactor both into one and allow cell or true/false as return? Although I see usage of const ListCell so this might be problematic.
6. Loop for (i = 0; i < tail_idx; i += nelem_per_iteration) for Vector32 in list.c looks duplicated from pg_lfind32 (in pg_lfind.h), can we not reuse that?
7. Is it possible to add a benchmark which shows improvement against HEAD ?

Regards,
Ankit

The new status of this patch is: Waiting on Author


^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
  2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 18:58     ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-11 09:41       ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
@ 2023-03-11 10:58         ` Ankit Kumar Pandey <[email protected]>
  1 sibling, 0 replies; 31+ messages in thread

From: Ankit Kumar Pandey @ 2023-03-11 10:58 UTC (permalink / raw)
  To: [email protected]; +Cc: Nathan Bossart <[email protected]>


 > 7. Is it possible to add a benchmark which shows improvement against 
HEAD ?


Please ignore this from my earlier mail, I just saw stats now.

Thanks,

Ankit







^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
  2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 18:58     ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-11 09:41       ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
@ 2023-03-13 21:40         ` Nathan Bossart <[email protected]>
  2023-03-15 14:01           ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
  1 sibling, 1 reply; 31+ messages in thread

From: Nathan Bossart @ 2023-03-13 21:40 UTC (permalink / raw)
  To: Ankit Kumar Pandey <[email protected]>; +Cc: [email protected]

Thanks for taking a look.

On Sat, Mar 11, 2023 at 09:41:18AM +0000, Ankit Kumar Pandey wrote:
> 1. In list_member_ptr, will it be okay to bring `const ListCell *cell` from 
> #ifdef USE_NO_SIMD
> 	const ListCell *cell;
> #endif
> to #else like as mentioned below? This will make visual separation between #if cases more cleaner

I would expect to see -Wdeclaration-after-statement warnings if we did
this.

> 2. Lots of duplicated
> if (list == NIL) checks before calling  list_member_inline_internal(list, datum)
> Can we not add this check in list_member_inline_internal itself?

We probably could.  I only extracted the NIL checks to simplify the code in
list_member_inline_internal() a bit.

> 3. if (cell)
> 		return list_delete_cell(list, cell) in list_delete_int/oid
> can we change if (cell) to if (cell != NULL) as used elsewhere?

Sure.

> 4. list_member_inline_interal_idx , there is typo in name.

Will fix.

> 5. list_member_inline_interal_idx and list_member_inline_internal are practically same with almost 90+ % duplication.
> can we not refactor both into one and allow cell or true/false as return? Although I see usage of const ListCell so this might be problematic.

The idea was to skip finding the exact match if all we care about is
whether the element exists.  This micro-optimization might be negligible,
in which case we could use list_member_inline_internal_idx() for both
cases.

> 6. Loop for (i = 0; i < tail_idx; i += nelem_per_iteration) for Vector32 in list.c looks duplicated from pg_lfind32 (in pg_lfind.h), can we not reuse that?

The list.c version is slightly different because we need to disregard any
matches that we find in between the data.  For example, in an integer List,
the integer will take up 4 bytes of the 8-byte ListCell (for 64-bit
platforms).

	typedef union ListCell
	{
		void	   *ptr_value;
		int			int_value;
		Oid			oid_value;
		TransactionId xid_value;
	} ListCell;

-- 
Nathan Bossart
Amazon Web Services: https://aws.amazon.com





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
  2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 18:58     ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-11 09:41       ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
  2023-03-13 21:40         ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
@ 2023-03-15 14:01           ` Ankit Kumar Pandey <[email protected]>
  2023-03-15 16:23             ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  0 siblings, 1 reply; 31+ messages in thread

From: Ankit Kumar Pandey @ 2023-03-15 14:01 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: [email protected]

Agree with your points Nathan. Just a headup.

> On 14/03/23 03:10, Nathan Bossart wrote:
> On Sat, Mar 11, 2023 at 09:41:18AM +0000, Ankit Kumar Pandey wrote:
>> 1. In list_member_ptr, will it be okay to bring `const ListCell *cell` from 
>> #ifdef USE_NO_SIMD
>> 	const ListCell *cell;
>> #endif
>> to #else like as mentioned below? This will make visual separation between #if cases more cleaner
> I would expect to see -Wdeclaration-after-statement warnings if we did
> this.

This worked fine for me, no warnings on gcc 12.2.0. Not a concern though.

Thanks,

Ankit






^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
  2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 18:58     ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-11 09:41       ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
  2023-03-13 21:40         ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-15 14:01           ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
@ 2023-03-15 16:23             ` Nathan Bossart <[email protected]>
  2023-03-15 16:48               ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
  0 siblings, 1 reply; 31+ messages in thread

From: Nathan Bossart @ 2023-03-15 16:23 UTC (permalink / raw)
  To: Ankit Kumar Pandey <[email protected]>; +Cc: [email protected]

On Wed, Mar 15, 2023 at 07:31:46PM +0530, Ankit Kumar Pandey wrote:
>> On 14/03/23 03:10, Nathan Bossart wrote:
>> On Sat, Mar 11, 2023 at 09:41:18AM +0000, Ankit Kumar Pandey wrote:
>> > 1. In list_member_ptr, will it be okay to bring `const ListCell
>> > *cell` from #ifdef USE_NO_SIMD
>> > 	const ListCell *cell;
>> > #endif
>> > to #else like as mentioned below? This will make visual separation between #if cases more cleaner
>> I would expect to see -Wdeclaration-after-statement warnings if we did
>> this.
> 
> This worked fine for me, no warnings on gcc 12.2.0. Not a concern though.

Did you try building without SIMD support?  This is what I see:

	list.c: In function ‘list_member_ptr’:
	list.c:697:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
	  697 |  const ListCell *cell;
	      |  ^~~~~

If your build doesn't have USE_NO_SIMD defined, this warning won't appear
because the code in question will be compiled out.

-- 
Nathan Bossart
Amazon Web Services: https://aws.amazon.com





^ permalink  raw  reply  [nested|flat] 31+ messages in thread

* Re: optimize several list functions with SIMD intrinsics
  2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
  2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-08 18:58     ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-11 09:41       ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
  2023-03-13 21:40         ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
  2023-03-15 14:01           ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
  2023-03-15 16:23             ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
@ 2023-03-15 16:48               ` Ankit Kumar Pandey <[email protected]>
  0 siblings, 0 replies; 31+ messages in thread

From: Ankit Kumar Pandey @ 2023-03-15 16:48 UTC (permalink / raw)
  To: Nathan Bossart <[email protected]>; +Cc: [email protected]


On 15/03/23 21:53, Nathan Bossart wrote:

> Did you try building without SIMD support?  This is what I see:

>	list.c: In function ‘list_member_ptr’:
>	list.c:697:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
>	  697 |  const ListCell *cell;
>	      |  ^~~~~

> If your build doesn't have USE_NO_SIMD defined, this warning won't appear
> because the code in question will be compiled out.

My mistake, I tried with USE_NO_SIMD defined and it showed the warning. Sorry for the noise.

Regards,
Ankit






^ permalink  raw  reply  [nested|flat] 31+ messages in thread


end of thread, other threads:[~2023-03-15 16:48 UTC | newest]

Thread overview: 31+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2021-01-20 14:59 [PATCH v5 3/3] Poc: Keep page-LSN updated while WAL-skipping. Kyotaro Horiguchi <[email protected]>
2023-03-08 00:25 optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
2023-03-08 00:54 ` Re: optimize several list functions with SIMD intrinsics David Rowley <[email protected]>
2023-03-08 04:56   ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
2023-03-08 18:58     ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
2023-03-11 09:41       ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
2023-03-11 10:58         ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
2023-03-13 21:40         ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
2023-03-15 14:01           ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>
2023-03-15 16:23             ` Re: optimize several list functions with SIMD intrinsics Nathan Bossart <[email protected]>
2023-03-15 16:48               ` Re: optimize several list functions with SIMD intrinsics Ankit Kumar Pandey <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox