aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-03-18 17:49:06 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2017-03-18 17:49:39 -0400
commit17f8ffa1e331cd0d95a3c4ccec66ea83d8b893c5 (patch)
tree8a027451104c4fa8504a8ccffe21af7148a507c0
parent27f1f585fd7ee749cacd3de8c2c77a457ef4c288 (diff)
downloadpostgresql-17f8ffa1e331cd0d95a3c4ccec66ea83d8b893c5.tar.gz
postgresql-17f8ffa1e331cd0d95a3c4ccec66ea83d8b893c5.zip
Fix REFRESH MATERIALIZED VIEW to report activity to the stats collector.
The non-concurrent code path for REFRESH MATERIALIZED VIEW failed to report its updates to the stats collector. This is bad since it means auto-analyze doesn't know there's any work to be done. Adjust it to report the refresh as a table truncate followed by insertion of an appropriate number of rows. Since a matview could contain more than INT_MAX rows, change the signature of pgstat_count_heap_insert() to accept an int64 rowcount. (The accumulator it's adding into is already int64, but existing callers could not insert more than a small number of rows at once, so the argument had been declared just "int n".) This is surely a bug fix, but changing pgstat_count_heap_insert()'s API seems too risky for the back branches. Given the lack of previous complaints, I'm not sure it's a big enough problem to justify a kluge solution that would avoid that. So, no back-patch, at least for now. Jim Mlodgenski, adjusted a bit by me Discussion: https://postgr.es/m/CAB_5SRchSz7-WmdO5szdiknG8Oj_GGqJytrk1KRd11yhcMs1KQ@mail.gmail.com
-rw-r--r--src/backend/commands/matview.c30
-rw-r--r--src/backend/postmaster/pgstat.c2
-rw-r--r--src/include/pgstat.h2
3 files changed, 29 insertions, 5 deletions
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index a18c9173360..c952dea6ead 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -30,6 +30,7 @@
#include "executor/spi.h"
#include "miscadmin.h"
#include "parser/parse_relation.h"
+#include "pgstat.h"
#include "rewrite/rewriteHandler.h"
#include "storage/lmgr.h"
#include "storage/smgr.h"
@@ -59,7 +60,7 @@ static void transientrel_startup(DestReceiver *self, int operation, TupleDesc ty
static bool transientrel_receive(TupleTableSlot *slot, DestReceiver *self);
static void transientrel_shutdown(DestReceiver *self);
static void transientrel_destroy(DestReceiver *self);
-static void refresh_matview_datafill(DestReceiver *dest, Query *query,
+static uint64 refresh_matview_datafill(DestReceiver *dest, Query *query,
const char *queryString);
static char *make_temptable_name_n(char *tempname, int n);
@@ -145,6 +146,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
Oid relowner;
Oid OIDNewHeap;
DestReceiver *dest;
+ uint64 processed = 0;
bool concurrent;
LOCKMODE lockmode;
char relpersistence;
@@ -322,7 +324,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
/* Generate the data, if wanted. */
if (!stmt->skipData)
- refresh_matview_datafill(dest, dataQuery, queryString);
+ processed = refresh_matview_datafill(dest, dataQuery, queryString);
heap_close(matviewRel, NoLock);
@@ -345,8 +347,20 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
Assert(matview_maintenance_depth == old_depth);
}
else
+ {
refresh_by_heap_swap(matviewOid, OIDNewHeap, relpersistence);
+ /*
+ * Inform stats collector about our activity: basically, we truncated
+ * the matview and inserted some new data. (The concurrent code path
+ * above doesn't need to worry about this because the inserts and
+ * deletes it issues get counted by lower-level code.)
+ */
+ pgstat_count_truncate(matviewRel);
+ if (!stmt->skipData)
+ pgstat_count_heap_insert(matviewRel, processed);
+ }
+
/* Roll back any GUC changes */
AtEOXact_GUC(false, save_nestlevel);
@@ -360,8 +374,13 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
/*
* refresh_matview_datafill
+ *
+ * Execute the given query, sending result rows to "dest" (which will
+ * insert them into the target matview).
+ *
+ * Returns number of rows inserted.
*/
-static void
+static uint64
refresh_matview_datafill(DestReceiver *dest, Query *query,
const char *queryString)
{
@@ -369,6 +388,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
PlannedStmt *plan;
QueryDesc *queryDesc;
Query *copied_query;
+ uint64 processed;
/* Lock and rewrite, using a copy to preserve the original query. */
copied_query = copyObject(query);
@@ -406,6 +426,8 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
/* run the plan */
ExecutorRun(queryDesc, ForwardScanDirection, 0L);
+ processed = queryDesc->estate->es_processed;
+
/* and clean up */
ExecutorFinish(queryDesc);
ExecutorEnd(queryDesc);
@@ -413,6 +435,8 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
FreeQueryDesc(queryDesc);
PopActiveSnapshot();
+
+ return processed;
}
DestReceiver *
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 5fe9f35199a..3a50488db32 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -1803,7 +1803,7 @@ add_tabstat_xact_level(PgStat_TableStatus *pgstat_info, int nest_level)
* pgstat_count_heap_insert - count a tuple insertion of n tuples
*/
void
-pgstat_count_heap_insert(Relation rel, int n)
+pgstat_count_heap_insert(Relation rel, PgStat_Counter n)
{
PgStat_TableStatus *pgstat_info = rel->pgstat_info;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9d2e1fe19f4..f2daf32e1ab 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -1256,7 +1256,7 @@ pgstat_report_wait_end(void)
#define pgstat_count_buffer_write_time(n) \
(pgStatBlockWriteTime += (n))
-extern void pgstat_count_heap_insert(Relation rel, int n);
+extern void pgstat_count_heap_insert(Relation rel, PgStat_Counter n);
extern void pgstat_count_heap_update(Relation rel, bool hot);
extern void pgstat_count_heap_delete(Relation rel);
extern void pgstat_count_truncate(Relation rel);