agora inbox for pgsql-hackers@postgresql.org  
help / color / mirror / Atom feed
[PATCH v39 2/8] Add relisivm column to pg_class system catalog
4+ messages / 2 participants
[nested] [flat]

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <nagata@sraoss.co.jp>
  0 siblings, 0 replies; 4+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v27 2/5] Save the values of the callback..
@ 2020-03-19 20:21  Justin Pryzby <pryzbyj@telsasoft.com>
  0 siblings, 0 replies; 4+ messages in thread

From: Justin Pryzby @ 2020-03-19 20:21 UTC (permalink / raw)

..allowing them to be restored later, rather than setting phase=UNKNOWN.
---
 src/backend/access/heap/vacuumlazy.c | 81 ++++++++++++++++++----------
 1 file changed, 54 insertions(+), 27 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 92bac9a24d..d923a40687 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -378,7 +378,8 @@ static LVSharedIndStats *get_indstats(LVShared *lvshared, int n);
 static bool skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared);
 static void vacuum_error_callback(void *arg);
 static void update_vacuum_error_cbarg(LVRelStats *errcbarg, int phase,
-									  BlockNumber blkno, Relation rel);
+									  BlockNumber blkno, char *indname,
+									  LVRelStats *olderrcbarg);
 
 
 /*
@@ -745,6 +746,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 	};
 	int64		initprog_val[3];
 	ErrorContextCallback errcallback;
+	LVRelStats	olderrcbarg;
 
 	pg_rusage_init(&ru0);
 
@@ -892,7 +894,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_SCAN_HEAP,
-			InvalidBlockNumber, NULL);
+			InvalidBlockNumber, NULL, &olderrcbarg);
 	errcallback.callback = vacuum_error_callback;
 	errcallback.arg = vacrelstats;
 	errcallback.previous = error_context_stack;
@@ -924,7 +926,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 		pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_SCANNED, blkno);
 
 		update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_SCAN_HEAP,
-								  blkno, NULL);
+								  blkno, NULL, &olderrcbarg);
 
 		if (blkno == next_unskippable_block)
 		{
@@ -1047,7 +1049,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 
 			/* Set the error context while continuing heap scan */
 			update_vacuum_error_cbarg(vacrelstats,
-									  VACUUM_ERRCB_PHASE_SCAN_HEAP, blkno, NULL);
+									  olderrcbarg.phase,
+									  olderrcbarg.blkno,
+									  olderrcbarg.indname,
+									  NULL);
 		}
 
 		/*
@@ -1532,8 +1537,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 
 			/* Set the error context while continuing heap scan */
 			update_vacuum_error_cbarg(vacrelstats,
-				VACUUM_ERRCB_PHASE_SCAN_HEAP, blkno, NULL);
-
+									  olderrcbarg.phase,
+									  olderrcbarg.blkno,
+									  olderrcbarg.indname,
+									  NULL);
 		}
 
 		freespace = PageGetHeapFreeSpace(page);
@@ -1817,6 +1824,7 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 	int			npages;
 	PGRUsage	ru0;
 	Buffer		vmbuffer = InvalidBuffer;
+	LVRelStats	olderrcbarg;
 
 	/* Report that we are now vacuuming the heap */
 	pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
@@ -1824,7 +1832,7 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_VACUUM_HEAP,
-							  InvalidBlockNumber, NULL);
+							  InvalidBlockNumber, NULL, &olderrcbarg);
 
 	pg_rusage_init(&ru0);
 	npages = 0;
@@ -1875,7 +1883,9 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
 							  NULL);
 }
 
@@ -1899,12 +1909,13 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 	int			uncnt = 0;
 	TransactionId visibility_cutoff_xid;
 	bool		all_frozen;
+	LVRelStats	olderrcbarg;
 
 	pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_VACUUMED, blkno);
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_VACUUM_HEAP,
-							  blkno, NULL);
+							  blkno, NULL, &olderrcbarg);
 
 	START_CRIT_SECTION();
 
@@ -1984,9 +1995,10 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
 							  NULL);
-
 	return tupindex;
 }
 
@@ -2384,6 +2396,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 	IndexVacuumInfo ivinfo;
 	const char *msg;
 	PGRUsage	ru0;
+	LVRelStats	olderrcbarg;
 
 	pg_rusage_init(&ru0);
 
@@ -2397,8 +2410,9 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_VACUUM_INDEX, InvalidBlockNumber,
-							  indrel);
+							  VACUUM_ERRCB_PHASE_VACUUM_INDEX,
+							  InvalidBlockNumber,
+							  RelationGetRelationName(indrel), &olderrcbarg);
 
 	/* Do bulk deletion */
 	*stats = index_bulk_delete(&ivinfo, *stats,
@@ -2417,7 +2431,9 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
 							  NULL);
 }
 
@@ -2435,6 +2451,7 @@ lazy_cleanup_index(Relation indrel,
 	IndexVacuumInfo ivinfo;
 	const char *msg;
 	PGRUsage	ru0;
+	LVRelStats	olderrcbarg;
 
 	pg_rusage_init(&ru0);
 
@@ -2449,7 +2466,9 @@ lazy_cleanup_index(Relation indrel,
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_INDEX_CLEANUP, InvalidBlockNumber, indrel);
+							  VACUUM_ERRCB_PHASE_INDEX_CLEANUP,
+							  InvalidBlockNumber,
+							  RelationGetRelationName(indrel), &olderrcbarg);
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
@@ -2475,7 +2494,9 @@ lazy_cleanup_index(Relation indrel,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
 							  NULL);
 }
 
@@ -3522,22 +3543,28 @@ vacuum_error_callback(void *arg)
 /* Update vacuum error callback for current phase, block and index */
 static void
 update_vacuum_error_cbarg(LVRelStats *errcbarg, int phase, BlockNumber blkno,
-						  Relation indrel)
+						  char *indname, LVRelStats *olderrcbarg)
 {
-	errcbarg->blkno = blkno;
-	errcbarg->phase = phase;
-
-	/* Free index name from any previous phase */
-	if (errcbarg->indname)
+	/* Save the values to allow resetting later */
+	if (olderrcbarg != NULL)
+		*olderrcbarg = *errcbarg;
+	else if (errcbarg->indname)
 	{
+		/*
+		 * Free index name from any previous phase, but only if we're resetting
+		 * the values to a previous state, and not if the values were saved to
+		 * restore later.  We need to avoid pfreeing a pointer that's
+		 * referenced by olderrcbarg.
+		 */
+		Assert(olderrcbarg == NULL);
 		pfree(errcbarg->indname);
 		errcbarg->indname = NULL;
 	}
 
+	errcbarg->blkno = blkno;
+	errcbarg->phase = phase;
+
 	/* For index phases, save the name of the current index for the callback */
-	if (indrel)
-	{
-		Assert(indrel->rd_rel->relkind == RELKIND_INDEX);
-		errcbarg->indname = pstrdup(RelationGetRelationName(indrel));
-	}
+	if (indname)
+		errcbarg->indname = pstrdup(indname);
 }
-- 
2.17.0


--gPQW1Pk7T/0rhUBV
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="v27-0003-Drop-reltuples.patch"



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

* [PATCH v28 2/5] Save the values of the callback..
@ 2020-03-19 20:21  Justin Pryzby <pryzbyj@telsasoft.com>
  0 siblings, 0 replies; 4+ messages in thread

From: Justin Pryzby @ 2020-03-19 20:21 UTC (permalink / raw)

..allowing them to be restored later, rather than setting phase=UNKNOWN.
---
 src/backend/access/heap/vacuumlazy.c | 74 +++++++++++++++++-----------
 1 file changed, 46 insertions(+), 28 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 768a69120b..141a50e968 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -378,7 +378,8 @@ static LVSharedIndStats *get_indstats(LVShared *lvshared, int n);
 static bool skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared);
 static void vacuum_error_callback(void *arg);
 static void update_vacuum_error_cbarg(LVRelStats *errcbarg, int phase,
-									  BlockNumber blkno, char *indname);
+									  BlockNumber blkno, char *indname,
+									  bool free_oldindname);
 
 
 /*
@@ -892,7 +893,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_SCAN_HEAP,
-			InvalidBlockNumber, NULL);
+			InvalidBlockNumber, NULL, false);
 	errcallback.callback = vacuum_error_callback;
 	errcallback.arg = vacrelstats;
 	errcallback.previous = error_context_stack;
@@ -924,7 +925,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 		pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_SCANNED, blkno);
 
 		update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_SCAN_HEAP,
-								  blkno, NULL);
+								  blkno, NULL, false);
 
 		if (blkno == next_unskippable_block)
 		{
@@ -1044,10 +1045,6 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 			/* Report that we are once again scanning the heap */
 			pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
 										 PROGRESS_VACUUM_PHASE_SCAN_HEAP);
-
-			/* Set the error context while continuing heap scan */
-			update_vacuum_error_cbarg(vacrelstats,
-									  VACUUM_ERRCB_PHASE_SCAN_HEAP, blkno, NULL);
 		}
 
 		/*
@@ -1494,10 +1491,6 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 				lazy_vacuum_page(onerel, blkno, buf, 0, vacrelstats, &vmbuffer);
 				vacuumed_pages++;
 				has_dead_tuples = false;
-
-				/* Set the error context while continuing heap scan */
-				update_vacuum_error_cbarg(vacrelstats,
-					VACUUM_ERRCB_PHASE_SCAN_HEAP, blkno, NULL);
 			}
 			else
 			{
@@ -1816,14 +1809,16 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 	int			npages;
 	PGRUsage	ru0;
 	Buffer		vmbuffer = InvalidBuffer;
+	LVRelStats	olderrcbarg;
 
 	/* Report that we are now vacuuming the heap */
 	pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
 								 PROGRESS_VACUUM_PHASE_VACUUM_HEAP);
 
 	/* Setup error traceback support for ereport() */
+	olderrcbarg = *vacrelstats;
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_VACUUM_HEAP,
-							  InvalidBlockNumber, NULL);
+							  InvalidBlockNumber, NULL, false);
 
 	pg_rusage_init(&ru0);
 	npages = 0;
@@ -1874,8 +1869,10 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
-							  NULL);
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
+							  true);
 }
 
 /*
@@ -1898,12 +1895,14 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 	int			uncnt = 0;
 	TransactionId visibility_cutoff_xid;
 	bool		all_frozen;
+	LVRelStats	olderrcbarg;
 
 	pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_VACUUMED, blkno);
 
 	/* Setup error traceback support for ereport() */
+	olderrcbarg = *vacrelstats;
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_VACUUM_HEAP,
-							  blkno, NULL);
+							  blkno, NULL, false);
 
 	START_CRIT_SECTION();
 
@@ -1983,9 +1982,10 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
-							  NULL);
-
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
+							  true);
 	return tupindex;
 }
 
@@ -2383,6 +2383,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 	IndexVacuumInfo ivinfo;
 	const char *msg;
 	PGRUsage	ru0;
+	LVRelStats	olderrcbarg;
 
 	pg_rusage_init(&ru0);
 
@@ -2395,9 +2396,12 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 	ivinfo.strategy = vac_strategy;
 
 	/* Setup error traceback support for ereport() */
+	olderrcbarg = *vacrelstats;
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_VACUUM_INDEX, InvalidBlockNumber,
-							  RelationGetRelationName(indrel));
+							  VACUUM_ERRCB_PHASE_VACUUM_INDEX,
+							  InvalidBlockNumber,
+							  RelationGetRelationName(indrel),
+							  false);
 
 	/* Do bulk deletion */
 	*stats = index_bulk_delete(&ivinfo, *stats,
@@ -2416,8 +2420,10 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
-							  NULL);
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
+							  true);
 }
 
 /*
@@ -2434,6 +2440,7 @@ lazy_cleanup_index(Relation indrel,
 	IndexVacuumInfo ivinfo;
 	const char *msg;
 	PGRUsage	ru0;
+	LVRelStats	olderrcbarg;
 
 	pg_rusage_init(&ru0);
 
@@ -2447,10 +2454,12 @@ lazy_cleanup_index(Relation indrel,
 	ivinfo.strategy = vac_strategy;
 
 	/* Setup error traceback support for ereport() */
+	olderrcbarg = *vacrelstats;
 	update_vacuum_error_cbarg(vacrelstats,
 							  VACUUM_ERRCB_PHASE_INDEX_CLEANUP,
 							  InvalidBlockNumber,
-							  RelationGetRelationName(indrel));
+							  RelationGetRelationName(indrel),
+							  false);
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
@@ -2476,8 +2485,10 @@ lazy_cleanup_index(Relation indrel,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
-							  NULL);
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
+							  true);
 }
 
 /*
@@ -3520,16 +3531,23 @@ vacuum_error_callback(void *arg)
 	}
 }
 
-/* Update vacuum error callback for current phase, block and index */
+/*
+ * Update vacuum error callback for current phase, block and index
+ *
+ * free_oldindex is true if the previous "indname" should be freed.  It must be
+ * false if the caller has copied the old LVRelSTats, to avoid keeping a
+ * pointer to a freed allocation.  In which case, the caller should call again
+ * with free_oldindname=true to avoid a leak.
+ */
 static void
 update_vacuum_error_cbarg(LVRelStats *errcbarg, int phase, BlockNumber blkno,
-						  char *indname)
+						  char *indname, bool free_oldindname)
 {
 	errcbarg->blkno = blkno;
 	errcbarg->phase = phase;
 
 	/* Free index name from any previous phase */
-	if (errcbarg->indname)
+	if (free_oldindname && errcbarg->indname)
 		pfree(errcbarg->indname);
 
 	/* For index phases, save the name of the current index for the callback */
-- 
2.17.0


--rG8Oha4Ryswg1dZ8
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="v28-0003-Drop-reltuples.patch"



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

* [PATCH v27 2/5] Save the values of the callback..
@ 2020-03-19 20:21  Justin Pryzby <pryzbyj@telsasoft.com>
  0 siblings, 0 replies; 4+ messages in thread

From: Justin Pryzby @ 2020-03-19 20:21 UTC (permalink / raw)

..allowing them to be restored later, rather than setting phase=UNKNOWN.
---
 src/backend/access/heap/vacuumlazy.c | 81 ++++++++++++++++++----------
 1 file changed, 54 insertions(+), 27 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 92bac9a24d..d923a40687 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -378,7 +378,8 @@ static LVSharedIndStats *get_indstats(LVShared *lvshared, int n);
 static bool skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared);
 static void vacuum_error_callback(void *arg);
 static void update_vacuum_error_cbarg(LVRelStats *errcbarg, int phase,
-									  BlockNumber blkno, Relation rel);
+									  BlockNumber blkno, char *indname,
+									  LVRelStats *olderrcbarg);
 
 
 /*
@@ -745,6 +746,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 	};
 	int64		initprog_val[3];
 	ErrorContextCallback errcallback;
+	LVRelStats	olderrcbarg;
 
 	pg_rusage_init(&ru0);
 
@@ -892,7 +894,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_SCAN_HEAP,
-			InvalidBlockNumber, NULL);
+			InvalidBlockNumber, NULL, &olderrcbarg);
 	errcallback.callback = vacuum_error_callback;
 	errcallback.arg = vacrelstats;
 	errcallback.previous = error_context_stack;
@@ -924,7 +926,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 		pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_SCANNED, blkno);
 
 		update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_SCAN_HEAP,
-								  blkno, NULL);
+								  blkno, NULL, &olderrcbarg);
 
 		if (blkno == next_unskippable_block)
 		{
@@ -1047,7 +1049,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 
 			/* Set the error context while continuing heap scan */
 			update_vacuum_error_cbarg(vacrelstats,
-									  VACUUM_ERRCB_PHASE_SCAN_HEAP, blkno, NULL);
+									  olderrcbarg.phase,
+									  olderrcbarg.blkno,
+									  olderrcbarg.indname,
+									  NULL);
 		}
 
 		/*
@@ -1532,8 +1537,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 
 			/* Set the error context while continuing heap scan */
 			update_vacuum_error_cbarg(vacrelstats,
-				VACUUM_ERRCB_PHASE_SCAN_HEAP, blkno, NULL);
-
+									  olderrcbarg.phase,
+									  olderrcbarg.blkno,
+									  olderrcbarg.indname,
+									  NULL);
 		}
 
 		freespace = PageGetHeapFreeSpace(page);
@@ -1817,6 +1824,7 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 	int			npages;
 	PGRUsage	ru0;
 	Buffer		vmbuffer = InvalidBuffer;
+	LVRelStats	olderrcbarg;
 
 	/* Report that we are now vacuuming the heap */
 	pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
@@ -1824,7 +1832,7 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_VACUUM_HEAP,
-							  InvalidBlockNumber, NULL);
+							  InvalidBlockNumber, NULL, &olderrcbarg);
 
 	pg_rusage_init(&ru0);
 	npages = 0;
@@ -1875,7 +1883,9 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
 							  NULL);
 }
 
@@ -1899,12 +1909,13 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 	int			uncnt = 0;
 	TransactionId visibility_cutoff_xid;
 	bool		all_frozen;
+	LVRelStats	olderrcbarg;
 
 	pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_VACUUMED, blkno);
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_VACUUM_HEAP,
-							  blkno, NULL);
+							  blkno, NULL, &olderrcbarg);
 
 	START_CRIT_SECTION();
 
@@ -1984,9 +1995,10 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
 							  NULL);
-
 	return tupindex;
 }
 
@@ -2384,6 +2396,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 	IndexVacuumInfo ivinfo;
 	const char *msg;
 	PGRUsage	ru0;
+	LVRelStats	olderrcbarg;
 
 	pg_rusage_init(&ru0);
 
@@ -2397,8 +2410,9 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_VACUUM_INDEX, InvalidBlockNumber,
-							  indrel);
+							  VACUUM_ERRCB_PHASE_VACUUM_INDEX,
+							  InvalidBlockNumber,
+							  RelationGetRelationName(indrel), &olderrcbarg);
 
 	/* Do bulk deletion */
 	*stats = index_bulk_delete(&ivinfo, *stats,
@@ -2417,7 +2431,9 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
 							  NULL);
 }
 
@@ -2435,6 +2451,7 @@ lazy_cleanup_index(Relation indrel,
 	IndexVacuumInfo ivinfo;
 	const char *msg;
 	PGRUsage	ru0;
+	LVRelStats	olderrcbarg;
 
 	pg_rusage_init(&ru0);
 
@@ -2449,7 +2466,9 @@ lazy_cleanup_index(Relation indrel,
 
 	/* Setup error traceback support for ereport() */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_INDEX_CLEANUP, InvalidBlockNumber, indrel);
+							  VACUUM_ERRCB_PHASE_INDEX_CLEANUP,
+							  InvalidBlockNumber,
+							  RelationGetRelationName(indrel), &olderrcbarg);
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
@@ -2475,7 +2494,9 @@ lazy_cleanup_index(Relation indrel,
 
 	/* Clear the error traceback phase */
 	update_vacuum_error_cbarg(vacrelstats,
-							  VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber,
+							  olderrcbarg.phase,
+							  olderrcbarg.blkno,
+							  olderrcbarg.indname,
 							  NULL);
 }
 
@@ -3522,22 +3543,28 @@ vacuum_error_callback(void *arg)
 /* Update vacuum error callback for current phase, block and index */
 static void
 update_vacuum_error_cbarg(LVRelStats *errcbarg, int phase, BlockNumber blkno,
-						  Relation indrel)
+						  char *indname, LVRelStats *olderrcbarg)
 {
-	errcbarg->blkno = blkno;
-	errcbarg->phase = phase;
-
-	/* Free index name from any previous phase */
-	if (errcbarg->indname)
+	/* Save the values to allow resetting later */
+	if (olderrcbarg != NULL)
+		*olderrcbarg = *errcbarg;
+	else if (errcbarg->indname)
 	{
+		/*
+		 * Free index name from any previous phase, but only if we're resetting
+		 * the values to a previous state, and not if the values were saved to
+		 * restore later.  We need to avoid pfreeing a pointer that's
+		 * referenced by olderrcbarg.
+		 */
+		Assert(olderrcbarg == NULL);
 		pfree(errcbarg->indname);
 		errcbarg->indname = NULL;
 	}
 
+	errcbarg->blkno = blkno;
+	errcbarg->phase = phase;
+
 	/* For index phases, save the name of the current index for the callback */
-	if (indrel)
-	{
-		Assert(indrel->rd_rel->relkind == RELKIND_INDEX);
-		errcbarg->indname = pstrdup(RelationGetRelationName(indrel));
-	}
+	if (indname)
+		errcbarg->indname = pstrdup(indname);
 }
-- 
2.17.0


--gPQW1Pk7T/0rhUBV
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="v27-0003-Drop-reltuples.patch"



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


end of thread, other threads:[~2020-03-19 20:21 UTC | newest]

Thread overview: 4+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <nagata@sraoss.co.jp>
2020-03-19 20:21 [PATCH v27 2/5] Save the values of the callback.. Justin Pryzby <pryzbyj@telsasoft.com>
2020-03-19 20:21 [PATCH v28 2/5] Save the values of the callback.. Justin Pryzby <pryzbyj@telsasoft.com>
2020-03-19 20:21 [PATCH v27 2/5] Save the values of the callback.. Justin Pryzby <pryzbyj@telsasoft.com>

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