From 0c320b5af1f508a5b9512a69701085f423b92245 Mon Sep 17 00:00:00 2001 From: George Caragea Date: Tue, 12 Jan 2016 11:33:36 -0800 Subject: [PATCH 1/3] [HAWQ-333] Remove Metadata Versioning code --- GNUmakefile.in | 4 - contrib/Makefile | 1 - contrib/gp_mdver/.gitignore | 1 - contrib/gp_mdver/Makefile | 15 - contrib/gp_mdver/gp_mdver_contents.c | 139 ------- contrib/gp_mdver/gp_mdver_utils.sql.in | 41 --- contrib/gp_mdver/uninstall_gp_mdver_utils.sql | 10 - src/backend/gpopt/gpdbwrappers.cpp | 20 -- .../gpopt/translate/CTranslatorUtils.cpp | 16 +- src/backend/storage/ipc/ipci.c | 18 - src/backend/storage/ipc/sinvaladt.c | 8 - src/backend/tcop/utility.c | 7 - src/backend/utils/Makefile | 2 +- src/backend/utils/cache/catcache.c | 4 - src/backend/utils/cache/inval.c | 248 ------------- src/backend/utils/mdver/Makefile | 18 - .../utils/mdver/mdver_dep_translator.c | 184 ---------- .../utils/mdver/mdver_global_handler.c | 254 ------------- src/backend/utils/mdver/mdver_global_mdvsn.c | 235 ------------ src/backend/utils/mdver/mdver_local_handler.c | 200 ----------- src/backend/utils/mdver/mdver_local_mdvsn.c | 249 ------------- src/backend/utils/mdver/mdver_utils.c | 339 ------------------ src/backend/utils/mdver/test/.gitignore | 1 - src/backend/utils/mdver/test/Makefile | 38 -- .../mdver/test/mdver_dep_translator_test.c | 106 ------ src/include/gpopt/utils/gpdbdefs.h | 1 - src/include/storage/sinval.h | 22 -- src/include/utils/inval.h | 3 - src/include/utils/mdver.h | 104 ------ 29 files changed, 6 insertions(+), 2282 deletions(-) delete mode 100644 contrib/gp_mdver/.gitignore delete mode 100644 contrib/gp_mdver/Makefile delete mode 100644 contrib/gp_mdver/gp_mdver_contents.c delete mode 100644 contrib/gp_mdver/gp_mdver_utils.sql.in delete mode 100644 contrib/gp_mdver/uninstall_gp_mdver_utils.sql delete mode 100644 src/backend/utils/mdver/Makefile delete mode 100644 src/backend/utils/mdver/mdver_dep_translator.c delete mode 100644 src/backend/utils/mdver/mdver_global_handler.c delete mode 100644 src/backend/utils/mdver/mdver_global_mdvsn.c delete mode 100644 src/backend/utils/mdver/mdver_local_handler.c delete mode 100644 src/backend/utils/mdver/mdver_local_mdvsn.c delete mode 100644 src/backend/utils/mdver/mdver_utils.c delete mode 100644 src/backend/utils/mdver/test/.gitignore delete mode 100644 src/backend/utils/mdver/test/Makefile delete mode 100644 src/backend/utils/mdver/test/mdver_dep_translator_test.c delete mode 100644 src/include/utils/mdver.h diff --git a/GNUmakefile.in b/GNUmakefile.in index a329495c0f..40e887b325 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -18,7 +18,6 @@ all: $(MAKE) -C contrib/orafce all $(MAKE) -C contrib/gp_cancel_query all $(MAKE) -C contrib/hawq-hadoop all - $(MAKE) -C contrib/gp_mdver all $(MAKE) -C tools all @echo "All of HAWQ successfully made. Ready to install." @@ -32,7 +31,6 @@ install: $(MAKE) -C contrib/orafce $@ $(MAKE) -C contrib/gp_cancel_query $@ $(MAKE) -C contrib/hawq-hadoop $@ - $(MAKE) -C contrib/gp_mdver $@ $(MAKE) -C tools $@ @echo "HAWQ installation complete." @@ -46,7 +44,6 @@ installdirs uninstall: $(MAKE) -C contrib/orafce $@ $(MAKE) -C contrib/gp_cancel_query $@ $(MAKE) -C contrib/hawq-hadoop $@ - $(MAKE) -C contrib/gp_mdver $@ distprep: # $(MAKE) -C doc $@ @@ -67,7 +64,6 @@ clean: $(MAKE) -C contrib/orafce $@ $(MAKE) -C contrib/gp_cancel_query $@ $(MAKE) -C contrib/hawq-hadoop $@ - $(MAKE) -C contrib/gp_mdver $@ $(MAKE) -C tools $@ # Garbage from autoconf: @rm -rf autom4te.cache/ diff --git a/contrib/Makefile b/contrib/Makefile index eb622f41a3..92df3922f8 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -8,7 +8,6 @@ WANTED_DIRS = \ orafce \ extprotocol \ gp_cancel_query \ - gp_mdver \ hawq-hadoop # Missing: diff --git a/contrib/gp_mdver/.gitignore b/contrib/gp_mdver/.gitignore deleted file mode 100644 index 5d653f59a7..0000000000 --- a/contrib/gp_mdver/.gitignore +++ /dev/null @@ -1 +0,0 @@ -gp_mdver_utils.sql diff --git a/contrib/gp_mdver/Makefile b/contrib/gp_mdver/Makefile deleted file mode 100644 index 0b568393bb..0000000000 --- a/contrib/gp_mdver/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -MODULE_big = gp_mdver_utils -OBJS = gp_mdver_contents.o - -DATA_built = gp_mdver_utils.sql -DATA = uninstall_gp_mdver_utils.sql - -ifdef USE_PGXS -PGXS := $(shell pg_config --pgxs) -include $(PGXS) -else -subdir = contrib/gp_mdver -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global -include $(top_srcdir)/contrib/contrib-global.mk -endif diff --git a/contrib/gp_mdver/gp_mdver_contents.c b/contrib/gp_mdver/gp_mdver_contents.c deleted file mode 100644 index 59a2ddff83..0000000000 --- a/contrib/gp_mdver/gp_mdver_contents.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* - * The dynamically linked library created from this source can be reference by - * creating a function in psql that references it. For example, - * - * CREATE OR REPLACE FUNCTION gp_mdver_cache_entries() - * RETURNS RECORD - * AS '$libdir/gp_mdver.so', 'gp_mdver_cache_entries' - * LANGUAGE C; - * - */ - -#include "postgres.h" -#include "funcapi.h" -#include "utils/mdver.h" - -#ifdef PG_MODULE_MAGIC -PG_MODULE_MAGIC; -#endif - -/* Forward declarations */ -Datum gp_mdver_cache_entries(PG_FUNCTION_ARGS); - -/* Shared library Postgres module magic */ -PG_FUNCTION_INFO_V1(gp_mdver_cache_entries); - -/* Number of columns in the tuple holding a mdver entry */ -#define NUM_MDVER_ENTRIES_COL 3 - -/* - * Function returning all workfile cache entries for one segment - */ -Datum -gp_mdver_cache_entries(PG_FUNCTION_ARGS) -{ - FuncCallContext *funcctx = NULL; - int32 *crtIndexPtr = NULL; - - if (SRF_IS_FIRSTCALL()) - { - /* create a function context for cross-call persistence */ - funcctx = SRF_FIRSTCALL_INIT(); - - /* Switch to memory context appropriate for multiple function calls */ - MemoryContext oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - - /* - * Build a tuple descriptor for our result type - * The number and type of attributes have to match the definition of the - * view gp_mdver_cache_entries - */ - TupleDesc tupdesc = CreateTemplateTupleDesc(NUM_MDVER_ENTRIES_COL, false); - - TupleDescInitEntry(tupdesc, (AttrNumber) 1, "oid", - OIDOID, -1 /* typmod */, 0 /* attdim */); - TupleDescInitEntry(tupdesc, (AttrNumber) 2, "ddl_version", - INT8OID, -1 /* typmod */, 0 /* attdim */); - TupleDescInitEntry(tupdesc, (AttrNumber) 3, "dml_version", - INT8OID, -1 /* typmod */, 0 /* attdim */); - - Assert(NUM_MDVER_ENTRIES_COL == 3); - - funcctx->tuple_desc = BlessTupleDesc(tupdesc); - - crtIndexPtr = (int32 *) palloc(sizeof(*crtIndexPtr)); - *crtIndexPtr = 0; - funcctx->user_fctx = crtIndexPtr; - MemoryContextSwitchTo(oldcontext); - - } - - Cache *cache = mdver_get_glob_mdvsn(); - funcctx = SRF_PERCALL_SETUP(); - crtIndexPtr = (int32 *) funcctx->user_fctx; - - - while (true) - { - - CacheEntry *crtEntry = Cache_NextEntryToList(cache, crtIndexPtr); - - if (!crtEntry) - { - /* Reached the end of the entry array, we're done */ - SRF_RETURN_DONE(funcctx); - } - - Datum values[NUM_MDVER_ENTRIES_COL]; - bool nulls[NUM_MDVER_ENTRIES_COL]; - MemSet(nulls, 0, sizeof(nulls)); - - mdver_entry *mdver = CACHE_ENTRY_PAYLOAD(crtEntry); - - /* - * Lock entry in order to read its payload - * Don't call any functions that can get interrupted or - * that palloc memory while holding this lock. - */ - Cache_LockEntry(cache, crtEntry); - - if (!Cache_ShouldListEntry(crtEntry)) - { - Cache_UnlockEntry(cache, crtEntry); - continue; - } - - values[0] = ObjectIdGetDatum(mdver->key); - values[1] = UInt64GetDatum(mdver->ddl_version); - values[2] = UInt64GetDatum(mdver->dml_version); - - /* Done reading from the payload of the entry, release lock */ - Cache_UnlockEntry(cache, crtEntry); - - HeapTuple tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); - Datum result = HeapTupleGetDatum(tuple); - SRF_RETURN_NEXT(funcctx, result); - } -} - - -/* EOF */ diff --git a/contrib/gp_mdver/gp_mdver_utils.sql.in b/contrib/gp_mdver/gp_mdver_utils.sql.in deleted file mode 100644 index 4731906385..0000000000 --- a/contrib/gp_mdver/gp_mdver_utils.sql.in +++ /dev/null @@ -1,41 +0,0 @@ -CREATE SCHEMA mdver_utils; -SET search_path = mdver_utils; - -BEGIN; - --- Register the functions and views. - --------------------------------------------------------------------------------- --- @function: --- mdver_utils.__gp_mdver_cache_entries_f() --- --- @in: --- --- @out: --- oid - Oid of versioned object --- bigint - ddl version --- bigint - dml version --------------------------------------------------------------------------------- - -CREATE FUNCTION mdver_utils.__gp_mdver_cache_entries_f() - RETURNS RECORD - AS 'MODULE_PATHNAME', 'gp_mdver_cache_entries' LANGUAGE C; - --------------------------------------------------------------------------------- --- @view: --- mdver_utils.gp_mdver_cache_entries --- --- @doc: --- List of all the objects in the Global MDVSN cache and their version --- --------------------------------------------------------------------------------- - -CREATE VIEW mdver_utils.gp_mdver_cache_entries AS -SELECT C.* - FROM mdver_utils.__gp_mdver_cache_entries_f() AS C ( - oid oid, - ddlversion bigint, - dmlversion bigint - ); - -COMMIT; diff --git a/contrib/gp_mdver/uninstall_gp_mdver_utils.sql b/contrib/gp_mdver/uninstall_gp_mdver_utils.sql deleted file mode 100644 index be695b62f1..0000000000 --- a/contrib/gp_mdver/uninstall_gp_mdver_utils.sql +++ /dev/null @@ -1,10 +0,0 @@ -SET search_path = mdver_utils; - -BEGIN; - -DROP VIEW mdver_utils.gp_mdver_cache_entries; -DROP FUNCTION mdver_utils.__gp_mdver_cache_entries_f(); - -DROP SCHEMA mdver_utils; - -COMMIT; diff --git a/src/backend/gpopt/gpdbwrappers.cpp b/src/backend/gpopt/gpdbwrappers.cpp index 8be3fd74a9..7d72823902 100644 --- a/src/backend/gpopt/gpdbwrappers.cpp +++ b/src/backend/gpopt/gpdbwrappers.cpp @@ -215,10 +215,6 @@ #define ALLOW_GetActiveRelType #define ALLOW_GetActiveQueryResource -#define ALLOW_mdver_request_version -#define ALLOW_mdver_enabled - - #include "gpopt/utils/gpdbdefs.h" #include "gpos/base.h" @@ -3115,20 +3111,4 @@ gpdb::UlLeafPartitions return 0; } -void -gpdb::MdVerRequestVersion - ( - Oid key, - uint64 *ddl_version, - uint64 *dml_version - ) -{ - GP_WRAP_START; - { - mdver_request_version(key, ddl_version, dml_version); - return; - } - GP_WRAP_END; -} - // EOF diff --git a/src/backend/gpopt/translate/CTranslatorUtils.cpp b/src/backend/gpopt/translate/CTranslatorUtils.cpp index 30f00a8563..4c474552b4 100644 --- a/src/backend/gpopt/translate/CTranslatorUtils.cpp +++ b/src/backend/gpopt/translate/CTranslatorUtils.cpp @@ -40,7 +40,6 @@ #include "catalog/pg_trigger.h" #include "optimizer/walkers.h" #include "utils/rel.h" -#include "utils/mdver.h" #define GPDB_NEXTVAL 1574 #define GPDB_CURRVAL 1575 @@ -345,8 +344,8 @@ CTranslatorUtils::PmdidWithVersion OID oidObj ) { - ULLONG ullDDLv = INVALID_MD_VERSION; - ULLONG ullDMLv = INVALID_MD_VERSION; + ULONG ullDDLv = 0; + ULONG ullDMLv = 0; if (InvalidOid == oidObj) { @@ -354,21 +353,16 @@ CTranslatorUtils::PmdidWithVersion ullDDLv = 0; ullDMLv = 0; } - else if (FBuiltinObject(oidObj)) + else { /* - * Built-in types, functions etc get default value 1.0 + * All valid objects get 1.0 as the version */ ullDDLv = 1; ullDMLv = 0; } - else - { - gpdb::MdVerRequestVersion(oidObj, &ullDDLv, &ullDMLv); - } - // TODO: gcaragea - Feb 6, 2015; Refactor CMDIdGPDB to eliminate need for casting - return GPOS_NEW(pmp) CMDIdGPDB(oidObj, (ULONG) ullDDLv, (ULONG) ullDMLv); + return GPOS_NEW(pmp) CMDIdGPDB(oidObj, ullDDLv, ullDMLv); } diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 5cea686b0f..de8e72068b 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -63,7 +63,6 @@ #include "executor/spi.h" #include "utils/workfile_mgr.h" #include "cdb/cdbmetadatacache.h" -#include "utils/mdver.h" #include "utils/session_state.h" shmem_startup_hook_type shmem_startup_hook = NULL; @@ -139,15 +138,6 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) size = add_size(size, AppendOnlyWriterShmemSize()); } - /* - * On the master and standby master, we also allocate the - * Global Metadata Versioning shared cache - */ - if (AmIMaster()||AmIStandby()) - { - size = add_size(size, mdver_shmem_size()); - } - size = add_size(size, ProcGlobalShmemSize()); size = add_size(size, XLOGShmemSize()); size = add_size(size, CLOGShmemSize()); @@ -371,14 +361,6 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) workfile_mgr_cache_init(); FSCredShmemInit(); - /* - * On the master and standby master, we also allocate the - * Global Metadata Versioning shared cache - */ - if (AmIMaster() || AmIStandby()) - { - mdver_shmem_init(); - } #ifdef EXEC_BACKEND diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c index f9040d4dbc..28cf6c3503 100644 --- a/src/backend/storage/ipc/sinvaladt.c +++ b/src/backend/storage/ipc/sinvaladt.c @@ -367,14 +367,6 @@ SIInsertDataEntries(SharedInvalidationMessage *data, int n) * SICleanupQueue every so often. */ - /* - * Pass messages through the MD Global VE Handler component - * TODO gcaragea 3/28/2014: Figure out locking once we start doing cache - * look-ups for reconciliation (MPP-22928) - * - */ - mdver_globalhandler_new_event(data, n); - while (n > 0) { int nthistime = Min(n, WRITE_QUANTUM); diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 88999208e5..ae42d6c6be 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -50,7 +50,6 @@ #include "commands/user.h" #include "commands/vacuum.h" #include "commands/view.h" -#include "utils/mdver.h" #include "miscadmin.h" #include "postmaster/checkpoint.h" #include "rewrite/rewriteDefine.h" @@ -833,12 +832,6 @@ ProcessUtility(Node *parsetree, RequireTransactionChain((void *) stmt, "SAVEPOINT"); - /* TODO gcaragea 3/4/2015: Remove this check when support for subtransactions is added to Metadata Versioning */ - if (mdver_enabled()) - { - elog(ERROR, "Subtransactions are not supported when metadata versioning is enabled"); - } - foreach(cell, stmt->options) { DefElem *elem = lfirst(cell); diff --git a/src/backend/utils/Makefile b/src/backend/utils/Makefile index 35b8407961..da8a82e25f 100644 --- a/src/backend/utils/Makefile +++ b/src/backend/utils/Makefile @@ -10,7 +10,7 @@ include $(top_builddir)/src/Makefile.global OBJS = fmgrtab.o session_state.o SUBDIRS = adt cache error fmgr hash init mb misc mmgr resowner \ - resscheduler sort time gpmon gp workfile_manager mdver + resscheduler sort time gpmon gp workfile_manager include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 004c9feeb7..286fafbd8d 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -34,7 +34,6 @@ #include "utils/rel.h" #include "utils/resowner.h" #include "utils/syscache.h" -#include "utils/mdver.h" #include "utils/guc.h" /* #define CACHEDEBUG */ /* turns DEBUG elogs on */ @@ -1680,9 +1679,6 @@ PrepareToInvalidateCacheTuple(Relation relation, reloid = RelationGetRelid(relation); - /* Add corresponding Metadata versioning events for this action */ - mdver_dt_catcache_inval(relation, tuple, action); - /* ---------------- * for each cache * if the cache contains tuples from the specified relation diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index f5b7d141e4..1e330c391f 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -94,7 +94,6 @@ #include "storage/sinval.h" #include "storage/smgr.h" #include "utils/inval.h" -#include "utils/mdver.h" #include "utils/memutils.h" #include "utils/relcache.h" #include "utils/simex.h" @@ -167,9 +166,6 @@ typedef struct TransInvalidationInfo /* init file must be invalidated? */ bool RelcacheInitFileInval; - /* Metadata Versioning: Local Metadata Version cache/hashtable */ - mdver_local_mdvsn *local_mdvsn; - } TransInvalidationInfo; /* @@ -201,9 +197,6 @@ static int cache_callback_count = 0; static void PersistInvalidationMessage(SharedInvalidationMessage *msg); static void PrepareForRelcacheInvalidation(Oid relid, HeapTuple tuple); -static bool MdVer_IsRedundantNukeEvent(InvalidationListHeader *hdr, mdver_event *mdev); -static void MdVer_PreProcessInvalidMsgs(InvalidationListHeader *dest, - InvalidationListHeader *src); /* ---------------------------------------------------------------- * Invalidation list support functions * @@ -375,68 +368,6 @@ AddCatcacheInvalidationMessage(InvalidationListHeader *hdr, #endif } -/* - * Add a Metadata Versioning versioning event entry to a message list - * hdr: The list to be added to - * mdev: The event to be added - */ -static void -AddVersioningEventMessage(InvalidationListHeader *hdr, mdver_event *mdev) -{ - Assert(NULL != hdr); - Assert(NULL != mdev); - - /* Check for last event in the queue. If we're trying to add a nuke, and it's already nuke, skip it */ - if (MdVer_IsRedundantNukeEvent(hdr, mdev)) - { - return; - } - - SharedInvalidationMessage msg; - msg.ve.id = SHAREDVERSIONINGMSG_ID; - msg.ve.local = true; - msg.ve.verEvent = *mdev; - AddInvalidationMessage(&hdr->velist, &msg); -} - -/* - * Detect if adding a Metadata Versioning Nuke event to the event list is redundant. - * A Nuke message is redundant if the last message in the list is already a Nuke. - */ -static bool -MdVer_IsRedundantNukeEvent(InvalidationListHeader *hdr, mdver_event *mdev) -{ - Assert(NULL != hdr); - Assert(NULL != mdev); - - if (!mdver_is_nuke_event(mdev)) { - return false; - } - - InvalidationChunk *chunk = hdr->velist; - if (NULL == chunk) - { - /* Destination is empty */ - return false; - } - - /* Find last chunk of destination list */ - while (chunk->next != NULL) - { - chunk = chunk->next; - } - - /* Get the last event from the last chunk. Then check if it's a NUKE */ - SharedInvalidationMessage *last_message = &chunk->msgs[chunk->nitems - 1]; - Assert(last_message->id == SHAREDVERSIONINGMSG_ID); - mdver_event *last_event = &(last_message->ve.verEvent); - if (mdver_is_nuke_event(last_event)) { - return true; - } - - return false; -} - /* * Add a relcache inval entry */ @@ -691,10 +622,6 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg) smgrclosenode(msg->sm.rnode); break; - case SHAREDVERSIONINGMSG_ID: - mdver_localhandler_new_event(msg); - break; - default: #ifdef USE_ASSERT_CHECKING elog(NOTICE, "invalid SI message: %s", si_to_str(msg)); @@ -722,12 +649,6 @@ InvalidateSystemCaches(void) ResetCatalogCaches(); RelationCacheInvalidate(); /* gets smgr cache too */ - mdver_local_mdvsn *local_mdvsn = GetCurrentLocalMDVSN(); - if (NULL != local_mdvsn && mdver_enabled()) - { - mdver_local_mdvsn_nuke(local_mdvsn); - } - for (i = 0; i < cache_callback_count; i++) { struct CACHECALLBACK *ccitem = cache_callback_list + i; @@ -971,16 +892,6 @@ AtStart_Inval(void) sizeof(TransInvalidationInfo)); transInvalInfo->my_level = GetCurrentTransactionNestLevel(); - if (mdver_enabled()) - { - /* - * Since we create the TransInvalidationInfo in the TopTransactionContext, - * we should create the local mdvsn in the same context as well. - */ - MemoryContext oldcxt = MemoryContextSwitchTo(TopTransactionContext); - transInvalInfo->local_mdvsn = mdver_create_local_mdvsn(transInvalInfo->my_level); - MemoryContextSwitchTo(oldcxt); - } } /* @@ -1049,17 +960,6 @@ AtSubStart_Inval(void) myInfo->parent = transInvalInfo; myInfo->my_level = GetCurrentTransactionNestLevel(); - if (mdver_enabled()) - { - /* - * Since we create the TransInvalidationInfo in the TopTransactionContext, - * we should create the local mdvsn in the same context as well. - */ - MemoryContext oldcxt = MemoryContextSwitchTo(TopTransactionContext); - myInfo->local_mdvsn = mdver_create_local_mdvsn(myInfo->my_level); - MemoryContextSwitchTo(oldcxt); - } - transInvalInfo = myInfo; } @@ -1164,14 +1064,6 @@ AtEOXact_Inval(bool isCommit) ProcessInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs, LocalExecuteInvalidationMessage); - - /* TODO gcaragea 05/07/2014: Add support for aborting transactions (MPP-23505) */ - - if (mdver_enabled()) - { - mdver_destroy_local_mdvsn(transInvalInfo->local_mdvsn, transInvalInfo->my_level); - transInvalInfo->local_mdvsn = NULL; - } } transInvalInfo = NULL; @@ -1221,12 +1113,6 @@ AtEOSubXact_Inval(bool isCommit) /* Pop the transaction state stack */ transInvalInfo = myInfo->parent; - if (mdver_enabled()) - { - mdver_destroy_local_mdvsn(myInfo->local_mdvsn, myInfo->my_level); - myInfo->local_mdvsn = NULL; - } - /* Need not free anything else explicitly */ pfree(myInfo); } @@ -1241,18 +1127,10 @@ AtEOSubXact_Inval(bool isCommit) /* Pop the transaction state stack */ transInvalInfo = myInfo->parent; - if (mdver_enabled()) - { - mdver_destroy_local_mdvsn(myInfo->local_mdvsn, myInfo->my_level); - myInfo->local_mdvsn = NULL; - } - /* Need not free anything else explicitly */ pfree(myInfo); } - elog(gp_mdversioning_loglevel, "In AtEOSubXact_Inval. Freeing subxact MDVSN"); - } /* @@ -1281,9 +1159,6 @@ CommandEndInvalidationMessages(void) if (transInvalInfo == NULL) return; - MdVer_PreProcessInvalidMsgs(&transInvalInfo->PriorCmdInvalidMsgs, - &transInvalInfo->CurrentCmdInvalidMsgs); - ProcessInvalidationMessages(&transInvalInfo->CurrentCmdInvalidMsgs, LocalExecuteInvalidationMessage); AppendInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs, @@ -1301,24 +1176,6 @@ CacheInvalidateHeapTuple(Relation relation, HeapTuple tuple, SysCacheInvalidateA PrepareForTupleInvalidation(relation, tuple, action); } -/* - * CacheAddVersioningEvent - * Register a new versioning event for propagation at the end of - * command. A copy of the event is added to the queue. - */ -void -CacheAddVersioningEvent(mdver_event *mdev) -{ - if (transInvalInfo == NULL) - { - return; - } - - AddVersioningEventMessage( - &transInvalInfo->CurrentCmdInvalidMsgs, - mdev); -} - /* * CacheInvalidateRelcache * Register invalidation of the specified relation's relcache entry @@ -1447,108 +1304,3 @@ CacheRegisterRelcacheCallback(CacheCallbackFunction func, ++cache_callback_count; } - -/* - * Returns the Local Metadata Version cache handler corresponding - * to the current subtransaction nesting level. - */ -mdver_local_mdvsn * -GetCurrentLocalMDVSN(void) -{ - - if (NULL != transInvalInfo) - { - return transInvalInfo->local_mdvsn; - } - - return NULL; -} - -/* - * When moving messages from the Current Command Invalidation Queue (CVQ) to the - * Prior Command Invalidation Queue (XVQ), pre-process the event queue to - * eliminate any events that will have no effect. - * If a versioning event is followed by a nuke event, it will have no effect. - * Moreover, when a nuke event is moved to XVQ, everything prior in XVQ will - * also have no effect. - * Therefore we look for Nuke events in CVQ. Find the last one (in the order - * of creation), then move all messages from then on to XVQ, overwriting XVQ. - */ -static void -MdVer_PreProcessInvalidMsgs(InvalidationListHeader *dest, - InvalidationListHeader *src) -{ - - /* Go through src from first until last. Keep track of last nuke found - * If nuke found, then: - * -- move msgs from nuke onward from cvq to svq - * -- move msgs to the beginning of first chunk - * -- make the first chunk of cvq to be the firs chunk of svq - * -- at this point, make cvq null, we already moved everything - */ - - InvalidationChunk *chunk = src->velist; - if (NULL == chunk) - { - /* Source is empty */ - return; - } - - /* Find chunk and index of the last nuke message */ - InvalidationChunk *last_good_chunk = NULL; - int last_good_index = -1; - while (NULL != chunk) - { - for (int i = 0; i < chunk->nitems; i++) - { - SharedInvalidationMessage *crt_message = &chunk->msgs[i]; - Assert(crt_message->id == SHAREDVERSIONINGMSG_ID); - mdver_event *crt_event = &(crt_message->ve.verEvent); - if (mdver_is_nuke_event(crt_event)) - { - last_good_chunk = chunk; - last_good_index = i; - } - } - chunk = chunk->next; - } - - - if (NULL != last_good_chunk) { - /* Found a nuke, and we have the chunk and index saved */ - Assert(last_good_index >= 0); - - /* 1. Free up previous chunks from src, as we'll discard them */ - InvalidationChunk *src_chunk = src->velist; - while (src_chunk != last_good_chunk) { - InvalidationChunk *next_chunk = src_chunk->next; - pfree(src_chunk); - src_chunk = next_chunk; - } - src->velist = last_good_chunk; - - /* 1. Move messages to the beginning of the chunk */ - for (int i = last_good_index; i < last_good_chunk->nitems; i++) - { - last_good_chunk->msgs[i - last_good_index] = last_good_chunk->msgs[i]; - } - /* 2. Update nitems value */ - last_good_chunk->nitems = last_good_chunk->nitems - last_good_index; - - /* Free up all the chunks from dest */ - InvalidationChunk *dest_chunk = dest->velist; - while (NULL != dest_chunk) { - InvalidationChunk *next_chunk = dest_chunk->next; - pfree(dest_chunk); - dest_chunk = next_chunk; - } - - /* Move messages from src to overwrite dest */ - dest->velist = last_good_chunk; - - /* Set src to NULL as we're done with the transfer */ - src->velist = NULL; - } -} - - diff --git a/src/backend/utils/mdver/Makefile b/src/backend/utils/mdver/Makefile deleted file mode 100644 index afca18a7a4..0000000000 --- a/src/backend/utils/mdver/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile-- -# Makefile for utils/mdver -# -# IDENTIFICATION -# $PostgreSQL: pgsql/src/backend/utils/mdver/Makefile,v 1.15 2008/02/19 10:30:09 petere Exp $ -# -#------------------------------------------------------------------------- - -subdir = src/backend/utils/mdver -top_builddir = ../../../.. -include $(top_builddir)/src/Makefile.global - -OBJS = mdver_global_mdvsn.o mdver_dep_translator.o mdver_utils.o \ - mdver_global_handler.o mdver_local_mdvsn.o mdver_local_handler.o - -include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/utils/mdver/mdver_dep_translator.c b/src/backend/utils/mdver/mdver_dep_translator.c deleted file mode 100644 index 1c38aa03d5..0000000000 --- a/src/backend/utils/mdver/mdver_dep_translator.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/*------------------------------------------------------------------------- - * - * mdver_dep_translator.c - * Implementation of Dependency Translator (DT) for metadata versioning - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "catalog/catalog.h" -#include "cdb/cdbvars.h" -#include "miscadmin.h" -#include "storage/sinval.h" -#include "utils/guc.h" -#include "utils/inval.h" -#include "utils/mdver.h" - -/* Catalog table definitions */ -#include "catalog/pg_constraint.h" -#include "catalog/pg_proc.h" -#include "catalog/pg_operator.h" -#include "catalog/pg_aggregate.h" - -static void mdver_dt_add_cache_events(List **events); -static mdver_event *mdver_new_nuke_event(void); -static void mdver_add_nuke_event(List **events); - -/* - * Generate all the invalidation messages caused by updating a tuple in a catalog table - * relation: The catalog table being touched - * tuple: The affected tuple - * action: The action performed on the tuple - */ -void -mdver_dt_catcache_inval(Relation relation, HeapTuple tuple, SysCacheInvalidateAction action) -{ - if (!mdver_enabled()) - { - return; - } - - List *events = NIL; - - /* For milestone 0, we generate NUKE events for any DDL. - * Well, not really, there's no need to generate NUKE events for INSERTS and DELETE - * in catalog tables, since those do not have dependencies that need to be tracked. - * - * TODO gcaragea 01/14/2015: Remove this code for milestone 1 (simple dependecies) - */ - - if (IsAoSegmentRelation(relation)) - { - /* - * We don't create versioning messages for catalog tables in the AOSEG - * namespace. These are modified for DML only (not DDL) - * - * TODO gcaragea 01/14/2015: Remove this once we have DML versioning - */ - return; - } - - switch (action) - { - - case SysCacheInvalidate_Update_OldTup: - /* We ignore the first event from the update. We only process the second one below */ - break; - case SysCacheInvalidate_Insert: - /* fall through */ - case SysCacheInvalidate_Delete: - /* fall through */ - case SysCacheInvalidate_Update_NewTup: - /* fall through */ - case SysCacheInvalidate_Update_InPlace: - /* fall through */ - case SysCacheInvalidate_VacuumMove: - mdver_add_nuke_event(&events); - break; - default: - insist_log(false, "Unkown syscache invalidation operation"); - - } - - /* If we generated any events, add them to the event message list */ - if (NIL != events) - { - mdver_dt_add_cache_events(&events); - } -} - -/* - * Add a new nuke event to the list of events generated. - * Avoid adding consecutive nuke events since they are composable. - */ -static void -mdver_add_nuke_event(List **events) -{ - /* Don't append a nuke if the last event in the queue is already a nuke */ - if (NIL != *events) { - ListCell *tail = list_tail(*events); - mdver_event *last_event = lfirst(tail); - if (mdver_is_nuke_event(last_event)) { - return; - } - } - - /* Last event is not nuke, or events was empty. Append to queue */ - *events = lappend(*events, mdver_new_nuke_event()); -} - -/* - * Iterate through a list of versioning events and add them all to the - * message queue. The list of events is deep-freed after events are added, - * since we shouldn't need the actual events anymore. - * - * events: Pointer to list of events to be added to the CVQ - */ -static void -mdver_dt_add_cache_events(List **events) -{ - Assert(NIL != *events); - - ListCell *lc = NULL; - foreach (lc, *events) - { - mdver_event *new_event = (mdver_event *) lfirst(lc); - CacheAddVersioningEvent(new_event); - } - - /* Deep free the list of events. This also calls pfree() on all the events */ - list_free_deep(*events); - *events = NIL; -} - -/* - * Returns true if the event given is a NUKE event - */ -bool -mdver_is_nuke_event(const mdver_event *event) -{ - Assert(NULL != event); - - return (event->key == MDVER_NUKE_KEY); -} - -/* - * Creates and returns a new NUKE event. - * - * The event is palloc-ed in the current memory context, and the - * caller is responsible for pfree-ing it. - */ -static mdver_event * -mdver_new_nuke_event(void) -{ - mdver_event *event = (mdver_event *) palloc0(sizeof(mdver_event)); - event->key = MDVER_NUKE_KEY; - -#ifdef MD_VERSIONING_INSTRUMENTATION - ereport(gp_mdversioning_loglevel, - (errmsg("Generating NUKE event"), - errprintstack(true))); -#endif - - return event; -} diff --git a/src/backend/utils/mdver/mdver_global_handler.c b/src/backend/utils/mdver/mdver_global_handler.c deleted file mode 100644 index d1da474893..0000000000 --- a/src/backend/utils/mdver/mdver_global_handler.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/*------------------------------------------------------------------------- - * - * mdver_global_handler.c - * Implementation of Global VE Handler for metadata versioning - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "utils/mdver.h" -#include "utils/guc.h" -#include "storage/sinval.h" -#include "cdb/cdbvars.h" - -/* Forward declarations */ -static void mdver_globalhandler_add_version(mdver_event *event); -static void mdver_globalhandler_reconcile(mdver_event *event, CacheEntry *cached_entry); - -/* - * Entry point to the Global VE Handler. Iterate through a list of messages, - * and add versions to the cache if there are any versioning events in the list. - * messages: Pointer to the list of messages - * n: Number of messages to process - */ -void -mdver_globalhandler_new_event(SharedInvalidationMessage *messages, int n) -{ - Assert(NULL != messages); - - /* There is no metadata versioning on segments, ignore */ - if (AmISegment()) - { - return; - } - - for (int i=0; i < n; i++) - { - SharedInvalidationMessage *msg = &messages[i]; - if (SHAREDVERSIONINGMSG_ID == msg->id) - { - mdver_globalhandler_add_version(&msg->ve.verEvent); - /* - * We change the flag of the message to non-local once added - * to the SVQ - */ - msg->ve.local = false; - } - } -} - -/* - * Add or update an entry in the Global MDVSN cache for a versioning event - * found in the event list. Reconcile with current contents of the cache - * if needed. - * event: The event containing the versioning information for an update - */ -static void -mdver_globalhandler_add_version(mdver_event *event) -{ - Assert(NULL != event); - - Cache *glob_mdvsn = mdver_get_glob_mdvsn(); - - if (mdver_is_nuke_event(event)) - { - mdver_glob_mdvsn_nuke(); - return; - } - - mdver_entry mdver = { InvalidOid, INVALID_MD_VERSION, INVALID_MD_VERSION }; - mdver.key = event->key; - mdver.ddl_version = INVALID_MD_VERSION; - mdver.dml_version = INVALID_MD_VERSION; - - /* FIXME gcaragea 04/14/2014: Trigger evictions if cache is full (MPP-22923) */ - CacheEntry *acquired_entry = Cache_AcquireEntry(glob_mdvsn, &mdver); - Assert(NULL != acquired_entry); - - /* - * We're about to look-up and insert/update a shared cache entry. - * Grab writer lock in exclusive mode, so that no other backend - * tries to insert or update the same entry at the same time. - */ - LWLockAcquire(MDVerWriteLock, LW_EXCLUSIVE); - - CacheEntry *cached_entry = Cache_Lookup(glob_mdvsn, acquired_entry); - - if (NULL != cached_entry) - { - mdver_globalhandler_reconcile(event, cached_entry); - - /* Done with the looked-up entry. Release it */ - Cache_Release(glob_mdvsn, cached_entry); - } - else - { - /* Entry not found, insert new entry */ - mdver_entry *new_mdver_entry = CACHE_ENTRY_PAYLOAD(acquired_entry); - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Inserting into GlobalMDVSN entry %d: (%d,%d)", - event->key, - (int) event->new_ddl_version, (int) event->new_dml_version); -#endif - - new_mdver_entry->ddl_version = event->new_ddl_version; - new_mdver_entry->dml_version = event->new_dml_version; - - Cache_Insert(glob_mdvsn, acquired_entry); - } - - Cache_Release(glob_mdvsn, acquired_entry); - LWLockRelease(MDVerWriteLock); -} - -/* - * Reconcile an incoming versioning event with an existing Global MDVSN entry - * for the same versioned object. - * - * Each versioning event contains the old version and the new version as known - * by the originating backend: - * VE = (key, oldV, newV) - * Cached entry contains the current version globally visible: - * entry = (key, crtV) - * - * We have the following scenarios: - * - If oldV == crtV, (i.e. VE old version is the same as the current version) - * then nobody else has modified the object since the backend read it. - * We simply update the entry with the new version in that case: - * entry = (key, crtV) --> entry = (key, newV) - * - * - If oldV < crtV, (i.e. VE old version is different than the current version) - * some other backend must have modified the object in the meantime. - * We generate an entirely new version new_newV for the object to reflect - * the new "combined" object. - * - * The cached entry is updated directly with the new version: - * entry = (key, crtV) --> entry = (key, new_newV) - * - * The versioning event in the queue is updated directly: - VE = (key, oldV, newV) --> VE = (key, crtV, new_newV) - * - * event: The event containing the versioning information for an update - * cached_entry: The existing entry for this object in the Global MDVSN - * - * This function is called while the MDVerWriteLock is held in exclusive - * mode. Don't do anything that is not allowed while holding a LWLock - * (e.g. allocate memory, or call unsafe functions). - * - */ -static void -mdver_globalhandler_reconcile(mdver_event *event, CacheEntry *cached_entry) -{ - - /* Found existing entry, reconcile and update the version */ - mdver_entry *cached_mdver_entry = CACHE_ENTRY_PAYLOAD(cached_entry); - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Updating GlobalMDVSN entry %d: Current (%d,%d). Event: [(%d,%d)->(%d,%d)]", - event->key, - (int) cached_mdver_entry->ddl_version, (int) cached_mdver_entry->dml_version, - (int) event->old_ddl_version, (int) event->old_dml_version, - (int) event->new_ddl_version, (int) event->new_dml_version); -#endif - - /* - * Reconcile and resolve conflicts for incoming versioning events. - * When a new versioning event is received at the Global MDVSN, - * look up if the same object has a conflicting version. - * If so, resolve conflict by generating a new version. - */ - - uint64 new_ddl_version = event->new_ddl_version; - uint64 new_dml_version = event->new_dml_version; - bool conflict = false; - - /* - * It is safe to read the cached_mdver_entry contents, since - * we're holding the write lock on the Global MDVSN cache. - */ - if (cached_mdver_entry->ddl_version != event->old_ddl_version) - { - new_ddl_version = mdver_next_global_version(); - conflict = true; - } - - if (cached_mdver_entry->dml_version != event->old_dml_version) - { - new_dml_version = mdver_next_global_version(); - conflict = true; - } - - if (conflict) - { - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Updating event in the queue (pid=%d, oid=%d): Old event: [(%d,%d)->(%d,%d)]. Modified event: [(%d,%d)->(%d,%d)]", - event->backend_pid, - event->key, - /* Old event */ - (int) event->old_ddl_version, (int) event->old_dml_version, - (int) event->new_ddl_version, (int) event->new_dml_version, - /* New event */ - (int) cached_mdver_entry->ddl_version, (int) cached_mdver_entry->dml_version, - (int) new_ddl_version, (int) new_dml_version); -#endif - - /* - * A new version for this object is being generated here. - * We're going to directly update the event in the queue with the new - * version. - */ - - event->new_ddl_version = new_ddl_version; - event->new_dml_version = new_dml_version; - - /* - * We're also updating the VE old version to reflect the current - * visible global version - */ - event->old_ddl_version = cached_mdver_entry->ddl_version; - event->old_dml_version = cached_mdver_entry->dml_version; - } - - /* About to update the cached entry. Lock entry to make update atomic */ - Cache *glob_mdvsn = mdver_get_glob_mdvsn(); - Cache_LockEntry(glob_mdvsn, cached_entry); - - cached_mdver_entry->ddl_version = new_ddl_version; - cached_mdver_entry->dml_version = new_dml_version; - - Cache_UnlockEntry(glob_mdvsn, cached_entry); - -} - diff --git a/src/backend/utils/mdver/mdver_global_mdvsn.c b/src/backend/utils/mdver/mdver_global_mdvsn.c deleted file mode 100644 index ffaa736486..0000000000 --- a/src/backend/utils/mdver/mdver_global_mdvsn.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/*------------------------------------------------------------------------- - * - * mdver_global_mdvsn.c - * Implementation of Global MDVSN for metadata versioning - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "utils/mdver.h" -#include "miscadmin.h" -#include "cdb/cdbvars.h" - -/* Name to identify the MD Versioning Global MDVSN shared memory */ -#define MDVER_GLOB_MDVN_SHMEM_NAME "MDVer Global MDVSN" - -/* Name to identify the MD Versioning global version counter (GVC) shared memory area */ -#define MDVER_GLOBAL_VER_SHMEM_NAME "MDVer Global Version Counter" - -/* Pointer to the shared memory global version counter (GVC) */ -uint64 *mdver_global_version_counter = NULL; - -/* MDVer Global MDVSN is stored here, once attached to */ -Cache *mdver_glob_mdvsn = NULL; - -/* Forward declarations */ -static bool mdver_entry_equivalent(const void *new_entry, const void *cached_entry); -static void mdver_entry_populate(const void *resource, const void *param); - -/* - * Initialize the shared memory data structures needed for MD Versioning - * - */ -void -mdver_shmem_init(void) -{ - CacheCtl cacheCtl; - MemSet(&cacheCtl, 0, sizeof(CacheCtl)); - - cacheCtl.maxSize = gp_mdver_max_entries; - cacheCtl.cacheName = MDVER_GLOB_MDVN_SHMEM_NAME; - cacheCtl.entrySize = sizeof(mdver_entry); - cacheCtl.keySize = sizeof(((mdver_entry *)0)->key); - cacheCtl.keyOffset = GPDB_OFFSET(mdver_entry, key); - - cacheCtl.hash = int32_hash; - cacheCtl.keyCopy = (HashCopyFunc) memcpy; - cacheCtl.match = (HashCompareFunc) memcmp; - cacheCtl.equivalentEntries = mdver_entry_equivalent; - cacheCtl.cleanupEntry = NULL; /* No cleanup necessary */ - cacheCtl.populateEntry = mdver_entry_populate; - - cacheCtl.baseLWLockId = FirstMDVersioningLock; - cacheCtl.numPartitions = NUM_MDVERSIONING_PARTITIONS; - - mdver_glob_mdvsn = Cache_Create(&cacheCtl); - Assert(NULL != mdver_glob_mdvsn); - - bool attach = false; - /* Allocate or attach to shared memory area */ - void *shmem_base = ShmemInitStruct(MDVER_GLOBAL_VER_SHMEM_NAME, - sizeof(*mdver_global_version_counter), - &attach); - - mdver_global_version_counter = (uint64 *)shmem_base; - Assert(0 == *mdver_global_version_counter); - -} - - -/* - * SharedCache callback. Tests if two mdver entries are equivalent - * Two entries are considered equivalent if the keys are equal, regardless - * of the versions. - * - * new_entry: A new entry that is considered for insertion/look-up - * cached_entry: The entry in the cache we're comparing to - */ -static bool -mdver_entry_equivalent(const void *new_entry, const void *cached_entry) -{ - Assert(NULL != new_entry); - Assert(NULL != cached_entry); - -#if USE_ASSERT_CHECKING - mdver_entry *res1 = (mdver_entry *) new_entry; - mdver_entry *res2 = (mdver_entry *) cached_entry; -#endif - - Assert(res1->key == res2->key); - - /* As long as keys are equal, we consider the entries equal */ - return true; -} - -/* - * SharedCache callback. Populates a newly acquired mdver entry - * returning it to the caller. - * resource: Pointer to the acquired mdver entry - * param: Pointer to the entry with the source data - * - */ -static void -mdver_entry_populate(const void *resource, const void *param) -{ - Assert(NULL != resource); - Assert(NULL != param); - - mdver_entry *mdver_new = (mdver_entry *) resource; - mdver_entry *mdver_info = (mdver_entry *) param; - - memcpy(mdver_new, mdver_info, sizeof(mdver_entry)); -} - -/* - * Compute the size of shared memory required for the MD Versioning component - */ -Size -mdver_shmem_size(void) -{ - return Cache_SharedMemSize(gp_mdver_max_entries, sizeof(mdver_entry)) - + sizeof(*mdver_global_version_counter); -} - -/* - * Returns pointer to the MDVer Global MDVSN component - */ -Cache * -mdver_get_glob_mdvsn(void) -{ - Assert(NULL != mdver_glob_mdvsn); - return mdver_glob_mdvsn; -} - -/* - * Look up an entry in the Global MDVSN component. - * To avoid any concurrency issues, this returns a copy of the entry, - * palloc'ed in the current memory context. The caller is responsible - * for freeing this copy. - * - * Returns a copy of the entry if found, NULL otherwise. - * - */ -mdver_entry * -mdver_glob_mdvsn_find(Oid oid) -{ - - Assert(NULL != mdver_glob_mdvsn); - - mdver_entry mdver_info; - mdver_info.key = oid; - - /* FIXME gcaragea 03/18/2014: Trigger evictions if cache is full (MPP-22923) */ - CacheEntry *localEntry = Cache_AcquireEntry(mdver_glob_mdvsn, &mdver_info); - Assert(NULL != localEntry); - - CacheEntry *cachedEntry = Cache_Lookup(mdver_glob_mdvsn, localEntry); - - /* Release local entry. We don't need it anymore */ - Cache_Release(mdver_glob_mdvsn, localEntry); - - mdver_entry *mdver_copy = NULL; - if (NULL != cachedEntry) - { - /* Found a match. Make a local copy */ - mdver_entry *shared_mdver = (mdver_entry *) CACHE_ENTRY_PAYLOAD(cachedEntry); - mdver_copy = (mdver_entry *) palloc0(sizeof(mdver_entry)); - - /* Lock entry to ensure atomicity of copy */ - Cache_LockEntry(mdver_glob_mdvsn, cachedEntry); - - memcpy(mdver_copy, shared_mdver, sizeof(mdver_entry)); - - /* Got the copy, unlock entry */ - Cache_UnlockEntry(mdver_glob_mdvsn, cachedEntry); - - /* - * We're also done with the entry, release our pincount on it - * - * TODO gcaragea 05/02/2014: Are there cases where we need to hold the - * entry past this point? (MPP-22923) - */ - Cache_Release(mdver_glob_mdvsn, cachedEntry); - } - - return mdver_copy; -} - -/* - * Clears the contents of the entire Global MDVSN specified. - * - * Pinned entries are not deleted, but they are marked for removal as soon - * as the last user releases them. Entries marked for deletion are not returned - * as valid results during look-ups either. - */ -void -mdver_glob_mdvsn_nuke(void) -{ - Assert(NULL != mdver_glob_mdvsn); - - LWLockAcquire(MDVerWriteLock, LW_EXCLUSIVE); - - PG_TRY(); - { - int32 num_deleted = Cache_Clear(mdver_glob_mdvsn); - elog(gp_mdversioning_loglevel, "Nuke at Global MDVSN deleted %d entries", num_deleted); - } - PG_CATCH(); - { - LWLockRelease(MDVerWriteLock); - PG_RE_THROW(); - } - PG_END_TRY(); - - LWLockRelease(MDVerWriteLock); -} diff --git a/src/backend/utils/mdver/mdver_local_handler.c b/src/backend/utils/mdver/mdver_local_handler.c deleted file mode 100644 index 0e1465305c..0000000000 --- a/src/backend/utils/mdver/mdver_local_handler.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/*------------------------------------------------------------------------- - * - * mdver_local_handler.c - * Implementation of Local VE Handler for metadata versioning - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "utils/mdver.h" -#include "utils/guc.h" -#include "storage/sinval.h" - -static void mdver_localhandler_reconcile(mdver_event *event, mdver_entry *local_entry); - -/* - * Entry point for the Local Versioning Event Handler. This gets called - * for every message that is executed locally at a backend. - */ -extern void -mdver_localhandler_new_event(SharedInvalidationMessage *msg) -{ - Assert(NULL != msg); - Assert(SHAREDVERSIONINGMSG_ID == msg->id); - -#ifdef MD_VERSIONING_INSTRUMENTATION - char *mdev_str = mdver_event_str(&msg->ve.verEvent); - ereport(gp_mdversioning_loglevel, - (errmsg("LocalExecuteVE: got %s event %s", - msg->ve.local ? "LOCAL" : "REMOTE", - mdev_str), - errprintstack(false))); - pfree(mdev_str); -#endif - - /* - * There are some cases where we don't have a transInvalInfo structure, - * and thus we don't have a Local MDVSN. For example: - * - an auxiliary process (fts prober comes to mind) that queries - * catalog tables directly using heap functions (no transaction) - * - updating persistent tables during transaction commit - * (transInvalInfo has already been reset). - * - bootstrap - * - * In other cases, we simply don't have a Local MDVSN since we don't - * cache versions: - * - a QE process running on the master or segments will have a - * syscache, but not a Metadata Version cache - * - * In those cases we don't care about versioning, so skip adding - * to local MDVSN. - */ - - mdver_local_mdvsn *local_mdvsn = GetCurrentLocalMDVSN(); - if (NULL != local_mdvsn) - { - - mdver_event *event = &msg->ve.verEvent; - - if (mdver_is_nuke_event(event)) - { - elog(gp_mdversioning_loglevel, "Local VE Handler: Received NUKE event"); - mdver_local_mdvsn_nuke(local_mdvsn); - return; - } - - if (msg->ve.local) - { - /* - * Locally generated event, we must add or update the version - * in the Local MDVSN. - */ - mdver_entry entry; - entry.key = event->key; - - /* FIXME gcaragea 7/4/2014: Can we assert anything here? */ - entry.ddl_version = event->new_ddl_version; - entry.dml_version = event->new_dml_version; - - mdver_local_mdvsn_add(local_mdvsn, &entry, msg->ve.local); - } - else - { - /* - * An event coming from the global queue (GVQ) - * If we are interested in this object, add / update - * version in Local MDVSN. - * - */ - - mdver_entry *local_entry = mdver_local_mdvsn_find(local_mdvsn, event->key); - if (NULL != local_entry) - { - - /* - * A VE came from SVQ for a key that we already have locally. - * Need to reconcile and record. - */ - mdver_localhandler_reconcile(event, local_entry); - } - else - { - elog(gp_mdversioning_loglevel, "Local VE Handler: Ignoring remote event for object not of interest key=%d", event->key); - } - - /* TODO gcaragea 5/27/2014: For subtransactions, keep all messages (MPP-22935) */ - } - - } -} - -/* - * Reconcile and resolve conflicts for incoming versioning events. - * - * This function handles both events generated locally and remotely by other - * backends. - * - * When a new versioning event is received at the Local MDVSN, - * look up if the same object has a conflicting version locally. - * - * If a conflict is detected, resolve by generating a new version for - * the "combined" object. We don't generate a new VE for the conflict. - * This means the combined object version is only visible to the - * current backend. - * - * event: The new event to be considered - * local_entry: The conflicting entry in the Local MDVSN cache - */ -static void -mdver_localhandler_reconcile(mdver_event *event, mdver_entry *local_entry) -{ - -#ifdef MD_VERSIONING_INSTRUMENTATION - char *mdev_str = mdver_event_str(event); - elog(gp_mdversioning_loglevel, "Local VE Handler: Reconcile: Local entry = %d: (%d, %d). Incoming event %s", - local_entry->key, - (int) local_entry->ddl_version, - (int) local_entry->dml_version, - mdev_str); - pfree(mdev_str); -#endif - - uint64 new_ddl_version = event->new_ddl_version; - uint64 new_dml_version = event->new_dml_version; - bool conflict = false; - - if (local_entry->ddl_version != event->old_ddl_version) - { - new_ddl_version = mdver_next_global_version(); - conflict = true; - } - - if (local_entry->dml_version != event->old_dml_version) - { - new_dml_version = mdver_next_global_version(); - conflict = true; - } - -#if MD_VERSIONING_INSTRUMENTATION - if (conflict) - { - elog(gp_mdversioning_loglevel, "Local VE Handler: Conflict resolved. New" - "version generated, updated local entry to %d : (%d,%d) -> (%d, %d)", - local_entry->key, - (int) local_entry->ddl_version, (int) local_entry->dml_version, - (int) new_ddl_version, (int) new_dml_version); - - } - else - { - elog(gp_mdversioning_loglevel, "Local VE Handler: No conflict. Update local entry to %d : (%d,%d) -> (%d, %d)", - local_entry->key, - (int) event->old_ddl_version, (int) event->old_dml_version, - (int) event->new_ddl_version, (int) event->new_dml_version); - } -#endif - - /* Update local entry with the resolved versions */ - local_entry->ddl_version = new_ddl_version; - local_entry->dml_version = new_dml_version; -} diff --git a/src/backend/utils/mdver/mdver_local_mdvsn.c b/src/backend/utils/mdver/mdver_local_mdvsn.c deleted file mode 100644 index 87fa54064d..0000000000 --- a/src/backend/utils/mdver/mdver_local_mdvsn.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/*------------------------------------------------------------------------- - * - * mdver_local_mdvsn.c - * Implementation of Local MDVSN for metadata versioning - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "utils/mdver.h" -#include "miscadmin.h" -#include "cdb/cdbvars.h" - -/* Number of buckets for a Local MDVSN hashtable */ -#define MDVER_LOCAL_MDVSN_NBUCKETS 1024 - -/* - * Look up an entry in the specified Local MDVSN component. This function - * doesn't traverse to the parent Local MDVSN. - * - * Returns the entry if found, NULL otherwise. - * - * local_mdvsn: Which MDVSN to look into. For subtransactions, we have - * a separate Local MDVSN component for each level - * key: The key of the object to look for - */ -mdver_entry * -mdver_local_mdvsn_find(mdver_local_mdvsn *local_mdvsn, Oid key) -{ - Assert(NULL != local_mdvsn); - Assert(InvalidOid != key); - - mdver_entry *entry = (mdver_entry *) hash_search(local_mdvsn->htable, &key, - HASH_FIND, NULL /* foundPtr */); - - ereport(gp_mdversioning_loglevel, - (errmsg("LocalMDVSN find for key=%d. Found=%s, nukeHappened=%s", - key, - (NULL!=entry)?"yes":"no", - local_mdvsn->nuke_happened?"yes":"no"), - errprintstack(true))); - - - return entry; -} - -/* - * Inserts or updates an entry in the Local MDVSN component. - * Entry is inserted if not already existing, or updated otherwise. - * - * local_mdvsn: Which MDVSN to insert/update into. For subtransactions, we have - * a separate Local MDVSN compoment for each level. - * entry: The mdver_entry to be inserted or updated. A copy of it will be inserted - * in the hashtable - * local: true if the message was generated locally, and it's coming from CVQ. - * false if message is coming from the global queue SVQ - */ -void -mdver_local_mdvsn_add(mdver_local_mdvsn *local_mdvsn, mdver_entry *entry, bool local) -{ - Assert(NULL != local_mdvsn); - Assert(NULL != local_mdvsn->htable); - Assert(NULL != entry); - - bool found_ptr = false; - mdver_entry *inserted_entry = (mdver_entry *) hash_search(local_mdvsn->htable, - &entry->key, HASH_ENTER, &found_ptr); - Assert(NULL != inserted_entry); - -#ifdef MD_VERSIONING_INSTRUMENTATION - if (found_ptr) - { - ereport(gp_mdversioning_loglevel, - (errmsg("local_mdvsn_add: updating entry Oid=%d [" UINT64_FORMAT ", " UINT64_FORMAT "] --> [" UINT64_FORMAT ", " UINT64_FORMAT "]", - inserted_entry->key, inserted_entry->ddl_version, inserted_entry->dml_version, - entry->ddl_version, entry->dml_version), - errprintstack(false))); - } - else - { - ereport(gp_mdversioning_loglevel, - (errmsg("local_mdvsn_add: inserting entry Oid=%d [" UINT64_FORMAT ", " UINT64_FORMAT "]", - inserted_entry->key, - entry->ddl_version, entry->dml_version), - errprintstack(false))); - } -#endif - - memcpy(inserted_entry, entry, sizeof(mdver_entry)); - -} - -/* - * Clears the contents of the entire Local MDVSN specified. - */ -void -mdver_local_mdvsn_nuke(mdver_local_mdvsn *local_mdvsn) -{ - Assert(NULL != local_mdvsn); - Assert(NULL != local_mdvsn->htable); - - HASH_SEQ_STATUS iterator; - hash_seq_init(&iterator, local_mdvsn->htable); - mdver_entry *entry = NULL; - int num_deleted = 0; - - while ((entry = (mdver_entry *) hash_seq_search(&iterator)) != NULL) - { -#if USE_ASSERT_CHECKING - mdver_entry *result = (mdver_entry *) -#endif - hash_search(local_mdvsn->htable, - (void *) &(entry->key), - HASH_REMOVE, - NULL); - - Assert(NULL != result); - - num_deleted++; - - } - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Nuke at Local MDVSN deleted %d entries", num_deleted); -#endif - - local_mdvsn->nuke_happened = true; - - return; -} - -/* - * Allocate a new Local MDVSN data structure in the Current Memory Context - * - */ -static mdver_local_mdvsn * -mdver_local_mdvsn_create_hashtable(const char *htable_name) -{ - - mdver_local_mdvsn *new_local_mdvsn = palloc0(sizeof(mdver_local_mdvsn)); - - HASHCTL ctl; - ctl.keysize = sizeof(Oid); - ctl.entrysize = sizeof(mdver_entry); - ctl.hash = oid_hash; - - HTAB *htable = hash_create(htable_name, - MDVER_LOCAL_MDVSN_NBUCKETS, - &ctl, - HASH_ELEM | HASH_FUNCTION); - - new_local_mdvsn->htable = htable; - new_local_mdvsn->nuke_happened = false; - - return new_local_mdvsn; -} - -/* - * Creates the Local MDVSN for the current transaction or subtransaction. - * - * For a top-level transaction, returns the session-level Local MDVSN, - * which has already been created at the start of the session. - * - * For a subtransaction, it creates a new Local MDVSN for the life of the - * subtransaction. - * - * nesting_level: The nesting level of the current transaction. - * nesting_level is 0 for outside any transaction, 1 for top-level - * transaction, and > 1 for subtransaction - */ -mdver_local_mdvsn * -mdver_create_local_mdvsn(int nesting_level) -{ - - Assert(1 <= nesting_level); - - /* - * nesting_level is 0 for outside any transaction, 1 for top-level - * transaction, and > 1 for subtransaction. - */ - - - StringInfo cache_name = makeStringInfo(); - - if (nesting_level == 1) - { - /* Top-level transaction */ - appendStringInfo(cache_name, "TopLevel Xact MDVSN"); - - } - else - { - /* nesting_level > 1: Subtransaction level */ - appendStringInfo(cache_name, "SubXact MDVSN nesting_level=%d", nesting_level); - } - - elog(gp_mdversioning_loglevel, - "In mdver_get_local_mdvsn. Creating Local MDVSN: [%s]. Gp_role = %d, Gp_identity=%d", - cache_name->data, - Gp_role, GpIdentity.segindex); - - mdver_local_mdvsn *local_mdvsn = mdver_local_mdvsn_create_hashtable(cache_name->data); - - pfree(cache_name->data); - pfree(cache_name); - - return local_mdvsn; -} - -/* - * Frees up the memory allocated to a Local MDVSN component - * local_mdvsn: the Local MDVSN to be freed - * nesting_level: Nesting level of the owner transaction or subtransaction - * - * After this function is called, the local_mdvsn is a dangling pointer. - * Caller should set this pointer to NULL. - * - * FIXME gcaragea 6/2/2014: Pass double pointer and assign to NULL here - */ -void -mdver_destroy_local_mdvsn(mdver_local_mdvsn *local_mdvsn, int nesting_level) -{ - Assert(NULL != local_mdvsn); - Assert(nesting_level >= 1); - - elog(gp_mdversioning_loglevel, "Destroying Local MDVSN, level=%d", nesting_level); - - hash_destroy(local_mdvsn->htable); - pfree(local_mdvsn); -} diff --git a/src/backend/utils/mdver/mdver_utils.c b/src/backend/utils/mdver/mdver_utils.c deleted file mode 100644 index 33b487c0bc..0000000000 --- a/src/backend/utils/mdver/mdver_utils.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/*------------------------------------------------------------------------- - * - * mdver_utils.c - * Utility functions for metadata versioning - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include "cdb/cdbvars.h" -#include "miscadmin.h" -#include "utils/atomic.h" -#include "utils/inval.h" -#include "utils/mdver.h" - - -static void mdver_request_from_global(Oid key, uint64 *ddl_version, uint64 *dml_version); -static void mdver_request_after_nuke(Oid key, uint64 *ddl_version, uint64 *dml_version); - -/* - * Returns a string representation of the MD Versioning event passed in. - * Result string is palloc-ed in the current memory context. - */ -char * -mdver_event_str(mdver_event *ev) -{ - char *result = (char *) palloc(MDVER_EVENT_STR_LEN); -#ifdef MD_VERSIONING_INSTRUMENTATION - snprintf(result, MDVER_EVENT_STR_LEN, "[MDVER_EVENT PID=%d OID=%d DDV= " UINT64_FORMAT " --> " UINT64_FORMAT " DMV= " UINT64_FORMAT " --> " UINT64_FORMAT "]", - ev->backend_pid, - ev->key, - ev->old_ddl_version, ev->new_ddl_version, - ev->old_dml_version, ev->new_dml_version); -#else - snprintf(result, MDVER_EVENT_STR_LEN, "[MDVER_EVENT OID=%d DDV= " UINT64_FORMAT " --> " UINT64_FORMAT " DMV= " UINT64_FORMAT " --> " UINT64_FORMAT "]", - ev->key, - ev->old_ddl_version, ev->new_ddl_version, - ev->old_dml_version, ev->new_dml_version); -#endif - - return result; -} - -/* - * Main entry point for clients that request versions for objects. Returns - * the most recent visible version of an object when requested by a - * backend/client. - * - * If no version is found, a new version for the object is generated and - * recorded in the caches. New versioning events are potentially generated - * as well if needed. - * - * This function never returns INVALID_MD_VERSION as a result. - * - * key: The key of the looked-up object - * ddl_version: used to return the ddl version for the object - * dml_version: used to return the dml version for the object - * - */ -void -mdver_request_version(Oid key, uint64 *ddl_version, uint64 *dml_version) -{ - - Assert(NULL != ddl_version); - Assert(NULL != dml_version); - - *dml_version = INVALID_MD_VERSION; - *ddl_version = INVALID_MD_VERSION; - - if (!mdver_enabled()) - { - /* - * MD Versioning feature is turned off. Return (1,0) as a fixed - * version so that ORCA can check for equality etc. - */ - *ddl_version = 1; - *dml_version = 0; - return; - } - - /* - * Basic flow is described below. More details can be found in - * the Metadata Versioning design document. - * - * - Do a look-up in the Local MDVSN. If the object is found there, - * return its version. - * - If not found in Local MDVSN, and nuke_happened is not set, - * do a look-up in the Global MDVSN. - * - If the object is found there, - * - Add it to the Local MDVSN and - * - Return its version. - * - If the object is not in Global MDVSN - * - Generate a new version for the object - * - Record the version in Global MDVSN - * - Add new version to Local MDVSN - * - Return new version - * - If not found in Local MDVSN and nuke_happened is set, the object - * needs a new version. - * - Generate a new version for the object - * - Read current version from Global MDVSN (if exists) - * - Add a versioning event to the CVQ with the new version - * - Record the new version in the Local MDVSN - * - Return the new version. - */ - - /* Try Local MDVSN first */ - mdver_local_mdvsn *local_mdvsn = GetCurrentLocalMDVSN(); - Assert(NULL != local_mdvsn); - - mdver_entry *crt_entry = mdver_local_mdvsn_find(local_mdvsn, key); - if (NULL != crt_entry) - { - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Found version in Local MDVSN: (%d, " UINT64_FORMAT ", " UINT64_FORMAT ")", - key, crt_entry->ddl_version, crt_entry->dml_version); -#endif - - *ddl_version = crt_entry->ddl_version; - *dml_version = crt_entry->dml_version; - return; - } - - if (!local_mdvsn->nuke_happened) - { - /* TODO gcaragea 6/3/2014: Traverse subtransaction contexts during look-up (MPP-22935) */ - mdver_request_from_global(key, ddl_version, dml_version); - - } - else - { - mdver_request_after_nuke(key, ddl_version, dml_version); - } - - Assert(INVALID_MD_VERSION != *ddl_version || - INVALID_MD_VERSION != *dml_version); - - mdver_entry new_entry = { key, *ddl_version, *dml_version}; - mdver_local_mdvsn_add(local_mdvsn, &new_entry, true /* local */); - -} - -/* - * When a backend is requesting the more recent version of an object, - * if the Local MDVSN cache doesn't have the version, and if a NUKE event - * hasn't been encountered in the current transaction, it is looked up - * in the Global MDVSN shared cache. - * - * If the object is found in Global MDVSN, return the global version. - * If the object is not found, generate a new version, record it in Global MDVSN - * and then return it. - * - * key: The key of the looked-up object - * ddl_version: used to return the ddl version for the object - * dml_version: used to return the dml version for the object - * - */ -static void -mdver_request_from_global(Oid key, uint64 *ddl_version, uint64 *dml_version) -{ - - Assert(NULL != ddl_version); - Assert(NULL != dml_version); - - Cache *mdver_glob_mdvsn = mdver_get_glob_mdvsn(); - Assert(NULL != mdver_glob_mdvsn); - - mdver_entry entry = {key, INVALID_MD_VERSION, INVALID_MD_VERSION}; - - /* FIXME gcaragea 06/03/2014: Trigger evictions if cache is full (MPP-22923) */ - CacheEntry *localEntry = Cache_AcquireEntry(mdver_glob_mdvsn, &entry); - - Assert(NULL != localEntry); - - /* - * We're about to look-up and insert a shared cache entry. - * Grab writer lock in exclusive mode, so that no other backend - * can insert or update the same entry at the same time. - */ - LWLockAcquire(MDVerWriteLock, LW_EXCLUSIVE); - - CacheEntry *cachedEntry = Cache_Lookup(mdver_glob_mdvsn, localEntry); - - if (NULL != cachedEntry) - { - /* Not found in LVSN, not nuke happened, eventually found in GVSN */ - mdver_entry *crt_entry = CACHE_ENTRY_PAYLOAD(cachedEntry); - - *ddl_version = crt_entry->ddl_version; - *dml_version = crt_entry->dml_version; - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Found version in Global MDVSN: (%d, " UINT64_FORMAT ", " UINT64_FORMAT "). Adding it to Local MDVSN", - key, crt_entry->ddl_version, crt_entry->dml_version); -#endif - - /* - * We're also done with the entry, release our pincount on it - * - * TODO gcaragea 05/02/2014: Are there cases where we need to hold the - * entry past this point? (MPP-22923) - */ - - Cache_Release(mdver_glob_mdvsn, cachedEntry); - } - else - { - /* Not found in LVSN, not nuke happened, not found in GVSN either */ - - /* Generate new version */ - *ddl_version = mdver_next_global_version(); - *dml_version = mdver_next_global_version(); - - /* Add to GVSN */ - mdver_entry *new_entry = CACHE_ENTRY_PAYLOAD(localEntry); - new_entry->ddl_version = *ddl_version; - new_entry->dml_version = *dml_version; - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Inserting new version in Global MDVSN: (%d, " UINT64_FORMAT ", " UINT64_FORMAT "). Adding it to Local MDVSN", - key, new_entry->ddl_version, new_entry->dml_version); -#endif - - Cache_Insert(mdver_glob_mdvsn, localEntry); - - } - - LWLockRelease(MDVerWriteLock); - - /* Release local entry. We don't need it anymore */ - Cache_Release(mdver_glob_mdvsn, localEntry); -} - -/* - * When a backend is requesting the more recent version of an object, - * if the Local MDVSN cache doesn't have the version, and if a NUKE event - * has been encountered in the current transaction, a new version is - * generated and returned for the object. A new versioning event is also - * produced. - * - * key: The key of the looked-up object - * ddl_version: used to return the ddl version for the object - * dml_version: used to return the dml version for the object - * - */ -static void -mdver_request_after_nuke(Oid key, uint64 *ddl_version, uint64 *dml_version) -{ - Assert(NULL != ddl_version); - Assert(NULL != dml_version); - - /* Generate new version */ - *ddl_version = mdver_next_global_version(); - *dml_version = mdver_next_global_version(); - - mdver_event *new_event = (mdver_event *) palloc0(sizeof(mdver_event)); - new_event->key = key; - new_event->new_ddl_version = *ddl_version; - new_event->new_dml_version = *dml_version; - new_event->old_ddl_version = INVALID_MD_VERSION; - new_event->old_dml_version = INVALID_MD_VERSION; - -#ifdef MD_VERSIONING_INSTRUMENTATION - /* Add my current process id as the originating backend pid */ - new_event->backend_pid = MyProcPid; -#endif - - /* Annotate Versioning Event with the current version from Global MDVSN if exists */ - mdver_entry *crt_entry = mdver_glob_mdvsn_find(key); - if (NULL != crt_entry) - { - new_event->old_ddl_version = crt_entry->ddl_version; - new_event->old_dml_version = crt_entry->dml_version; - } - - CacheAddVersioningEvent(new_event); - -#ifdef MD_VERSIONING_INSTRUMENTATION - char *mdev_str = mdver_event_str(new_event); - ereport(gp_mdversioning_loglevel, - (errmsg("mdver_consume_after_nuke: generated new VE %s", - mdev_str), - errprintstack(false))); - pfree(mdev_str); -#endif - - /* A copy of the event is added to the queue above. We can pfree our local copy */ - pfree(new_event); -} - - -/* - * Retrieves the next unique version using the Global Version Counter (GVC) - */ -uint64 -mdver_next_global_version() -{ - return gp_atomic_add_uint64(mdver_global_version_counter, 1); -} - -/* - * Returns true if Metadata Versioning is enabled in the current - * context - */ -bool -mdver_enabled(void) -{ - /* - * We only initialized Metadata Versioning on the master, - * and only for QD or utility mode process. - * MD Versioning can also be disabled by the guc gp_metadata_versioning. - */ - - /* TODO gcaragea 05/06/2014: Do we need to disable MD Versioning during (auto)vacuum? (MPP-23504) */ - - return gp_metadata_versioning && - AmIMaster() && - ((GP_ROLE_DISPATCH == Gp_role) || (GP_ROLE_UTILITY == Gp_role)); -} diff --git a/src/backend/utils/mdver/test/.gitignore b/src/backend/utils/mdver/test/.gitignore deleted file mode 100644 index a8d6b6c195..0000000000 --- a/src/backend/utils/mdver/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.t diff --git a/src/backend/utils/mdver/test/Makefile b/src/backend/utils/mdver/test/Makefile deleted file mode 100644 index 996e997eea..0000000000 --- a/src/backend/utils/mdver/test/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -top_builddir=../../../../.. -subdir=src/backend/utils/mdver - -TARGETS=mdver_dep_translator - -mdver_dep_translator_REAL_OBJS=\ - $(top_srcdir)/src/backend/access/hash/hashfunc.o \ - $(top_srcdir)/src/backend/bootstrap/bootparse.o \ - $(top_srcdir)/src/backend/lib/stringinfo.o \ - $(top_srcdir)/src/backend/nodes/bitmapset.o \ - $(top_srcdir)/src/backend/nodes/equalfuncs.o \ - $(top_srcdir)/src/backend/nodes/list.o \ - $(top_srcdir)/src/backend/parser/gram.o \ - $(top_srcdir)/src/backend/regex/regcomp.o \ - $(top_srcdir)/src/backend/regex/regerror.o \ - $(top_srcdir)/src/backend/regex/regexec.o \ - $(top_srcdir)/src/backend/regex/regfree.o \ - $(top_srcdir)/src/backend/storage/page/itemptr.o \ - $(top_srcdir)/src/backend/utils/adt/datum.o \ - $(top_srcdir)/src/backend/utils/adt/like.o \ - $(top_srcdir)/src/backend/utils/hash/dynahash.o \ - $(top_srcdir)/src/backend/utils/hash/hashfn.o \ - $(top_srcdir)/src/backend/utils/mb/mbutils.o \ - $(top_srcdir)/src/backend/utils/mb/wchar.o \ - $(top_srcdir)/src/backend/utils/misc/guc.o \ - $(top_srcdir)/src/backend/utils/init/globals.o \ - $(top_srcdir)/src/port/pgsleep.o \ - $(top_srcdir)/src/port/path.o \ - $(top_srcdir)/src/port/pgstrcasecmp.o \ - $(top_srcdir)/src/port/qsort.o \ - $(top_srcdir)/src/port/strlcpy.o \ - $(top_srcdir)/src/port/thread.o \ - $(top_srcdir)/src/timezone/localtime.o \ - $(top_srcdir)/src/timezone/strftime.o \ - $(top_srcdir)/src/timezone/pgtz.o - -include ../../../../Makefile.mock - diff --git a/src/backend/utils/mdver/test/mdver_dep_translator_test.c b/src/backend/utils/mdver/test/mdver_dep_translator_test.c deleted file mode 100644 index da94176bd3..0000000000 --- a/src/backend/utils/mdver/test/mdver_dep_translator_test.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include -#include -#include -#include "cmockery.h" - -#include "c.h" -#include "postgres.h" - -#include "../mdver_dep_translator.c" - - -/* ==================== mdver_add_nuke_event ==================== */ -/* - * Tests that mdver_add_nuke_event doesn't do anything when passed - * a NIL event list - */ -void test__mdver_add_nuke_event_nil(void **state) -{ - List *events = NIL; - mdver_add_nuke_event(&events); -} - -/* - * Tests that mdver_add_nuke_event adds an event when the last - * event is not nuke - */ -void test__mdver_add_nuke_event_no_nuke(void **state) -{ - - /* Create an empty list of events */ - List *events = NIL; - - /* Let's create some non-nuke event and add it to the list */ - mdver_event *mdev = (mdver_event *) palloc0(sizeof(mdver_event)); - mdev->key = 100; - mdev->new_ddl_version = 1; - mdev->new_dml_version = 2; - events = lappend(events, mdev); - - /* Now add a nuke event */ - mdver_add_nuke_event(&events); - - /* Adding the nuke increased the length, it should be 2 */ - assert_int_equal(2 /* length */, length(events)); - -} - -/* - * Tests that mdver_add_nuke_event adds an event when the last - * event is not nuke - */ -void test__mdver_add_nuke_event_after_nuke(void **state) -{ - /* Create an empty list of events */ - List *events = NIL; - - /* Let's create some non-nuke event and add it to the list */ - mdver_event *mdev = (mdver_event *) palloc0(sizeof(mdver_event)); - mdev->key = 100; - mdev->new_ddl_version = 1; - mdev->new_dml_version = 2; - events = lappend(events, mdev); - - /* Create a nuke event and add it to the list */ - mdev = (mdver_event *) palloc0(sizeof(mdver_event)); - mdev->key = MDVER_NUKE_KEY; - events = lappend(events, mdev); - - /* Now add a nuke event */ - mdver_add_nuke_event(&events); - - /* Adding the nuke shouldn't have changed the length - it's still 2 */ - assert_int_equal(2 /* length */, length(events)); -} - -int -main(int argc, char* argv[]) { - cmockery_parse_arguments(argc, argv); - - const UnitTest tests[] = { - unit_test(test__mdver_add_nuke_event_nil), - unit_test(test__mdver_add_nuke_event_no_nuke), - unit_test(test__mdver_add_nuke_event_after_nuke) - }; - return run_tests(tests); -} - - diff --git a/src/include/gpopt/utils/gpdbdefs.h b/src/include/gpopt/utils/gpdbdefs.h index e9af2b5a2e..bd45930c39 100644 --- a/src/include/gpopt/utils/gpdbdefs.h +++ b/src/include/gpopt/utils/gpdbdefs.h @@ -82,7 +82,6 @@ extern "C" { #include "utils/selfuncs.h" #include "postmaster/identity.h" #include "utils/faultinjector.h" -#include "utils/mdver.h" extern Query *preprocess_query_optimizer(Query *pquery, ParamListInfo boundParams); diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h index 8420fb188f..8b472278fd 100644 --- a/src/include/storage/sinval.h +++ b/src/include/storage/sinval.h @@ -16,8 +16,6 @@ #include "storage/itemptr.h" #include "storage/relfilenode.h" -#include "utils/mdver.h" - /* * We currently support three types of shared-invalidation messages: one that @@ -75,28 +73,12 @@ typedef struct RelFileNode rnode; /* physical file ID */ } SharedInvalSmgrMsg; -/* - * TODO gcaragea 03/26/2014: Investigate if there is any impact on performance - * or memory footprint from adding the versioning event to the - * SharedInvalidationMessage union (MPP-23070) - */ - -#define SHAREDVERSIONINGMSG_ID (-3) - -typedef struct -{ - int32 id; /* type field --- must be first */ - bool local; /* true for events that were generated locally */ - mdver_event verEvent; /* versioning event information */ -} SharedVersioningMsg; - typedef union { int32 id; /* type field --- must be first */ SharedInvalCatcacheMsg cc; SharedInvalRelcacheMsg rc; SharedInvalSmgrMsg sm; - SharedVersioningMsg ve; } SharedInvalidationMessage; @@ -110,10 +92,6 @@ extern void ReceiveSharedInvalidMessages( void (*invalFunction) (SharedInvalidationMessage *msg), void (*resetFunction) (void)); -extern void mdver_globalhandler_new_event(SharedInvalidationMessage *messages, int n); - -extern void mdver_localhandler_new_event(SharedInvalidationMessage *msg); - /* signal handler for catchup events (PROCSIG_CATCHUP_INTERRUPT) */ extern void HandleCatchupInterrupt(void); diff --git a/src/include/utils/inval.h b/src/include/utils/inval.h index 06f108b820..5547ffe0b1 100644 --- a/src/include/utils/inval.h +++ b/src/include/utils/inval.h @@ -16,7 +16,6 @@ #include "access/htup.h" #include "utils/rel.h" -#include "utils/mdver.h" typedef void (*CacheCallbackFunction) (Datum arg, Oid relid); @@ -57,8 +56,6 @@ extern void inval_twophase_postcommit(TransactionId xid, uint16 info, extern void ResetSystemCaches(void); -extern void CacheAddVersioningEvent(mdver_event *mdev); - /* Enum for system cache invalidation mode */ typedef enum SysCacheFlushForce { diff --git a/src/include/utils/mdver.h b/src/include/utils/mdver.h deleted file mode 100644 index 5114aaefef..0000000000 --- a/src/include/utils/mdver.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/*------------------------------------------------------------------------- - * - * mdver.h - * Interface for metadata versioning - * - * - *------------------------------------------------------------------------- - */ -#ifndef __MDVER_H__ -#define __MDVER_H__ - -#include "postgres.h" -#include "utils/relcache.h" -#include "utils/sharedcache.h" - -#define INVALID_MD_VERSION 0 - -/* We use Oid = InvalidOid to signal that it's a NUKE event */ -#define MDVER_NUKE_KEY InvalidOid - -typedef struct mdver_entry -{ - Oid key; /* Key of the versioned entry */ - uint64 ddl_version; /* The ddl version of the entry */ - uint64 dml_version; /* The dml version of the entry */ -} mdver_entry; - -typedef struct mdver_event -{ - Oid key; /* Key of the versioned entry */ -#ifdef MD_VERSIONING_INSTRUMENTATION - int backend_pid; /* The PID of the originating backend */ -#endif - uint64 old_ddl_version; /* The ddl version of the entry before this update */ - uint64 old_dml_version; /* The dml version of the entry before this update */ - uint64 new_ddl_version; /* The ddl version of the entry after this update */ - uint64 new_dml_version; /* The dml version of the entry after this update */ -} mdver_event; - -typedef struct mdver_local_mdvsn -{ - HTAB *htable; - bool nuke_happened; -} mdver_local_mdvsn; - -/* Pointer to the shared memory global version counter (GVC) */ -extern uint64 *mdver_global_version_counter; - -/* MD Versioning shared memory initialization */ -void mdver_shmem_init(void); -Size mdver_shmem_size(void); - -/* MD Versioning Global MDVSN operations */ -Cache *mdver_get_glob_mdvsn(void); -mdver_entry *mdver_glob_mdvsn_find(Oid oid); -void mdver_glob_mdvsn_nuke(void); - -/* MD Versioning Local MDVSN operations */ -void mdver_init_session_mdvsn(void); -mdver_local_mdvsn *mdver_create_local_mdvsn(int nesting_level); -void mdver_destroy_local_mdvsn(mdver_local_mdvsn *local_mdvsn, int nesting_level); -mdver_entry *mdver_local_mdvsn_find(mdver_local_mdvsn *local_mdvsn, Oid key); -void mdver_local_mdvsn_add(mdver_local_mdvsn *local_mdvsn, mdver_entry *entry, bool local); -void mdver_local_mdvsn_nuke(mdver_local_mdvsn *local_mdvsn); - -/* MD Versioning Dependency Translator operations */ -void mdver_dt_catcache_inval(Relation relation, HeapTuple tuple, SysCacheInvalidateAction action); -bool mdver_is_nuke_event(const mdver_event *event); - -/* MD Version operations */ -uint64 mdver_next_global_version(void); -void mdver_request_version(Oid key, uint64 *ddl_version, uint64 *dml_version); -bool mdver_enabled(void); - -/* inval.c */ -extern mdver_local_mdvsn *GetCurrentLocalMDVSN(void); - -/* Debugging functions */ - -/* Maximum length for the string representation of a mdver_event */ -#define MDVER_EVENT_STR_LEN 256 -char *mdver_event_str(mdver_event *ev); - -#endif /* __MDVER_H__ */ - -/* EOF */ From 792723139bec40cc8aa78abcb9599739f56402ed Mon Sep 17 00:00:00 2001 From: George Caragea Date: Tue, 12 Jan 2016 11:43:39 -0800 Subject: [PATCH 2/3] [HAWQ-333] Removed unit test relevant to Metadata Versioning --- src/backend/utils/cache/test/.gitignore | 1 - src/backend/utils/cache/test/Makefile | 39 --- src/backend/utils/cache/test/inval_test.c | 400 ---------------------- 3 files changed, 440 deletions(-) delete mode 100644 src/backend/utils/cache/test/.gitignore delete mode 100644 src/backend/utils/cache/test/Makefile delete mode 100644 src/backend/utils/cache/test/inval_test.c diff --git a/src/backend/utils/cache/test/.gitignore b/src/backend/utils/cache/test/.gitignore deleted file mode 100644 index a8d6b6c195..0000000000 --- a/src/backend/utils/cache/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.t diff --git a/src/backend/utils/cache/test/Makefile b/src/backend/utils/cache/test/Makefile deleted file mode 100644 index cd5c007144..0000000000 --- a/src/backend/utils/cache/test/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -top_builddir=../../../../.. -subdir=src/backend/utils/cache - -TARGETS=inval - -inval_REAL_OBJS=\ - $(top_srcdir)/src/backend/access/hash/hashfunc.o \ - $(top_srcdir)/src/backend/bootstrap/bootparse.o \ - $(top_srcdir)/src/backend/lib/stringinfo.o \ - $(top_srcdir)/src/backend/nodes/bitmapset.o \ - $(top_srcdir)/src/backend/nodes/equalfuncs.o \ - $(top_srcdir)/src/backend/nodes/list.o \ - $(top_srcdir)/src/backend/parser/gram.o \ - $(top_srcdir)/src/backend/regex/regcomp.o \ - $(top_srcdir)/src/backend/regex/regerror.o \ - $(top_srcdir)/src/backend/regex/regexec.o \ - $(top_srcdir)/src/backend/regex/regfree.o \ - $(top_srcdir)/src/backend/storage/page/itemptr.o \ - $(top_srcdir)/src/backend/utils/adt/datum.o \ - $(top_srcdir)/src/backend/utils/adt/like.o \ - $(top_srcdir)/src/backend/utils/hash/dynahash.o \ - $(top_srcdir)/src/backend/utils/hash/hashfn.o \ - $(top_srcdir)/src/backend/utils/mb/mbutils.o \ - $(top_srcdir)/src/backend/utils/mb/wchar.o \ - $(top_srcdir)/src/backend/utils/misc/guc.o \ - $(top_srcdir)/src/backend/utils/init/globals.o \ - $(top_srcdir)/src/port/pgsleep.o \ - $(top_srcdir)/src/port/path.o \ - $(top_srcdir)/src/port/pgstrcasecmp.o \ - $(top_srcdir)/src/port/qsort.o \ - $(top_srcdir)/src/port/strlcpy.o \ - $(top_srcdir)/src/port/thread.o \ - $(top_srcdir)/src/timezone/localtime.o \ - $(top_srcdir)/src/timezone/strftime.o \ - $(top_srcdir)/src/timezone/pgtz.o \ - $(top_srcdir)/src/backend/utils/mdver/mdver_dep_translator.o - -include ../../../../Makefile.mock - diff --git a/src/backend/utils/cache/test/inval_test.c b/src/backend/utils/cache/test/inval_test.c deleted file mode 100644 index 877e8c0d02..0000000000 --- a/src/backend/utils/cache/test/inval_test.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include -#include -#include -#include "cmockery.h" - -#include "c.h" -#include "postgres.h" - -#include "../inval.c" - -#if defined(__i386) -#define TRANS_INVALIDATION_INFO_SIZE 40 -#define INVALIDATION_LIST_HEADER_SIZE 12 -#define INVALIDATION_CHUNK_SIZE 56 -#elif defined(__x86_64__) -#define TRANS_INVALIDATION_INFO_SIZE 80 -#define INVALIDATION_LIST_HEADER_SIZE 24 -#define INVALIDATION_CHUNK_SIZE 64 -#else -#error unsupported platform: only x86 and x86_64 supported by this test -#endif - - -/* - * Tests that the size of the data structures used for the transaction - * invalidation information has not changed. - * - * Background: To test metadata versioning, these structures are also - * declared in the test UDF that lives in tincrepo (mdversion_test.c). - * - * This test will fail if any change is made to these structs in the product - * If that happens, two things are needed: - * - update the sizes here to reflect the new definition - * - update the definitions in mdversion_test.c (in tincrepo) - * - */ -void -test__sizeof__TransInvalidationInfo(void **state) -{ - assert_true(sizeof(TransInvalidationInfo) == TRANS_INVALIDATION_INFO_SIZE); -} - - -void -test__sizeof__InvalidationListHeader(void **state) -{ - assert_true(sizeof(InvalidationListHeader) == INVALIDATION_LIST_HEADER_SIZE); -} - -void -test__sizeof__InvalidationChunk(void **state) -{ - assert_true(sizeof(InvalidationChunk) == INVALIDATION_CHUNK_SIZE); -} - - -/* ==================== InvalidateSystemCaches ==================== */ -/* - * Tests that InvalidateSystemCaches resets the local MDVSN cache when - * MD Versioning is enabled - */ -void test__InvalidateSystemCaches__resets_mdvsn_enabled(void **state) -{ - will_be_called(ResetCatalogCaches); - will_be_called(RelationCacheInvalidate); - - /* - * Initialize a fake transInvalInfo and transInvalInfo->local_mdvsn. - * They are used by GetCurrentLocalMDVSN() - */ - mdver_local_mdvsn local_mdvsn_fake; - TransInvalidationInfo transInvalInfo_fake; - transInvalInfo_fake.local_mdvsn = &local_mdvsn_fake; - transInvalInfo = &transInvalInfo_fake; - - will_return(mdver_enabled, true); - - expect_value(mdver_local_mdvsn_nuke, local_mdvsn, &local_mdvsn_fake); - will_be_called(mdver_local_mdvsn_nuke); - - InvalidateSystemCaches(); -} - -/* - * Tests that InvalidateSystemCaches does not reset the local MDVSN cache when - * MD Versioning is disabled - */ -void test__InvalidateSystemCaches__resets_mdvsn_disabled(void **state) -{ - will_be_called(ResetCatalogCaches); - will_be_called(RelationCacheInvalidate); - - /* - * Initialize a fake transInvalInfo and transInvalInfo->local_mdvsn. - * They are used by GetCurrentLocalMDVSN() - */ - mdver_local_mdvsn local_mdvsn_fake; - TransInvalidationInfo transInvalInfo_fake; - transInvalInfo_fake.local_mdvsn = &local_mdvsn_fake; - transInvalInfo = &transInvalInfo_fake; - - will_return(mdver_enabled, false); - - InvalidateSystemCaches(); - - /* - * Part of the test we're implicitly asserting that mdver_local_mdvsn_nuke - * does not get called in this scenario. - */ -} - -/* - * Tests that InvalidateSystemCaches does not reset the local MDVSN cache when - * there is no transaction invalidation information (not in a transaction, special - * backend) - */ -void test__InvalidateSystemCaches__resets_mdvsn_no_xact(void **state) -{ - will_be_called(ResetCatalogCaches); - will_be_called(RelationCacheInvalidate); - - /* - * Set transInvalInfo to NULL to simulate an case where we don't have - * a transaction invalidation information (e.g. auxiliary process) - */ - transInvalInfo = NULL; - - InvalidateSystemCaches(); - - /* - * Part of the test we're implicitly asserting that mdver_local_mdvsn_nuke - * does not get called in this scenario. - */ -} - - -/* Helper functions for the MdVer queue pre-processing */ - -/* - * Creates a new invalidation list, and adds a new empty chunk to it - */ -static InvalidationListHeader * -create_list_one_chunk(void) { - InvalidationListHeader *hdr = (InvalidationListHeader *) palloc0(sizeof(InvalidationListHeader)); - - /* Create a chunk */ - InvalidationChunk *first_chunk = (InvalidationChunk *) - palloc0(sizeof(InvalidationChunk) + - (FIRSTCHUNKSIZE - 1) *sizeof(SharedInvalidationMessage)); - - first_chunk->nitems = 0; - first_chunk->maxitems = FIRSTCHUNKSIZE; - first_chunk->next = NULL; - - hdr->velist = first_chunk; - return hdr; -} - -/* - * Adds a new event to an existing InvalidationChunk. - * If is_nuke is true, adds a nuke event. Otherwise, uses the given key - * to populate the event fields. - */ -static void -add_event_to_chunk(InvalidationChunk *chunk, bool is_nuke, int key) { - - /* Create a message */ - SharedInvalidationMessage msg; - msg.ve.id = SHAREDVERSIONINGMSG_ID; - msg.ve.local = true; - if (is_nuke) - { - msg.ve.verEvent.key = MDVER_NUKE_KEY; - msg.ve.verEvent.old_ddl_version = 0; - msg.ve.verEvent.old_dml_version = 0; - msg.ve.verEvent.new_ddl_version = 0; - msg.ve.verEvent.new_dml_version = 0; - } - else - { - msg.ve.verEvent.key = key; - msg.ve.verEvent.old_ddl_version = key + 1; - msg.ve.verEvent.old_dml_version = key + 2; - msg.ve.verEvent.new_ddl_version = key + 3; - msg.ve.verEvent.new_dml_version = key + 4; - } - - chunk->msgs[chunk->nitems++] = msg; -} - - -/* ==================== MdVer_IsRedundantNukeEvent ==================== */ -/* - * Trivial cases: not a nuke event, or the list is empty - */ -void test__MdVer_IsRedundantNukeEvent__no_action(void **state) -{ - InvalidationListHeader hdr; - hdr.cclist = hdr.rclist = hdr.velist = NULL; - - /* First case, when the event is not a nuke */ - mdver_event *mdev = (mdver_event *) palloc0(sizeof(mdver_event)); - mdev->key = 100; - mdev->new_ddl_version = 1; - mdev->new_dml_version = 2; - - bool result = MdVer_IsRedundantNukeEvent(&hdr, mdev); - assert_false(result); - - /* Second case, when the event is a nuke, but queue is empty */ - mdev->key = MDVER_NUKE_KEY; - result = MdVer_IsRedundantNukeEvent(&hdr, mdev); - assert_false(result); -} - -/* - * Non-trivial case: We have one chunk, with some events. Test that we are - * correctly looking at the last event in the chunk. - */ -void test__MdVer_IsRedundantNukeEvent__chunks(void **state) -{ - InvalidationListHeader *hdr = create_list_one_chunk(); - add_event_to_chunk(hdr->velist, false /* is_nuke */, 100 /* key */); - - - /* Create a new nuke event to be added */ - mdver_event *mdev_nuke = (mdver_event *) palloc0(sizeof(mdver_event)); - mdev_nuke->key = MDVER_NUKE_KEY; - - - /* First case, last event in chunk is not nuke. */ - bool result = MdVer_IsRedundantNukeEvent(hdr, mdev_nuke); - assert_false(result); - - /* Second case, last event in chunk is a nuke. */ - add_event_to_chunk(hdr->velist, true /* is_nuke */, 101); - - result = MdVer_IsRedundantNukeEvent(hdr, mdev_nuke); - assert_true(result); - - /* Multiple chunk case. Let's add a new chunk in the list. */ - InvalidationChunk *second_chunk = (InvalidationChunk *) - palloc0(sizeof(InvalidationChunk) + - (FIRSTCHUNKSIZE - 1) *sizeof(SharedInvalidationMessage)); - second_chunk->nitems = 0; - second_chunk->maxitems = FIRSTCHUNKSIZE; - second_chunk->next = NULL; - - /* Add chunk to the list. List now looks like this: hdr -> first_chunk -> second_chunk */ - hdr->velist->next = second_chunk; - - /* Last message in the list is not a nuke */ - add_event_to_chunk(second_chunk, false /* is_nuke */, 200 /* key */); - - result = MdVer_IsRedundantNukeEvent(hdr, mdev_nuke); - assert_false(result); - - - /* Add a nuke message to the last chunk */ - add_event_to_chunk(second_chunk, true /* is_nuke */, 210 /* key */); - - /* Last message in the list is the last message in first_chunk, which is not a nuke */ - result = MdVer_IsRedundantNukeEvent(hdr, mdev_nuke); - assert_true(result); -} - -/* ==================== MdVer_PreProcessInvalidMsgs ==================== */ -/* - * - */ - -/* Test that when appending a list with no nukes to dest, nothing changes */ -void test__MdVer_PreProcessInvalidMsgs__no_nuke(void **state) -{ - InvalidationListHeader* dest = create_list_one_chunk(); - add_event_to_chunk(dest->velist, false /* is_nuke */, 100 /* key */); - - InvalidationListHeader *src = create_list_one_chunk(); - add_event_to_chunk(src->velist, false /* is_nuke */, 200 /* key */); - add_event_to_chunk(src->velist, false /* is_nuke */, 210 /* key */); - - MdVer_PreProcessInvalidMsgs(dest, src); - - assert_int_equal(dest->velist->nitems, 1); - assert_int_equal(dest->velist->msgs[0].ve.verEvent.key, 100); - - assert_int_equal(src->velist->nitems, 2); - assert_int_equal(src->velist->msgs[0].ve.verEvent.key, 200); - assert_int_equal(src->velist->msgs[1].ve.verEvent.key, 210); - -} - -/* Test that when appending a list with a nuke in first chunk, dest gets updated */ -void test__MdVer_PreProcessInvalidMsgs__nuke_first_chunk(void **state) -{ - InvalidationListHeader* dest = create_list_one_chunk(); - add_event_to_chunk(dest->velist, false /* is_nuke */, 100 /* key */); - - InvalidationListHeader *src = create_list_one_chunk(); - add_event_to_chunk(src->velist, false /* is_nuke */, 200 /* key */); - add_event_to_chunk(src->velist, true /* is_nuke */, 210 /* key */); - add_event_to_chunk(src->velist, false /* is_nuke */, 220 /* key */); - add_event_to_chunk(src->velist, true /* is_nuke */, 230 /* key */); - add_event_to_chunk(src->velist, true /* is_nuke */, 240 /* key */); - add_event_to_chunk(src->velist, false /* is_nuke */, 250 /* key */); - /* src now is: 200->nuke->220->nuke->nuke->250 */ - - MdVer_PreProcessInvalidMsgs(dest, src); - - /* After processing, we should have: - * src: null - * dest: nuke->250 - */ - assert_int_equal(dest->velist->nitems, 2); - assert_int_equal(dest->velist->msgs[0].ve.verEvent.key, MDVER_NUKE_KEY); - assert_int_equal(dest->velist->msgs[1].ve.verEvent.key, 250); - - assert_true(NULL == src->velist); -} - -/* Test that when appending a list with a nuke in second chunk, dest gets updated */ -void test__MdVer_PreProcessInvalidMsgs__nuke_second_chunk(void **state) -{ - InvalidationListHeader* dest = create_list_one_chunk(); - add_event_to_chunk(dest->velist, false /* is_nuke */, 100 /* key */); - - InvalidationListHeader *src = create_list_one_chunk(); - add_event_to_chunk(src->velist, false /* is_nuke */, 200 /* key */); - add_event_to_chunk(src->velist, true /* is_nuke */, 210 /* key */); - - /* Create a chunk */ - InvalidationChunk *second_chunk = (InvalidationChunk *) - palloc0(sizeof(InvalidationChunk) + - (FIRSTCHUNKSIZE - 1) *sizeof(SharedInvalidationMessage)); - second_chunk->nitems = 0; - second_chunk->maxitems = FIRSTCHUNKSIZE; - second_chunk->next = NULL; - - /* Add events to second chunk */ - add_event_to_chunk(second_chunk, false /* is_nuke */, 220 /* key */); - add_event_to_chunk(second_chunk, true /* is_nuke */, 230 /* key */); - add_event_to_chunk(second_chunk, true /* is_nuke */, 240 /* key */); - add_event_to_chunk(second_chunk, false /* is_nuke */, 250 /* key */); - /* src now is: [200->nuke]->[220->nuke->nuke->250] */ - - /* Link second chunk into list */ - src->velist->next = second_chunk; - - MdVer_PreProcessInvalidMsgs(dest, src); - - /* After processing, we should have: - * src: null - * dest: nuke->250 - */ - assert_int_equal(dest->velist->nitems, 2); - assert_int_equal(dest->velist->msgs[0].ve.verEvent.key, MDVER_NUKE_KEY); - assert_int_equal(dest->velist->msgs[1].ve.verEvent.key, 250); - - assert_true(NULL == src->velist); -} - -int -main(int argc, char* argv[]) { - cmockery_parse_arguments(argc, argv); - - const UnitTest tests[] = { - unit_test(test__sizeof__TransInvalidationInfo), - unit_test(test__sizeof__InvalidationListHeader), - unit_test(test__sizeof__InvalidationChunk), - unit_test(test__InvalidateSystemCaches__resets_mdvsn_enabled), - unit_test(test__InvalidateSystemCaches__resets_mdvsn_disabled), - unit_test(test__InvalidateSystemCaches__resets_mdvsn_no_xact), - unit_test(test__MdVer_IsRedundantNukeEvent__no_action), - unit_test(test__MdVer_IsRedundantNukeEvent__chunks), - unit_test(test__MdVer_PreProcessInvalidMsgs__no_nuke), - unit_test(test__MdVer_PreProcessInvalidMsgs__nuke_first_chunk), - unit_test(test__MdVer_PreProcessInvalidMsgs__nuke_second_chunk) - }; - return run_tests(tests); -} - - From 2e835ff79db782ad4fa1f54c67544f2aa19a7b26 Mon Sep 17 00:00:00 2001 From: George Caragea Date: Tue, 12 Jan 2016 16:46:29 -0800 Subject: [PATCH 3/3] [HAWQ-333] Removed gucs and instrumentation code for MD Versioning --- configure.in | 5 -- src/backend/access/heap/heapam.c | 28 ----------- src/backend/cdb/cdbvars.c | 2 - src/backend/utils/cache/inval.c | 12 ----- src/backend/utils/misc/guc.c | 79 +------------------------------- src/include/cdb/cdbvars.h | 1 - src/include/pg_config.h.in | 4 -- src/include/utils/guc.h | 1 - 8 files changed, 1 insertion(+), 131 deletions(-) diff --git a/configure.in b/configure.in index feb12f057f..4df5a55790 100644 --- a/configure.in +++ b/configure.in @@ -507,11 +507,6 @@ PGAC_ARG_BOOL(enable, debugntuplestore, no, [ --enable-ntuplestore enable [Define to 1 to build with debug_ntuplestore. (--enable-ntuplestore)])]) -# Enable metadata versioning instrumentation -PGAC_ARG_BOOL(enable, mdverinstrumentation, no, [ --enable-mdverinstrumentation enable metadata versioning instrumentation], - [AC_DEFINE([MD_VERSIONING_INSTRUMENTATION], 1, - [Define to 1 to build with metadata versioning instrumentation. (--enable-mdverinstrumentation)])]) - # # Enable testing utilities # diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index e1205a4f65..b4d4e5c8e3 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2136,13 +2136,6 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, Insist(RelationIsHeap(relation)); -#ifdef MD_VERSIONING_INSTRUMENTATION - if (IsSystemRelation(relation)) - { - elog(gp_mdversioning_loglevel, "CatalogDML: ACTION=INSERT RELATION=%s", relation->rd_rel->relname.data); - } -#endif - // Fetch gp_persistent_relation_node information that will be added to XLOG record. RelationFetchGpRelationNodeForXLog(relation); @@ -2411,13 +2404,6 @@ heap_delete(Relation relation, ItemPointer tid, errmsg("Append-only tables are not updatable. Operation not permitted."), errOmitLocation(true))); -#ifdef MD_VERSIONING_INSTRUMENTATION - if (IsSystemRelation(relation)) - { - elog(gp_mdversioning_loglevel, "CatalogDML: ACTION=DELETE RELATION=%s", relation->rd_rel->relname.data); - } -#endif - // Fetch gp_persistent_relation_node information that will be added to XLOG record. RelationFetchGpRelationNodeForXLog(relation); @@ -3232,13 +3218,6 @@ simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup) ItemPointerData update_ctid; TransactionId update_xmax; -#ifdef MD_VERSIONING_INSTRUMENTATION - if (IsSystemRelation(relation)) - { - elog(gp_mdversioning_loglevel, "CatalogDML: ACTION=UPDATE RELATION=%s", relation->rd_rel->relname.data); - } -#endif - MIRROREDLOCK_BUFMGR_VERIFY_NO_LOCK_LEAK_ENTER; result = heap_update_internal( @@ -3816,13 +3795,6 @@ heap_inplace_update_internal(Relation relation, HeapTuple tuple, TransactionId x */ RelationFetchGpRelationNodeForXLog(relation); -#ifdef MD_VERSIONING_INSTRUMENTATION - if (IsSystemRelation(relation)) - { - elog(gp_mdversioning_loglevel, "CatalogDML: ACTION=INPLACE_UPDATE RELATION=%s", relation->rd_rel->relname.data); - } -#endif - // -------- MirroredLock ---------- MIRROREDLOCK_BUFMGR_LOCK; diff --git a/src/backend/cdb/cdbvars.c b/src/backend/cdb/cdbvars.c index 98c1cf437c..dfa307f09b 100644 --- a/src/backend/cdb/cdbvars.c +++ b/src/backend/cdb/cdbvars.c @@ -416,9 +416,7 @@ int gp_hashagg_compress_spill_files = 0; int gp_workfile_compress_algorithm = 0; bool gp_workfile_checksumming = false; bool gp_workfile_caching = false; -bool gp_metadata_versioning = false; int gp_workfile_caching_loglevel = DEBUG1; -int gp_mdversioning_loglevel = DEBUG1; int gp_sessionstate_loglevel = DEBUG1; /* Maximum disk space to use for workfiles on a segment, in kilobytes */ double gp_workfile_limit_per_segment = 0; diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index 1e330c391f..0a3118be8d 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -362,10 +362,6 @@ AddCatcacheInvalidationMessage(InvalidationListHeader *hdr, msg.cc.dbId = dbId; msg.cc.hashValue = hashValue; AddInvalidationMessage(&hdr->cclist, &msg); - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Invalidation: TYPE=CATCACHE CACHEID=%d ACTION=%d", id, action); -#endif } /* @@ -389,11 +385,6 @@ AddRelcacheInvalidationMessage(InvalidationListHeader *hdr, msg.rc.dbId = dbId; msg.rc.relId = relId; AddInvalidationMessage(&hdr->rclist, &msg); - - -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Invalidation: TYPE=RELCACHE RELID=%d", relId); -#endif } /* @@ -415,9 +406,6 @@ AddSmgrInvalidationMessage(InvalidationListHeader *hdr, msg.sm.id = SHAREDINVALSMGR_ID; msg.sm.rnode = rnode; AddInvalidationMessage(&hdr->rclist, &msg); -#ifdef MD_VERSIONING_INSTRUMENTATION - elog(gp_mdversioning_loglevel, "Invalidation: TYPE=SMGR RELID=%d", rnode.relNode); -#endif } /* diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 3f591d4ced..9e3cddf184 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -502,7 +502,6 @@ static char *log_min_error_statement_str; static char *log_destination_string; static char *gp_log_format_string; static char *gp_workfile_caching_loglevel_str; -static char *gp_mdversioning_loglevel_str; static char *gp_sessionstate_loglevel_str; static char *explain_memory_verbosity_str; @@ -1147,16 +1146,6 @@ static struct config_bool ConfigureNamesBool[] = &gp_workfile_caching, false, NULL, NULL }, - { - {"gp_metadata_versioning", PGC_SUSET, QUERY_TUNING_OTHER, - gettext_noop("Enable metadata versioning"), - gettext_noop("When enabled, catalog objects are versioned" - "and their version is changed only when updated"), - GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE - }, - &gp_metadata_versioning, - false, &assign_gp_metadata_versioning, NULL - }, { {"force_bitmap_table_scan", PGC_USERSET, DEVELOPER_OPTIONS, gettext_noop("Forces bitmap table scan instead of bitmap heap/ao/aoco scan."), @@ -3472,7 +3461,7 @@ static struct config_bool ConfigureNamesBool[] = GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE }, &optimizer_release_mdcache, - true, &assign_optimizer_release_mdcache, NULL + true, NULL, NULL }, { @@ -7150,19 +7139,6 @@ static struct config_string ConfigureNamesString[] = "debug1", assign_gp_workfile_caching_loglevel, NULL }, - { - {"gp_mdversioning_loglevel", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Sets the logging level for metadata versioning debugging messages"), - gettext_noop("Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, " - "DEBUG1, LOG, NOTICE, WARNING, and ERROR. Each level includes all the " - "levels that follow it. The later the level, the fewer messages are " - "sent."), - GUC_GPDB_ADDOPT | GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE - }, - &gp_mdversioning_loglevel_str, - "debug1", assign_gp_mdversioning_loglevel, NULL - }, - { {"gp_sessionstate_loglevel", PGC_SUSET, DEVELOPER_OPTIONS, gettext_noop("Sets the logging level for session state debugging messages"), @@ -12623,13 +12599,6 @@ assign_client_min_messages(const char *newval, bool doit, GucSource source) return (assign_msglvl(&client_min_messages, newval, doit, source)); } -static const char * -assign_gp_mdversioning_loglevel(const char *newval, - bool doit, GucSource source) -{ - return (assign_msglvl(&gp_mdversioning_loglevel, newval, doit, source)); -} - static const char * assign_gp_sessionstate_loglevel(const char *newval, bool doit, GucSource source) @@ -13239,52 +13208,6 @@ assign_transaction_read_only(bool newval, bool doit, GucSource source) } -/* - * Validate that if we disable releasing the MD Cache after each query, - * we must have MD Versioning turned on. - */ -static bool -assign_optimizer_release_mdcache(bool newval, bool doit, GucSource source) -{ - /* - * We want to avoid reaching the following state: - * - optimizer_release_mdcache = off - * - gp_metadata_versioning = off - * Other states are fine. - */ - if (!newval && !gp_metadata_versioning) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot set optimizer_release_mdcache to off when gp_metadata_versioning is off"))); - return false; - } - return true; -} - -/* - * Validate that if we disable MD Versioning, we are releasing the MD Cache - * after each query. - */ -static bool -assign_gp_metadata_versioning(bool newval, bool doit, GucSource source) -{ - /* - * We want to avoid reaching the following state: - * - optimizer_release_mdcache = off - * - gp_metadata_versioning = off - * Other states are fine. - */ - if (!newval && !optimizer_release_mdcache) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot set gp_metadata_versioning to off when optimizer_release_mdcache is off"))); - return false; - } - return true; -} - static const char * assign_canonical_path(const char *newval, bool doit, GucSource source) { diff --git a/src/include/cdb/cdbvars.h b/src/include/cdb/cdbvars.h index bb59d76f2b..123b972984 100644 --- a/src/include/cdb/cdbvars.h +++ b/src/include/cdb/cdbvars.h @@ -972,7 +972,6 @@ extern int gp_hashagg_compress_spill_files; extern int gp_workfile_compress_algorithm; extern bool gp_workfile_checksumming; extern bool gp_workfile_caching; -extern bool gp_metadata_versioning; extern double gp_workfile_limit_per_segment; extern double gp_workfile_limit_per_query; extern int gp_workfile_limit_files_per_query; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index e58636e389..90e1eca7ef 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -707,10 +707,6 @@ /* Define as the maximum alignment requirement of any C data type. */ #undef MAXIMUM_ALIGNOF -/* Define to 1 to build with metadata versioning instrumentation. - (--enable-mdverinstrumentation) */ -#undef MD_VERSIONING_INSTRUMENTATION - /* Define bytes to use libc memset(). */ #undef MEMSET_LOOP_LIMIT diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index b460b3bb74..2cf4ddb810 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -259,7 +259,6 @@ extern bool gp_temporary_files_filespace_repair; extern bool gp_perfmon_print_packet_info; extern bool gp_plpgsql_clear_cache_always; extern bool gp_disable_catalog_access_on_segment; -extern int gp_mdversioning_loglevel; extern bool gp_called_by_pgdump;