hawq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From y...@apache.org
Subject incubator-hawq git commit: HAWQ-430. HAWQ resource manager prunes those registered segments having different memory to core ratio
Date Wed, 24 Feb 2016 02:34:23 GMT
Repository: incubator-hawq
Updated Branches:
  refs/heads/master 4b84d6580 -> 20d14e3ad


HAWQ-430. HAWQ resource manager prunes those registered segments having different memory to
core ratio


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/20d14e3a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/20d14e3a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/20d14e3a

Branch: refs/heads/master
Commit: 20d14e3adea03b1d206d2ab8fed1c65ccb9ce463
Parents: 4b84d65
Author: YI JIN <yjin@pivotal.io>
Authored: Wed Feb 24 13:34:11 2016 +1100
Committer: YI JIN <yjin@pivotal.io>
Committed: Wed Feb 24 13:34:11 2016 +1100

----------------------------------------------------------------------
 src/backend/resourcemanager/include/envswitch.h |   5 +
 .../resourcemanager/include/resourcepool.h      |  13 +-
 src/backend/resourcemanager/requesthandler.c    |  11 +
 .../resourcemanager/requesthandler_ddl.c        |   5 +-
 src/backend/resourcemanager/resourcemanager.c   |   6 +-
 src/backend/resourcemanager/resourcepool.c      | 408 ++++++++++++++++---
 src/backend/resourcemanager/resqueuemanager.c   |  43 +-
 7 files changed, 413 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/20d14e3a/src/backend/resourcemanager/include/envswitch.h
----------------------------------------------------------------------
diff --git a/src/backend/resourcemanager/include/envswitch.h b/src/backend/resourcemanager/include/envswitch.h
index 7c1e376..e30f53c 100644
--- a/src/backend/resourcemanager/include/envswitch.h
+++ b/src/backend/resourcemanager/include/envswitch.h
@@ -85,4 +85,9 @@
 #include "utils/memutilities.h"	/* Memory context and manipulation wrapper   */
 
 #define RMLOG rm_log_level
+
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
 #endif //ENVIRONMENT_SWITCH_H

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/20d14e3a/src/backend/resourcemanager/include/resourcepool.h
----------------------------------------------------------------------
diff --git a/src/backend/resourcemanager/include/resourcepool.h b/src/backend/resourcemanager/include/resourcepool.h
index 01c97aa..6e1412c 100644
--- a/src/backend/resourcemanager/include/resourcepool.h
+++ b/src/backend/resourcemanager/include/resourcepool.h
@@ -435,9 +435,8 @@ struct ResourcePoolData {
 	 */
 	HASHTABLEData	GRMHostNameIndexed;
 
-	/* The cluster level memory/core ratio. */
-	uint32_t		MemCoreRatio;
-	uint32_t		MemCoreRatioMajorityCounter;
+	/* The fixed cluster level memory to core ratio. */
+	uint32_t		ClusterMemoryCoreRatio;
 
 	/*
 	 * GRM Container life-cycle management.
@@ -656,6 +655,14 @@ void refreshAvailableNodeCount(void);
 
 void checkSlavesFile(void);
 
+void fixClusterMemoryCoreRatio(void);
+void adjustSegmentCapacity(SegResource segres);
+void adjustSegmentStatFTSCapacity(SegStat segstat);
+void adjustSegmentStatGRMCapacity(SegStat segstat);
+void adjustSegmentCapacityForNone(SegResource segres);
+void adjustSegmentCapacityForGRM(SegResource segres);
+void adjustMemoryCoreValue(uint32_t *memorymb, uint32_t *core);
+
 /*
  *------------------------------------------------------------------------------
  * gp_segment_configuration catalog operating APIs.

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/20d14e3a/src/backend/resourcemanager/requesthandler.c
----------------------------------------------------------------------
diff --git a/src/backend/resourcemanager/requesthandler.c b/src/backend/resourcemanager/requesthandler.c
index 675d2fe..f690c8a 100644
--- a/src/backend/resourcemanager/requesthandler.c
+++ b/src/backend/resourcemanager/requesthandler.c
@@ -344,6 +344,17 @@ bool handleRMRequestAcquireResource(void **arg)
 		return false;
 	}
 
+	/*
+	 * If resource queue has no concrete capacity set yet, no need to handle
+	 * the request.
+	 */
+	if ( PQUEMGR->RootTrack->QueueInfo->ClusterMemoryMB <= 0 )
+	{
+		elog(DEBUG3, "Resource manager defers the resource request because the "
+					 "resource queues have no valid resource capacities yet.");
+		return false;
+	}
+
 	RPCRequestHeadAcquireResourceFromRM request =
 		SMBUFF_HEAD(RPCRequestHeadAcquireResourceFromRM,
 					&((*conntrack)->MessageBuff));

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/20d14e3a/src/backend/resourcemanager/requesthandler_ddl.c
----------------------------------------------------------------------
diff --git a/src/backend/resourcemanager/requesthandler_ddl.c b/src/backend/resourcemanager/requesthandler_ddl.c
index 5b3a6c9..48a726c 100644
--- a/src/backend/resourcemanager/requesthandler_ddl.c
+++ b/src/backend/resourcemanager/requesthandler_ddl.c
@@ -429,7 +429,10 @@ bool handleRMDDLRequestManipulateResourceQueue(void **arg)
 			 * Refresh actual capacity of the resource queue, the change is
 			 * expected to be updated in the shadow instances.
 			 */
-			refreshResourceQueuePercentageCapacity(true);
+			if ( PRESPOOL->ClusterMemoryCoreRatio > 0 )
+			{
+				refreshResourceQueuePercentageCapacity(true);
+			}
 
 			/*------------------------------------------------------------------
 			 * Till now, we expect the input for altering a resource queue is

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/20d14e3a/src/backend/resourcemanager/resourcemanager.c
----------------------------------------------------------------------
diff --git a/src/backend/resourcemanager/resourcemanager.c b/src/backend/resourcemanager/resourcemanager.c
index b8a7bb5..0abb99f 100644
--- a/src/backend/resourcemanager/resourcemanager.c
+++ b/src/backend/resourcemanager/resourcemanager.c
@@ -497,6 +497,9 @@ int ResManagerMainServer2ndPhase(void)
 
 	elog(DEBUG5, "HAWQ RM :: passed loading queue and user definition.");
 
+	/* Check slaves file firstly to ensure we have expected cluster size. */
+	checkSlavesFile();
+
 	if ( rm_resourcepool_test_filename != NULL &&
 		 rm_resourcepool_test_filename[0] != '\0' ) {
 		loadHostInformationIntoResourcePool();
@@ -505,9 +508,6 @@ int ResManagerMainServer2ndPhase(void)
 	/******* TILL NOW, resource manager starts providing services *******/
 	elog(LOG, "HAWQ RM process works now.");
 
-	/* Check slaves file firstly to ensure we have expected cluster size. */
-	checkSlavesFile();
-
     /* Start request handler to provide services. */
     res = MainHandlerLoop();
     /* res is returned to the caller. */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/20d14e3a/src/backend/resourcemanager/resourcepool.c
----------------------------------------------------------------------
diff --git a/src/backend/resourcemanager/resourcepool.c b/src/backend/resourcemanager/resourcepool.c
index cb43342..0af5369 100644
--- a/src/backend/resourcemanager/resourcepool.c
+++ b/src/backend/resourcemanager/resourcepool.c
@@ -355,10 +355,6 @@ void initializeResourcePoolManager(void)
 						HASHTABLE_KEYTYPE_SIMPSTR,
 						NULL);
 
-	PRESPOOL->MemCoreRatio 				  = 0;
-	PRESPOOL->MemCoreRatioMajorityCounter = 0;
-
-
 	initializeHASHTABLE(&(PRESPOOL->ToAcceptContainers),
 						PCONTEXT,
 						HASHTABLE_SLOT_VOLUME_DEFAULT,
@@ -398,6 +394,8 @@ void initializeResourcePoolManager(void)
 	}
 
 	PRESPOOL->RBClusterReportCounter = 0;
+
+	PRESPOOL->ClusterMemoryCoreRatio = 0;
 }
 
 #define CONNECT_TIMEOUT 60
@@ -745,6 +743,15 @@ int addHAWQSegWithSegStat(SegStat segstat, bool *capstatchanged)
 	bool			 segcapchanged  = false;
 
 	/*
+	 * Anyway, the host capacity is updated here if the cluster level capacity
+	 * is fixed.
+	 */
+	if ( PRESPOOL->ClusterMemoryCoreRatio > 0 )
+	{
+		adjustSegmentStatFTSCapacity(segstat);
+	}
+
+	/*
 	 * Check if the host information exists in the resource pool. Fetch old
 	 * machine and check if necessary to update.
 	 */
@@ -1117,41 +1124,6 @@ int addHAWQSegWithSegStat(SegStat segstat, bool *capstatchanged)
 		res = RESOURCEPOOL_DUPLICATE_HOST;
 	}
 
-
-	/*
-	 * If host capacity is changed, update the cluster level memory/core ratio.
-	 * The expectation is that more than 50% cluster nodes has the same memory/
-	 * core ratio which is selected as the cluster memory/core ratio.
-	 */
-	if ( segcapchanged )
-	{
-		uint32_t curratio = 0;
-		if ( DRMGlobalInstance->ImpType == NONE_HAWQ2 )
-		{
-			curratio = trunc(segresource->Stat->FTSTotalMemoryMB /
-							 segresource->Stat->FTSTotalCore);
-
-			if ( curratio != PRESPOOL->MemCoreRatio )
-			{
-				PRESPOOL->MemCoreRatioMajorityCounter--;
-				if ( PRESPOOL->MemCoreRatioMajorityCounter == -1 )
-				{
-					PRESPOOL->MemCoreRatioMajorityCounter = 1;
-					PRESPOOL->MemCoreRatio = curratio;
-					elog(LOG, "Resource manager changes cluster memory/core ratio "
-							  "to %d MBPCORE.",
-							  curratio);
-
-
-				}
-			}
-			else
-			{
-				PRESPOOL->MemCoreRatioMajorityCounter++;
-			}
-		}
-	}
-
 	validateResourcePoolStatus(true);
 	return res;
 }
@@ -1167,6 +1139,14 @@ int updateHAWQSegWithGRMSegStat( SegStat segstat)
 	SegStat	 	 	 newSegStat	     = NULL;
 	int32_t		 	 segid			 = SEGSTAT_ID_INVALID;
 
+	/* Anyway, the host GRM capacity is updated here if the cluster level
+	 * capacity is fixed.
+	 */
+	if ( PRESPOOL->ClusterMemoryCoreRatio > 0 )
+	{
+		adjustSegmentStatGRMCapacity(segstat);
+	}
+
 	/*
 	 * Check if the host information exists in the resource pool. Fetch old
 	 * machine and check if necessary to update.
@@ -1305,23 +1285,6 @@ int updateHAWQSegWithGRMSegStat( SegStat segstat)
 						 segres->Stat->GRMTotalCore);
 	}
 
-	if ( curratio != PRESPOOL->MemCoreRatio )
-	{
-		PRESPOOL->MemCoreRatioMajorityCounter--;
-		if ( PRESPOOL->MemCoreRatioMajorityCounter == -1 )
-		{
-			PRESPOOL->MemCoreRatioMajorityCounter = 1;
-			PRESPOOL->MemCoreRatio = curratio;
-			elog(LOG, "Resource manager changes cluster memory/core ratio to "
-						"%d MB Per core.",
-						curratio);
-		}
-	}
-	else
-	{
-		PRESPOOL->MemCoreRatioMajorityCounter++;
-	}
-
 	return FUNC_RETURN_OK;
 }
 
@@ -4230,6 +4193,339 @@ void getSegResResourceCountersByMemCoreCounters(SegResource  resinfo,
 	}
 }
 
+void fixClusterMemoryCoreRatio(void)
+{
+	/*
+	 * Once the ratio to fix has been estimated and fixed, we never change it
+	 * again.
+	 */
+	if ( PRESPOOL->ClusterMemoryCoreRatio > 0 )
+	{
+		return;
+	}
+
+	/* If no enough segment ready for fixing ratio, skip this. */
+	if ( PRESPOOL->SlavesHostCount <= 0 )
+	{
+		return;
+	}
+
+	int rejectlimit = PRESPOOL->SlavesHostCount <= rm_rejectrequest_nseg_limit ?
+					  0 :
+					  rm_rejectrequest_nseg_limit;
+	int criteria1 = PRESPOOL->SlavesHostCount - rejectlimit;
+	int criteria2 = (PRESPOOL->SlavesHostCount + 1) / 2;
+
+	if ( PRESPOOL->AvailNodeCount < criteria1 ||
+		 PRESPOOL->AvailNodeCount < criteria2 )
+	{
+		elog(RMLOG, "Resource manager expects at least %d segments available "
+					"before first time fixing cluster memory to core ratio, "
+					"currently %d available segments are ready.",
+					criteria1 > criteria2 ? criteria1 : criteria2,
+					PRESPOOL->AvailNodeCount );
+		return;
+	}
+
+	/*
+	 * Go into real calculation of the cluster level memory to core ratio now,
+	 * The idea of fixing the ratio is to calculate possible
+	 */
+
+	HASHTABLEData ratios;
+	initializeHASHTABLE(&ratios,
+						PCONTEXT,
+						HASHTABLE_SLOT_VOLUME_DEFAULT,
+						HASHTABLE_SLOT_VOLUME_DEFAULT_MAX,
+						HASHTABLE_KEYTYPE_UINT32,
+						NULL);
+
+	/*
+	 * STEP 1. Go through all current segments to get segment level ratios.
+	 */
+	List 	 *ressegl	 = NULL;
+	ListCell *cell		 = NULL;
+	getAllPAIRRefIntoList(&(PRESPOOL->Segments), &ressegl);
+	foreach(cell, ressegl)
+	{
+		PAIR 		pair 	 = (PAIR)lfirst(cell);
+		SegResource segres 	 = (SegResource)(pair->Value);
+		uint32_t 	ratio 	 = 0;
+		uint32_t 	memorymb = 0;
+		uint32_t 	core	 = 0;
+
+		if ( !IS_SEGSTAT_FTSAVAILABLE(segres->Stat) )
+		{
+			continue;
+		}
+
+		if ( DRMGlobalInstance->ImpType == NONE_HAWQ2 )
+		{
+			memorymb = segres->Stat->FTSTotalMemoryMB;
+			core	 = segres->Stat->FTSTotalCore;
+		}
+		else
+		{
+			if ( !IS_SEGSTAT_GRMAVAILABLE(segres->Stat) )
+			{
+				continue;
+			}
+			memorymb = segres->Stat->GRMTotalMemoryMB;
+			core	 = segres->Stat->GRMTotalCore;
+		}
+
+		Assert(core > 0);
+		ratio = memorymb / core;
+
+		PAIR ratiopair = getHASHTABLENode(&ratios, TYPCONVERT(void *, ratio));
+		if ( ratiopair == NULL )
+		{
+			setHASHTABLENode(&ratios, TYPCONVERT(void *, ratio), NULL, false);
+		}
+	}
+
+	/*
+	 * STEP 2. Choose one ratio as cluster ratio by estimating the possible
+	 * 		   resource waste.
+	 */
+	uint32_t minmemorywaste = UINT32_MAX;
+	uint32_t candratio = 0;
+
+	List 	 *ratiol	= NULL;
+	ListCell *ratiocell	= NULL;
+	getAllPAIRRefIntoList(&ratios, &ratiol);
+	foreach(ratiocell, ratiol)
+	{
+		PAIR pair = (PAIR)lfirst(ratiocell);
+		uint32_t segratio = TYPCONVERT(uint32_t, pair->Key);
+
+		uint32_t memorywaste = 0;
+		foreach(cell, ressegl)
+		{
+			PAIR segpair = (PAIR)lfirst(cell);
+			SegResource segres 	 = (SegResource)(segpair->Value);
+			uint32_t 	ratio 	 = 0;
+			uint32_t 	memorymb = 0;
+			uint32_t 	core	 = 0;
+
+			if ( !IS_SEGSTAT_FTSAVAILABLE(segres->Stat) )
+			{
+				continue;
+			}
+
+			if ( DRMGlobalInstance->ImpType == NONE_HAWQ2 )
+			{
+				memorymb = segres->Stat->FTSTotalMemoryMB;
+				core	 = segres->Stat->FTSTotalCore;
+			}
+			else
+			{
+				if ( !IS_SEGSTAT_GRMAVAILABLE(segres->Stat) )
+				{
+					continue;
+				}
+				memorymb = segres->Stat->GRMTotalMemoryMB;
+				core	 = segres->Stat->GRMTotalCore;
+			}
+			Assert(core > 0);
+			ratio = memorymb / core;
+			uint32_t segmemwaste = 0;
+
+			if ( segratio * core > memorymb )
+			{
+				segmemwaste = memorymb - (memorymb / segratio) * segratio;
+			}
+			else
+			{
+				segmemwaste = memorymb - core *segratio;
+			}
+			memorywaste += segmemwaste;
+		}
+
+		elog(RMLOG, "Resource manager estimates that ratio %u MB per core wastes "
+					"%d MB resource in the whole recognized cluster.",
+					segratio,
+					memorywaste);
+
+		if ( memorywaste < minmemorywaste )
+		{
+			minmemorywaste = memorywaste;
+			candratio = segratio;
+		}
+	}
+
+	PRESPOOL->ClusterMemoryCoreRatio = candratio;
+
+	elog(LOG, "Resource manager chooses ratio %u MB per core as cluster level "
+			  "memory to core ratio, there are %d MB memory resource unable to "
+			  "utilize.",
+			  PRESPOOL->ClusterMemoryCoreRatio,
+			  minmemorywaste);
+
+	/*
+	 * Refresh segments' capacity following the fixed cluster level memory to
+	 * core ratio.
+	 */
+
+	foreach(cell, ressegl)
+	{
+		PAIR 		pair 	 = (PAIR)lfirst(cell);
+		SegResource segres 	 = (SegResource)(pair->Value);
+		adjustSegmentCapacity(segres);
+	}
+
+	/* Clean up. */
+	freePAIRRefList(&(PRESPOOL->Segments), &ressegl);
+	cleanHASHTABLE(&ratios);
+
+}
+
+void adjustSegmentCapacity(SegResource segres)
+{
+	if ( PRESPOOL->ClusterMemoryCoreRatio == 0 )
+	{
+		return;
+	}
+
+	if ( DRMGlobalInstance->ImpType == NONE_HAWQ2 )
+	{
+		adjustSegmentCapacityForNone(segres);
+	}
+	else
+	{
+		adjustSegmentCapacityForGRM(segres);
+	}
+}
+
+void adjustSegmentStatFTSCapacity(SegStat segstat)
+{
+	if ( PRESPOOL->ClusterMemoryCoreRatio == 0 )
+	{
+		return;
+	}
+
+	uint32_t oldmemorymb = segstat->FTSTotalMemoryMB;
+	uint32_t oldcore	 = segstat->FTSTotalCore;
+
+	adjustMemoryCoreValue(&(segstat->FTSTotalMemoryMB), &(segstat->FTSTotalCore));
+
+	if ( oldmemorymb != segstat->FTSTotalMemoryMB ||
+		 oldcore	 != segstat->FTSTotalCore )
+	{
+		elog(RMLOG, "Resource manager adjusts segment FTS capacity from "
+					"(%d MB, %d CORE) to (%d MB, %d CORE)",
+					oldmemorymb,
+					oldcore,
+					segstat->FTSTotalMemoryMB,
+					segstat->FTSTotalCore);
+	}
+}
+
+void adjustSegmentStatGRMCapacity(SegStat segstat)
+{
+	if ( PRESPOOL->ClusterMemoryCoreRatio == 0 )
+	{
+		return;
+	}
+
+	uint32_t oldmemorymb = segstat->GRMTotalMemoryMB;
+	uint32_t oldcore	 = segstat->GRMTotalCore;
+
+	adjustMemoryCoreValue(&(segstat->GRMTotalMemoryMB), &(segstat->GRMTotalCore));
+
+	if ( oldmemorymb != segstat->GRMTotalMemoryMB ||
+		 oldcore	 != segstat->GRMTotalCore )
+	{
+		elog(RMLOG, "Resource manager adjusts segment GRM capacity from "
+					"(%d MB, %d CORE) to (%d MB, %d CORE)",
+					oldmemorymb,
+					oldcore,
+					segstat->GRMTotalMemoryMB,
+					segstat->GRMTotalCore);
+	}
+}
+
+void adjustSegmentCapacityForNone(SegResource segres)
+{
+	if ( PRESPOOL->ClusterMemoryCoreRatio == 0 )
+	{
+		return;
+	}
+
+	uint32_t oldmemorymb = 0;
+	uint32_t oldcore	 = 0;
+
+	oldmemorymb = segres->Stat->FTSTotalMemoryMB;
+	oldcore		= segres->Stat->FTSTotalCore;
+
+	adjustMemoryCoreValue(&(segres->Stat->FTSTotalMemoryMB),
+						  &(segres->Stat->FTSTotalCore));
+
+	if ( !IS_SEGSTAT_FTSAVAILABLE(segres->Stat) )
+	{
+		return;
+	}
+
+	if ( oldmemorymb != segres->Stat->FTSTotalMemoryMB ||
+		 oldcore	 != segres->Stat->FTSTotalCore )
+	{
+		minusResourceBundleData(&(PRESPOOL->FTSTotal),
+								oldmemorymb,
+								oldcore * 1.0);
+		addResourceBundleData(&(PRESPOOL->FTSTotal),
+							  segres->Stat->FTSTotalMemoryMB,
+							  segres->Stat->FTSTotalCore * 1.0);
+	}
+}
+
+void adjustSegmentCapacityForGRM(SegResource segres)
+{
+	if ( PRESPOOL->ClusterMemoryCoreRatio == 0 )
+	{
+		return;
+	}
+
+	uint32_t oldmemorymb = 0;
+	uint32_t oldcore	 = 0;
+
+	oldmemorymb = segres->Stat->GRMTotalMemoryMB;
+	oldcore		= segres->Stat->GRMTotalCore;
+
+	adjustMemoryCoreValue(&(segres->Stat->GRMTotalMemoryMB),
+						  &(segres->Stat->GRMTotalCore));
+
+	if ( !IS_SEGSTAT_FTSAVAILABLE(segres->Stat) ||
+		 !IS_SEGSTAT_GRMAVAILABLE(segres->Stat))
+	{
+		return;
+	}
+
+	if ( oldmemorymb != segres->Stat->GRMTotalMemoryMB ||
+		 oldcore 	 != segres->Stat->GRMTotalCore )
+	{
+		minusResourceBundleData(&(PRESPOOL->GRMTotal),
+								oldmemorymb,
+								oldcore * 1.0);
+		addResourceBundleData(&(PRESPOOL->GRMTotal),
+							  segres->Stat->GRMTotalMemoryMB,
+							  segres->Stat->GRMTotalCore * 1.0);
+	}
+}
+
+void adjustMemoryCoreValue(uint32_t *memorymb, uint32_t *core)
+{
+	if ( PRESPOOL->ClusterMemoryCoreRatio == 0 )
+	{
+		return;
+	}
+
+	if ( *core * PRESPOOL->ClusterMemoryCoreRatio > *memorymb )
+	{
+		*core = *memorymb / PRESPOOL->ClusterMemoryCoreRatio;
+	}
+	*memorymb = *core * PRESPOOL->ClusterMemoryCoreRatio;
+}
+
 void dumpResourcePoolHosts(const char *filename)
 {
     if ( filename == NULL )

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/20d14e3a/src/backend/resourcemanager/resqueuemanager.c
----------------------------------------------------------------------
diff --git a/src/backend/resourcemanager/resqueuemanager.c b/src/backend/resourcemanager/resqueuemanager.c
index 7bb6f44..c148f75 100644
--- a/src/backend/resourcemanager/resqueuemanager.c
+++ b/src/backend/resourcemanager/resqueuemanager.c
@@ -2684,6 +2684,24 @@ void refreshResourceQueueCapacity(bool queuechanged)
 	static char errorbuf[ERRORMESSAGE_SIZE];
 	List *qhavingshadow = NULL;
 
+	/*
+	 * If the cluster level memory to core ratio is not fixed based on FTS heart-
+	 * beat or GRM cluster report, try to fix it firstly, if unfortunately, this
+	 * ratio cannot be fixed, skip refreshing queue capacity temporarily.
+	 *
+	 * NOTE, once this ratio is fixed, it is not changed again until restart
+	 * master.
+	 *
+	 */
+	if ( PRESPOOL->ClusterMemoryCoreRatio <= 0 )
+	{
+		fixClusterMemoryCoreRatio();
+		if ( PRESPOOL->ClusterMemoryCoreRatio <= 0 )
+		{
+			return;
+		}
+	}
+
 	/* STEP 1. Build all necessary shadow resource queue track instances. */
 	buildQueueTrackShadows(PQUEMGR->RootTrack, &qhavingshadow);
 
@@ -2721,6 +2739,7 @@ void refreshResourceQueuePercentageCapacity(bool queuechanged)
 				   PQUEMGR->GRMQueueMaxCapacity;
 			core = PRESPOOL->GRMTotalHavingNoHAWQNode.Core     *
 				   PQUEMGR->GRMQueueMaxCapacity;
+
 		}
 		else if ( DRMGlobalInstance->ImpType == NONE_HAWQ2 )
 		{
@@ -2737,20 +2756,11 @@ void refreshResourceQueuePercentageCapacity(bool queuechanged)
 		return;
 	}
 
-	/* Logic to ensure the cluster total resource follows memory core ratio. */
-	if ( PRESPOOL->MemCoreRatio > 0 && core > 0 && mem > 0 ) {
-		/* Cluster has more memory resource */
-		if ( mem > PRESPOOL->MemCoreRatio * core) {
-			mem = core * PRESPOOL->MemCoreRatio;
-		}
-		/* Cluster has more core resource */
-		else {
-			core = trunc(mem * 1.0 / PRESPOOL->MemCoreRatio);
-		}
-	}
-	else {
-		return;
-	}
+	/*
+	 * If we use global resource manager to manage resource, the total capacity
+	 * might not follow the cluster memory to core ratio.
+	 */
+	adjustMemoryCoreValue(&mem, &core);
 
 	elog(DEBUG3, "HAWQ RM :: Use cluster (%d MB, %d CORE) resources as whole.",
 				mem, core);
@@ -5193,7 +5203,10 @@ void resetAllDeadLockDetector(void)
 
 void getIdleResourceRequest(int32_t *mem, double *core)
 {
-	*mem  = PRESPOOL->MemCoreRatio * PRESPOOL->AvailNodeCount * rm_min_resource_perseg;
+	Assert(PRESPOOL->ClusterMemoryCoreRatio > 0);
+	*mem  = PRESPOOL->ClusterMemoryCoreRatio *
+			PRESPOOL->AvailNodeCount *
+			rm_min_resource_perseg;
 	*core = 1.0 * PRESPOOL->AvailNodeCount * rm_min_resource_perseg;
 }
 


Mime
View raw message