Skip to content

Commit

Permalink
Maintain materialized view data status.
Browse files Browse the repository at this point in the history
A materialized view's data could be seen as up to date with
base tables if there are no writable operations since last
Refresh of the view.

If one of base tables in the query tree of a materailied view is
modified, the view data is not up to date. And we could not use
it to answer query.

This commit maintain the data satus of a materialized view and
it applies to normal materialized view, IVM with defer refresh.
IVM with immediately refresh is always up to date.

When a base table has writable operation, we try
to update view data status as:

- 'u'(up to date):
  Create Materialized View
  Refresh

- 'e'(expired):
  Update base tables
  Delete base tables
  Refresh With No Data
  Truncate base tables
  Create Materialized View With No Data

- 'i'(insert only):
  Insert info base tables
  Copy From
  Copy From on Segments

- 'r'(up to date but reorganized):
  Cluster base tables
  Vacuum Full base tables

Insert, Update, Delete, Copy From operations take effect if the
actual affected rows > 0, ex:
  insert into t1 select * from t2;
We don't need to update view if t2 has zero rows.

The real status will be decided both by current and the status we
try to mark as.Ex: we try to mark insert only on a expired status,
it will not success.

This doesn't work on utility mode, if user modified data in that
mode, should refresh views if want to use it to answer query.

AQUMV could use normal materialized views after this commit.

Authored-by: Zhang Mingli avamingli@gmail.com
  • Loading branch information
avamingli committed Jul 10, 2024
1 parent 472db76 commit d058070
Show file tree
Hide file tree
Showing 34 changed files with 1,700 additions and 12 deletions.
8 changes: 8 additions & 0 deletions gpMgmt/bin/gpcheckcat
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,10 @@ def checkTableMissingEntry(cat):
if catname == "gp_segment_configuration":
return

# Skip gp_matview_aux or gp_matview_tables
if catname == "gp_matview_aux" or catname == "gp_matview_tables":
return

# skip shared/non-shared tables
if GV.opt['-S']:
if re.match("none", GV.opt['-S'], re.I) and isShared:
Expand Down Expand Up @@ -1533,6 +1537,10 @@ def checkTableInconsistentEntry(cat):
if catname == "gp_segment_configuration" or catname == "pg_appendonly":
return

# Skip gp_matview_aux or gp_matview_tables
if catname == "gp_matview_aux" or catname == "gp_matview_tables":
return

# skip shared/non-shared tables
if GV.opt['-S']:
if re.match("none", GV.opt['-S'], re.I) and isShared:
Expand Down
4 changes: 3 additions & 1 deletion gpMgmt/bin/gppylib/gpcatalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ class GPCatalogException(Exception):
'pg_statistic_ext',
'pg_statistic_ext_data',
'gp_partition_template', # GPDB_12_MERGE_FIXME: is gp_partition_template intentionally missing from segments?
'pg_event_trigger'
'pg_event_trigger',
'gp_matview_aux',
'gp_matview_tables',
]

# Hard coded tables that have different values on every segment
Expand Down
3 changes: 3 additions & 0 deletions src/backend/catalog/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ OBJS += pg_extprotocol.o \
oid_dispatch.o aocatalog.o storage_tablespace.o storage_database.o \
storage_tablespace_twophase.o storage_tablespace_xact.o \
gp_partition_template.o pg_task.o pg_task_run_history.o \
gp_matview_aux.o \
pg_directory_table.o storage_directory_table.o

CATALOG_JSON:= $(addprefix $(top_srcdir)/gpMgmt/bin/gppylib/data/, $(addsuffix .json,$(GP_MAJORVERSION)))
Expand Down Expand Up @@ -94,6 +95,8 @@ CATALOG_HEADERS := \
pg_sequence.h pg_publication.h pg_publication_rel.h pg_subscription.h \
pg_subscription_rel.h gp_partition_template.h pg_task.h pg_task_run_history.h \
pg_profile.h pg_password_history.h pg_directory_table.h gp_storage_server.h \
gp_matview_aux.h \
gp_matview_tables.h \
gp_storage_user_mapping.h

USE_INTERNAL_FTS_FOUND := $(if $(findstring USE_INTERNAL_FTS,$(CFLAGS)),true,false)
Expand Down
12 changes: 12 additions & 0 deletions src/backend/catalog/catalog.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
#include "catalog/pg_stat_last_shoperation.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_trigger.h"
#include "catalog/gp_matview_aux.h"
#include "catalog/gp_matview_tables.h"
#include "cdb/cdbvars.h"

#include "catalog/gp_indexing.h"
Expand Down Expand Up @@ -551,6 +553,16 @@ IsSharedRelation(Oid relationId)
return true;
}

/* materialized view aux and its indexes */
if (relationId == GpMatviewAuxId ||
relationId == GpMatviewAuxMvoidIndexId ||
relationId == GpMatviewAuxMvnameIndexId ||
relationId == GpMatviewAuxDatastatusIndexId ||
relationId == GpMatviewTablesId ||
relationId == GpMatviewTablesMvRelIndexId ||
relationId == GpMatviewTablesRelIndexId)
return true;

/* warehouse table and its indexes */
if (relationId == GpWarehouseRelationId ||
relationId == GpWarehouseOidIndexId ||
Expand Down
11 changes: 10 additions & 1 deletion src/backend/catalog/dependency.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
#include "catalog/pg_profile.h"
#include "catalog/pg_password_history.h"
#include "commands/tablecmds.h"
#include "catalog/gp_matview_aux.h"


/*
Expand Down Expand Up @@ -209,7 +210,8 @@ static const Oid object_classes[] = {
StorageServerRelationId, /* OCLASS_STORAGE_SERVER */
StorageUserMappingRelationId, /* OCLASS_STORAGE_USER_MAPPING */
ExtprotocolRelationId, /* OCLASS_EXTPROTOCOL */
TaskRelationId /* OCLASS_TASK */
GpMatviewAuxId, /* OCLASS_MATVIEW_AUX */
TaskRelationId, /* OCLASS_TASK */
};


Expand Down Expand Up @@ -1554,6 +1556,10 @@ doDeletion(const ObjectAddress *object, int flags)
RemoveTaskById(object->objectId);
break;

case OCLASS_MATVIEW_AUX:
RemoveMatviewAuxEntry(object->objectId);
break;

case OCLASS_CAST:
case OCLASS_COLLATION:
case OCLASS_CONVERSION:
Expand Down Expand Up @@ -2978,6 +2984,9 @@ getObjectClass(const ObjectAddress *object)
case TaskRelationId:
return OCLASS_TASK;

case GpMatviewAuxId:
return OCLASS_MATVIEW_AUX;

case DirectoryTableRelationId:
return OCLASS_DIRTABLE;

Expand Down
Loading

0 comments on commit d058070

Please sign in to comment.