From 909febe892c89cc3e5a41f50740112e7fe252bcb Mon Sep 17 00:00:00 2001 From: yujiang Date: Mon, 3 Aug 2020 14:57:33 +0800 Subject: [PATCH] fix the issue: failed alloc memory when create many interval partitions in a transaction Signed-off-by: yujiang --- src/common/backend/catalog/heap.cpp | 21 +++++++++++++++------ src/common/backend/utils/cache/relcache.cpp | 9 ++++++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/common/backend/catalog/heap.cpp b/src/common/backend/catalog/heap.cpp index 6db766d935..e7bec0ec01 100755 --- a/src/common/backend/catalog/heap.cpp +++ b/src/common/backend/catalog/heap.cpp @@ -5114,8 +5114,12 @@ Oid AddNewIntervalPartition(Relation rel, HeapTuple insertTuple) List* oldRelOptions = NIL; Oid bucketOid; + if (rel->partMap->isDirty) { + CacheInvalidateRelcache(rel); + } + + /* it will accept invalidation messages generated by other sessions in lockRelationForAddIntervalPartition. */ lockRelationForAddIntervalPartition(rel); - RelationInitPartitionMap(rel); partitionRoutingForTuple(rel, insertTuple, u_sess->catalog_cxt.route); /* if the partition exists, return partition's oid */ @@ -5125,7 +5129,7 @@ Oid AddNewIntervalPartition(Relation rel, HeapTuple insertTuple) return u_sess->catalog_cxt.route->partitionId; } - /* check 1: can not add more partition, because more enough */ + /* can not add more partition, because more enough */ if ((getNumberOfPartitions(rel) + 1) > MAX_PARTITION_NUM) { ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), @@ -5133,7 +5137,7 @@ Oid AddNewIntervalPartition(Relation rel, HeapTuple insertTuple) errhint("Number of partitions can not be more than %d", MAX_PARTITION_NUM))); } - /* check 5: whether has the unusable local index */ + /* whether has the unusable local index */ if (!checkRelationLocalIndexesUsable(rel)) { ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), @@ -5144,7 +5148,7 @@ Oid AddNewIntervalPartition(Relation rel, HeapTuple insertTuple) pgPartRel = relation_open(PartitionRelationId, RowExclusiveLock); - /* step 2: add new partition entry in pg_partition */ + /* add new partition entry in pg_partition */ /* TRANSFORM into target first */ tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(rel->rd_id)); relOptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isNull); @@ -5172,13 +5176,18 @@ Oid AddNewIntervalPartition(Relation rel, HeapTuple insertTuple) addIndexForPartition(rel, newPartOid); addToastTableForNewPartition(rel, newPartOid); - /* step 4: invalidate relation */ + /* invalidate relation */ CacheInvalidateRelcache(rel); - RelationInitPartitionMap(rel); /* close relation, done */ relation_close(pgPartRel, NoLock); + /* + * We must bump the command counter to make the newly-created + * table partition visible for using. + */ + CommandCounterIncrement(); + return newPartOid; } diff --git a/src/common/backend/utils/cache/relcache.cpp b/src/common/backend/utils/cache/relcache.cpp index e1d5628c58..c43a66c9c9 100644 --- a/src/common/backend/utils/cache/relcache.cpp +++ b/src/common/backend/utils/cache/relcache.cpp @@ -2830,18 +2830,21 @@ static void relation_destroy_partition_map(Relation relation) /* first free partKeyNum/partitionKeyDataType/ranges in the range map */ if (range_map->partitionKey) { pfree_ext(range_map->partitionKey); - range_map->partitionKey = NULL; } if (range_map->partitionKeyDataType) { pfree_ext(range_map->partitionKeyDataType); - range_map->partitionKeyDataType = NULL; + } + if (range_map->intervalValue) { + pfree_ext(range_map->intervalValue); + } + if (range_map->intervalTablespace) { + pfree_ext(range_map->intervalTablespace); } if (range_map->rangeElements) { partition_map_destroy_range_array(range_map->rangeElements, range_map->rangeElementsNum); } } pfree_ext(relation->partMap); - relation->partMap = NULL; return; } -- Gitee