greenplumn aocatalog 源码
greenplumn aocatalog 代码
文件路径:/src/backend/catalog/aocatalog.c
/*
* aocatalog.c
*
* Helper function to support the creation of
* append-only auxiliary relations such as block directories and visimaps.
*
* Copyright (c) 2013-Present VMware, Inc. or its affiliates.
*
*
* IDENTIFICATION
* src/backend/catalog/aocatalog.c
*/
#include "postgres.h"
#include "access/heapam.h"
#include "access/xact.h"
#include "catalog/aoblkdir.h"
#include "catalog/aocatalog.h"
#include "catalog/aoseg.h"
#include "catalog/aovisimap.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_am.h"
#include "catalog/pg_appendonly.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "storage/lmgr.h"
#include "utils/builtins.h"
#include "catalog/gp_fastsequence.h"
/*
* Create append-only auxiliary relations for target relation rel.
* Returns true if they are newly created. If pg_appendonly has already
* known those tables, don't create them and returns false.
*/
bool
CreateAOAuxiliaryTable(
Relation rel,
const char *auxiliaryNamePrefix,
char relkind,
TupleDesc tupledesc,
IndexInfo *indexInfo,
List *indexColNames,
Oid *classObjectId,
int16 *coloptions)
{
char aoauxiliary_relname[NAMEDATALEN];
char aoauxiliary_idxname[NAMEDATALEN];
bool shared_relation;
bool mapped_relation;
Oid relOid, aoauxiliary_relid = InvalidOid;
Oid aoauxiliary_idxid = InvalidOid;
ObjectAddress baseobject;
ObjectAddress aoauxiliaryobject;
Oid namespaceid;
Assert(RelationIsValid(rel));
Assert(RelationIsAppendOptimized(rel));
Assert(auxiliaryNamePrefix);
Assert(tupledesc);
if (relkind != RELKIND_AOSEGMENTS)
Assert(indexInfo);
shared_relation = rel->rd_rel->relisshared;
/*
* We cannot allow creating an auxiliary table for a shared relation
* after initdb (because there's no way to let other databases know
* this visibility map.
*/
if (shared_relation && !IsBootstrapProcessingMode())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("shared tables cannot have append-only auxiliary relations after initdb")));
/* It's mapped if and only if its parent is, too */
mapped_relation = RelationIsMapped(rel);
relOid = RelationGetRelid(rel);
switch(relkind)
{
case RELKIND_AOVISIMAP:
GetAppendOnlyEntryAuxOids(relOid, NULL, NULL,
NULL, NULL, &aoauxiliary_relid, &aoauxiliary_idxid);
break;
case RELKIND_AOBLOCKDIR:
GetAppendOnlyEntryAuxOids(relOid, NULL, NULL,
&aoauxiliary_relid, &aoauxiliary_idxid, NULL, NULL);
break;
case RELKIND_AOSEGMENTS:
GetAppendOnlyEntryAuxOids(relOid, NULL,
&aoauxiliary_relid,
NULL, NULL, NULL, NULL);
break;
default:
elog(ERROR, "unsupported auxiliary relkind '%c'", relkind);
}
/*
* Does it have the auxiliary relation?
*/
if (OidIsValid(aoauxiliary_relid))
{
return false;
}
snprintf(aoauxiliary_relname, sizeof(aoauxiliary_relname),
"%s_%u", auxiliaryNamePrefix, relOid);
snprintf(aoauxiliary_idxname, sizeof(aoauxiliary_idxname),
"%s_%u_index", auxiliaryNamePrefix, relOid);
/*
* Aux tables for regular relations go in pg_aoseg; those for temp
* relations go into the per-backend temp-toast-table namespace.
*/
if (RelationUsesTempNamespace(rel))
namespaceid = GetTempToastNamespace();
else
namespaceid = PG_AOSEGMENT_NAMESPACE;
/*
* We place auxiliary relation in the pg_aoseg namespace
* even if its master relation is a temp table. There cannot be
* any naming collision, and the auxiliary relation will be
* destroyed when its master is, so there is no need to handle
* the aovisimap relation as temp.
*/
aoauxiliary_relid = heap_create_with_catalog(aoauxiliary_relname,
namespaceid,
rel->rd_rel->reltablespace,
InvalidOid,
InvalidOid,
InvalidOid,
rel->rd_rel->relowner,
HEAP_TABLE_AM_OID,
tupledesc,
NIL,
relkind,
rel->rd_rel->relpersistence,
shared_relation,
mapped_relation,
ONCOMMIT_NOOP,
NULL, /* GP Policy */
(Datum) 0,
/* use_user_acl */ false,
true,
true,
InvalidOid,
NULL, /* typeaddress */
/* valid_opts */ false);
/* Make this table visible, else index creation will fail */
CommandCounterIncrement();
/* Create an index on AO auxiliary tables (like visimap) except for pg_aoseg table */
if (relkind != RELKIND_AOSEGMENTS)
{
Oid *collationObjectId;
Relation aoauxiliary_rel;
/* ShareLock is not really needed here, but take it anyway */
aoauxiliary_rel = table_open(aoauxiliary_relid, ShareLock);
collationObjectId = palloc0(list_length(indexColNames) * sizeof(Oid));
aoauxiliary_idxid = index_create(aoauxiliary_rel,
aoauxiliary_idxname,
InvalidOid,
InvalidOid,
InvalidOid,
InvalidOid,
indexInfo,
indexColNames,
BTREE_AM_OID,
rel->rd_rel->reltablespace,
collationObjectId, classObjectId, coloptions, (Datum) 0,
INDEX_CREATE_IS_PRIMARY, 0, true, true, NULL);
/* Unlock target table -- no one can see it */
table_close(aoauxiliary_rel, ShareLock);
/* Unlock the index -- no one can see it anyway */
UnlockRelationOid(aoauxiliary_idxid, AccessExclusiveLock);
}
/*
* Store the auxiliary table's OID in the parent relation's pg_appendonly row.
* TODO (How to generalize this?)
*/
switch (relkind)
{
case RELKIND_AOVISIMAP:
UpdateAppendOnlyEntryAuxOids(relOid, InvalidOid,
InvalidOid, InvalidOid,
aoauxiliary_relid, aoauxiliary_idxid);
break;
case RELKIND_AOBLOCKDIR:
UpdateAppendOnlyEntryAuxOids(relOid, InvalidOid,
aoauxiliary_relid, aoauxiliary_idxid,
InvalidOid, InvalidOid);
break;
case RELKIND_AOSEGMENTS:
/* Add initial entries in gp_fastsequence */
InsertInitialFastSequenceEntries(aoauxiliary_relid);
UpdateAppendOnlyEntryAuxOids(relOid,
aoauxiliary_relid,
InvalidOid, InvalidOid,
InvalidOid, InvalidOid);
break;
default:
elog(ERROR, "unsupported auxiliary relkind '%c'", relkind);
}
/*
* Register dependency from the auxiliary table to the master, so that the
* aoseg table will be deleted if the master is.
*/
baseobject.classId = RelationRelationId;
baseobject.objectId = relOid;
baseobject.objectSubId = 0;
aoauxiliaryobject.classId = RelationRelationId;
aoauxiliaryobject.objectId = aoauxiliary_relid;
aoauxiliaryobject.objectSubId = 0;
recordDependencyOn(&aoauxiliaryobject, &baseobject, DEPENDENCY_INTERNAL);
/*
* Make changes visible
*/
CommandCounterIncrement();
return true;
}
bool
IsAppendonlyMetadataRelkind(const char relkind) {
return (relkind == RELKIND_AOSEGMENTS ||
relkind == RELKIND_AOBLOCKDIR ||
relkind == RELKIND_AOVISIMAP);
}
void
NewRelationCreateAOAuxTables(Oid relOid, bool createBlkDir)
{
AlterTableCreateAoSegTable(relOid);
AlterTableCreateAoVisimapTable(relOid);
if (createBlkDir)
AlterTableCreateAoBlkdirTable(relOid);
}
相关信息
相关文章
greenplumn gp_partition_template 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦