提交 6f940543 编写于 作者: X xiong-gang 提交者: GitHub

Detach resource group slot on segment

QE detach resource group slot at the end of transaction, the
last QE of the slot release the slot, and release the overused
memory if resource group config has been changed.
上级 fb1448d0
...@@ -2841,8 +2841,8 @@ CommitTransaction(void) ...@@ -2841,8 +2841,8 @@ CommitTransaction(void)
freeGangsForPortal(NULL); freeGangsForPortal(NULL);
/* Release resource group slot at the end of a transaction */ /* Release resource group slot at the end of a transaction */
if (ShouldAssignResGroupOnMaster()) if (ShouldUnassignResGroup())
UnassignResGroupOnMaster(); UnassignResGroup();
} }
...@@ -3394,8 +3394,8 @@ CleanupTransaction(void) ...@@ -3394,8 +3394,8 @@ CleanupTransaction(void)
finishDistributedTransactionContext("CleanupTransaction", true); finishDistributedTransactionContext("CleanupTransaction", true);
/* Release resource group slot at the end of a transaction */ /* Release resource group slot at the end of a transaction */
if (ShouldAssignResGroupOnMaster()) if (ShouldUnassignResGroup())
UnassignResGroupOnMaster(); UnassignResGroup();
} }
/* /*
......
...@@ -348,6 +348,10 @@ DropResourceGroup(DropResourceGroupStmt *stmt) ...@@ -348,6 +348,10 @@ DropResourceGroup(DropResourceGroupStmt *stmt)
errmsg("cannot drop default resource group \"%s\"", errmsg("cannot drop default resource group \"%s\"",
stmt->name))); stmt->name)));
/* check before dispatch to segment */
if (IsResGroupActivated())
ResGroupCheckForDrop(groupid, stmt->name);
/* /*
* Check to see if any roles are in this resource group. * Check to see if any roles are in this resource group.
*/ */
...@@ -399,8 +403,6 @@ DropResourceGroup(DropResourceGroupStmt *stmt) ...@@ -399,8 +403,6 @@ DropResourceGroup(DropResourceGroupStmt *stmt)
if (IsResGroupActivated()) if (IsResGroupActivated())
{ {
ResGroupCheckForDrop(groupid, stmt->name);
/* Argument of callback function should be allocated in heap region */ /* Argument of callback function should be allocated in heap region */
callbackArg = (Oid *)MemoryContextAlloc(TopMemoryContext, sizeof(Oid)); callbackArg = (Oid *)MemoryContextAlloc(TopMemoryContext, sizeof(Oid));
*callbackArg = groupid; *callbackArg = groupid;
......
...@@ -205,15 +205,15 @@ static void ResGroupWait(ResGroupData *group); ...@@ -205,15 +205,15 @@ static void ResGroupWait(ResGroupData *group);
static ResGroupData *ResGroupCreate(Oid groupId, const ResGroupCaps *caps); static ResGroupData *ResGroupCreate(Oid groupId, const ResGroupCaps *caps);
static void AtProcExit_ResGroup(int code, Datum arg); static void AtProcExit_ResGroup(int code, Datum arg);
static void ResGroupWaitCancel(void); static void ResGroupWaitCancel(void);
static void groupAssginChunks(ResGroupData *group,
int32 chunks,
const ResGroupCaps *caps);
static int32 groupIncMemUsage(ResGroupData *group, static int32 groupIncMemUsage(ResGroupData *group,
ResGroupSlotData *slot, ResGroupSlotData *slot,
int32 chunks); int32 chunks);
static void groupDecMemUsage(ResGroupData *group, static void groupDecMemUsage(ResGroupData *group,
ResGroupSlotData *slot, ResGroupSlotData *slot,
int32 chunks); int32 chunks);
static void initSlot(ResGroupSlotData *slot, ResGroupCaps *caps, int sessionId);
static void selfAttachToSlot(ResGroupData *group, ResGroupSlotData *slot);
static void selfDetachSlot(ResGroupData *group, ResGroupSlotData *slot);
static int getFreeSlot(ResGroupData *group); static int getFreeSlot(ResGroupData *group);
static int getSlot(ResGroupData *group); static int getSlot(ResGroupData *group);
static void putSlot(void); static void putSlot(void);
...@@ -234,7 +234,7 @@ static bool selfHasSlot(void); ...@@ -234,7 +234,7 @@ static bool selfHasSlot(void);
static bool selfHasGroup(void); static bool selfHasGroup(void);
static void selfSetGroup(ResGroupData *group); static void selfSetGroup(ResGroupData *group);
static void selfUnsetGroup(void); static void selfUnsetGroup(void);
static void selfSetSlot(void); static void selfSetSlot(int slotId);
static void selfUnsetSlot(void); static void selfUnsetSlot(void);
static bool procIsInWaitQueue(const PGPROC *proc); static bool procIsInWaitQueue(const PGPROC *proc);
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
...@@ -1132,6 +1132,41 @@ groupDecMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks) ...@@ -1132,6 +1132,41 @@ groupDecMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks)
} }
} }
/*
* Attach a process (QD or QE) to a slot.
*/
static void
selfAttachToSlot(ResGroupData *group, ResGroupSlotData *slot)
{
AssertImply(slot->nProcs == 0, slot->memUsage == 0);
groupIncMemUsage(group, slot, self->memUsage);
slot->nProcs++;
}
/*
* Detach a process (QD or QE) from a slot.
*/
static void
selfDetachSlot(ResGroupData *group, ResGroupSlotData *slot)
{
groupDecMemUsage(group, slot, self->memUsage);
slot->nProcs--;
AssertImply(slot->nProcs == 0, slot->memUsage == 0);
}
/*
* Initialize the members of a slot
*/
static void
initSlot(ResGroupSlotData *slot, ResGroupCaps *caps, int sessionId)
{
Assert(slot->inUse);
slot->sessionId = sessionId;
slot->caps = *caps;
slot->memQuota = slotGetMemQuotaExpected(caps);
slot->memUsage = 0;
}
/* /*
* Get a free resource group slot. * Get a free resource group slot.
* *
...@@ -1171,7 +1206,6 @@ getFreeSlot(ResGroupData *group) ...@@ -1171,7 +1206,6 @@ getFreeSlot(ResGroupData *group)
static int static int
getSlot(ResGroupData *group) getSlot(ResGroupData *group)
{ {
ResGroupSlotData *slot;
int32 slotMemQuota; int32 slotMemQuota;
int32 memQuotaUsed; int32 memQuotaUsed;
int slotId; int slotId;
...@@ -1195,7 +1229,6 @@ getSlot(ResGroupData *group) ...@@ -1195,7 +1229,6 @@ getSlot(ResGroupData *group)
/* Calculate the expected per slot quota */ /* Calculate the expected per slot quota */
slotMemQuota = slotGetMemQuotaExpected(caps); slotMemQuota = slotGetMemQuotaExpected(caps);
Assert(slotMemQuota > 0);
Assert(group->memQuotaUsed >= 0); Assert(group->memQuotaUsed >= 0);
Assert(group->memQuotaUsed <= group->memQuotaGranted); Assert(group->memQuotaUsed <= group->memQuotaGranted);
...@@ -1215,17 +1248,7 @@ getSlot(ResGroupData *group) ...@@ -1215,17 +1248,7 @@ getSlot(ResGroupData *group)
slotId = getFreeSlot(group); slotId = getFreeSlot(group);
Assert(slotId != InvalidSlotId); Assert(slotId != InvalidSlotId);
slot = &group->slots[slotId]; group->nRunning++;
Assert(slot->inUse);
/* Grant the memory quota to it */
slot->memQuota = slotMemQuota;
/* Store the config snapshot to it */
slot->caps = *caps;
/* And finally increase nRunning */
pg_atomic_add_fetch_u32((pg_atomic_uint32*)&group->nRunning, 1);
return slotId; return slotId;
} }
...@@ -1255,7 +1278,6 @@ putSlot(void) ...@@ -1255,7 +1278,6 @@ putSlot(void)
selfUnsetSlot(); selfUnsetSlot();
Assert(slot->inUse); Assert(slot->inUse);
Assert(slot->memQuota > 0);
/* Return the memory quota granted to this slot */ /* Return the memory quota granted to this slot */
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
...@@ -1273,7 +1295,7 @@ putSlot(void) ...@@ -1273,7 +1295,7 @@ putSlot(void)
slot->inUse = false; slot->inUse = false;
/* And finally decrease nRunning */ /* And finally decrease nRunning */
pg_atomic_sub_fetch_u32((pg_atomic_uint32*)&group->nRunning, 1); group->nRunning--;
} }
/* /*
...@@ -1324,17 +1346,17 @@ retry: ...@@ -1324,17 +1346,17 @@ retry:
if (!group->lockedForDrop) if (!group->lockedForDrop)
{ {
/* try to get a slot directly */ /* try to get a slot directly */
MyProc->resSlotId = getSlot(group); int slotId = getSlot(group);
if (MyProc->resSlotId != InvalidSlotId) if (slotId != InvalidSlotId)
{ {
/* got one, lucky */ /* got one, lucky */
selfSetSlot(); initSlot(&group->slots[slotId], &group->caps, gp_session_id);
selfSetSlot(slotId);
group->totalExecuted++; group->totalExecuted++;
pgstat_report_resgroup(0, group->groupId); pgstat_report_resgroup(0, group->groupId);
LWLockRelease(ResGroupLock); LWLockRelease(ResGroupLock);
Assert(selfIsAssignedValidGroup());
return; return;
} }
} }
...@@ -1365,14 +1387,13 @@ retry: ...@@ -1365,14 +1387,13 @@ retry:
* The waking process has granted us a valid slot. * The waking process has granted us a valid slot.
* Update the statistic information of the resource group. * Update the statistic information of the resource group.
*/ */
selfSetSlot(); selfSetSlot(MyProc->resSlotId);
LWLockAcquire(ResGroupLock, LW_EXCLUSIVE); LWLockAcquire(ResGroupLock, LW_EXCLUSIVE);
addTotalQueueDuration(group); addTotalQueueDuration(group);
group->totalExecuted++; group->totalExecuted++;
LWLockRelease(ResGroupLock); LWLockRelease(ResGroupLock);
pgstat_report_resgroup(0, group->groupId); pgstat_report_resgroup(0, group->groupId);
Assert(selfIsAssignedValidGroup());
} }
/* Update the total queued time of this group */ /* Update the total queued time of this group */
...@@ -1617,7 +1638,7 @@ static int32 ...@@ -1617,7 +1638,7 @@ static int32
slotGetMemQuotaExpected(const ResGroupCaps *caps) slotGetMemQuotaExpected(const ResGroupCaps *caps)
{ {
Assert(caps->concurrency.proposed != 0); Assert(caps->concurrency.proposed != 0);
return Max(1, groupGetMemQuotaExpected(caps) / caps->concurrency.proposed); return groupGetMemQuotaExpected(caps) / caps->concurrency.proposed;
} }
/* /*
...@@ -1653,6 +1674,7 @@ wakeupSlots(ResGroupData *group) ...@@ -1653,6 +1674,7 @@ wakeupSlots(ResGroupData *group)
Assert(waitProc->resWaiting != false); Assert(waitProc->resWaiting != false);
Assert(waitProc->resSlotId == InvalidSlotId); Assert(waitProc->resSlotId == InvalidSlotId);
initSlot(&group->slots[slotId], &group->caps, waitProc->mppSessionId);
waitProc->resWaiting = false; waitProc->resWaiting = false;
waitProc->resSlotId = slotId; waitProc->resSlotId = slotId;
SetLatch(&waitProc->procLatch); SetLatch(&waitProc->procLatch);
...@@ -1797,8 +1819,7 @@ ResGroupSlotRelease(void) ...@@ -1797,8 +1819,7 @@ ResGroupSlotRelease(void)
ResGroupData *group = self->group; ResGroupData *group = self->group;
Assert(selfIsAssignedValidGroup()); Assert(selfIsAssignedValidGroup());
Assert(LWLockHeldExclusiveByMe(ResGroupLock));
LWLockAcquire(ResGroupLock, LW_EXCLUSIVE);
putSlot(); putSlot();
Assert(!selfHasSlot()); Assert(!selfHasSlot());
...@@ -1822,12 +1843,11 @@ ResGroupSlotRelease(void) ...@@ -1822,12 +1843,11 @@ ResGroupSlotRelease(void)
Assert(waitProc->resWaiting != false); Assert(waitProc->resWaiting != false);
Assert(waitProc->resSlotId == InvalidSlotId); Assert(waitProc->resSlotId == InvalidSlotId);
initSlot(&group->slots[slotId], &group->caps, waitProc->mppSessionId);
waitProc->resSlotId = slotId; /* pass the slot to new query */ waitProc->resSlotId = slotId; /* pass the slot to new query */
waitProc->resWaiting = false; waitProc->resWaiting = false;
SetLatch(&waitProc->procLatch); SetLatch(&waitProc->procLatch);
} }
LWLockRelease(ResGroupLock);
} }
/* /*
...@@ -1871,7 +1891,10 @@ SerializeResGroupInfo(StringInfo str) ...@@ -1871,7 +1891,10 @@ SerializeResGroupInfo(StringInfo str)
*/ */
void void
DeserializeResGroupInfo(struct ResGroupCaps *capsOut, DeserializeResGroupInfo(struct ResGroupCaps *capsOut,
const char *buf, int len) Oid *groupId,
int *slotId,
const char *buf,
int len)
{ {
int i; int i;
int tmp; int tmp;
...@@ -1880,15 +1903,13 @@ DeserializeResGroupInfo(struct ResGroupCaps *capsOut, ...@@ -1880,15 +1903,13 @@ DeserializeResGroupInfo(struct ResGroupCaps *capsOut,
Assert(len > 0); Assert(len > 0);
/* TODO: don't deserialize into self directly */ memcpy(&tmp, ptr, sizeof(*groupId));
*groupId = ntohl(tmp);
ptr += sizeof(*groupId);
memcpy(&tmp, ptr, sizeof(self->groupId)); memcpy(&tmp, ptr, sizeof(*slotId));
self->groupId = ntohl(tmp); *slotId = ntohl(tmp);
ptr += sizeof(self->groupId); ptr += sizeof(*slotId);
memcpy(&tmp, ptr, sizeof(self->slotId));
self->slotId = ntohl(tmp);
ptr += sizeof(self->slotId);
for (i = 0; i < RESGROUP_LIMIT_TYPE_COUNT; i++) for (i = 0; i < RESGROUP_LIMIT_TYPE_COUNT; i++)
{ {
...@@ -1916,6 +1937,18 @@ ShouldAssignResGroupOnMaster(void) ...@@ -1916,6 +1937,18 @@ ShouldAssignResGroupOnMaster(void)
!AmIInSIGUSR1Handler(); !AmIInSIGUSR1Handler();
} }
/*
* UnassignResGroup() is called on both master and segments
*/
bool
ShouldUnassignResGroup(void)
{
return IsResGroupActivated() &&
IsNormalProcessingMode() &&
(Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_EXECUTE) &&
!AmIInSIGUSR1Handler();
}
/* /*
* On master, QD is assigned to a resource group at the beginning of a transaction. * On master, QD is assigned to a resource group at the beginning of a transaction.
* It will first acquire a slot from the resource group, and then, it will get the * It will first acquire a slot from the resource group, and then, it will get the
...@@ -1933,26 +1966,21 @@ AssignResGroupOnMaster(void) ...@@ -1933,26 +1966,21 @@ AssignResGroupOnMaster(void)
PG_TRY(); PG_TRY();
{ {
/* Acquire slot */ /* Acquire slot */
Assert(pResGroupControl != NULL);
Assert(pResGroupControl->segmentsOnMaster > 0);
Assert(selfIsUnassigned()); Assert(selfIsUnassigned());
ResGroupSlotAcquire(); ResGroupSlotAcquire();
Assert(selfIsAssignedValidGroup()); Assert(selfIsAssignedValidGroup());
Assert(selfHasSlot());
Assert(!self->doMemCheck); Assert(!self->doMemCheck);
group = self->group; group = self->group;
/* Init slot */
slot = self->slot; slot = self->slot;
Assert(slot->memQuota > 0); /* Add proc memory accounting info into group and slot */
slot->sessionId = gp_session_id; selfAttachToSlot(group, slot);
pg_atomic_add_fetch_u32((pg_atomic_uint32*)&slot->nProcs, 1);
/* Init self */ /* Init self */
self->caps = slot->caps; self->caps = slot->caps;
Assert(pResGroupControl != NULL);
Assert(pResGroupControl->segmentsOnMaster > 0);
/* Add proc memory accounting info into group and slot */
groupIncMemUsage(group, slot, self->memUsage);
/* Start memory limit checking */ /* Start memory limit checking */
self->doMemCheck = true; self->doMemCheck = true;
...@@ -1961,14 +1989,14 @@ AssignResGroupOnMaster(void) ...@@ -1961,14 +1989,14 @@ AssignResGroupOnMaster(void)
SIMPLE_FAULT_INJECTOR(ResGroupAssignedOnMaster); SIMPLE_FAULT_INJECTOR(ResGroupAssignedOnMaster);
/* Add into cgroup */ /* Add into cgroup */
ResGroupOps_AssignGroup(group->groupId, MyProcPid); ResGroupOps_AssignGroup(self->groupId, MyProcPid);
/* Set spill guc */ /* Set spill guc */
ResGroupSetMemorySpillRatio(&slot->caps); ResGroupSetMemorySpillRatio(&slot->caps);
} }
PG_CATCH(); PG_CATCH();
{ {
UnassignResGroupOnMaster(); UnassignResGroup();
PG_RE_THROW(); PG_RE_THROW();
} }
PG_END_TRY(); PG_END_TRY();
...@@ -1978,7 +2006,7 @@ AssignResGroupOnMaster(void) ...@@ -1978,7 +2006,7 @@ AssignResGroupOnMaster(void)
* Detach from a resource group at the end of the transaction. * Detach from a resource group at the end of the transaction.
*/ */
void void
UnassignResGroupOnMaster(void) UnassignResGroup(void)
{ {
ResGroupData *group = self->group; ResGroupData *group = self->group;
ResGroupSlotData *slot = self->slot; ResGroupSlotData *slot = self->slot;
...@@ -1994,22 +2022,42 @@ UnassignResGroupOnMaster(void) ...@@ -1994,22 +2022,42 @@ UnassignResGroupOnMaster(void)
/* Stop memory limit checking */ /* Stop memory limit checking */
self->doMemCheck = false; self->doMemCheck = false;
/* Sub proc memory accounting info from group and slot */
groupDecMemUsage(group, slot, self->memUsage);
/* Cleanup self */ /* Cleanup self */
if (self->memUsage > 10) if (self->memUsage > 10)
LOG_RESGROUP_DEBUG(LOG, "Idle proc memory usage: %d", self->memUsage); LOG_RESGROUP_DEBUG(LOG, "Idle proc memory usage: %d", self->memUsage);
/* Cleanup slotInfo */ LWLockAcquire(ResGroupLock, LW_EXCLUSIVE);
pg_atomic_sub_fetch_u32((pg_atomic_uint32*)&slot->nProcs, 1);
/* Release the slot */ /* Sub proc memory accounting info from group and slot */
ResGroupSlotRelease(); selfDetachSlot(group, slot);
Assert(!selfHasSlot());
if (Gp_role == GP_ROLE_DISPATCH)
{
/* Release the slot */
ResGroupSlotRelease();
Assert(!selfHasSlot());
}
else
{
Assert(Gp_role == GP_ROLE_EXECUTE);
selfUnsetSlot();
if (slot->nProcs == 0)
{
/* Release the slot memory */
groupReleaseMemQuota(group, slot);
/* Mark the slot as free */
slot->inUse = false;
/* And finally decrease nRunning */
group->nRunning--;
}
}
/* Cleanup group */ /* Cleanup group */
selfUnsetGroup(); selfUnsetGroup();
LWLockRelease(ResGroupLock);
Assert(selfIsUnassigned()); Assert(selfIsUnassigned());
} }
...@@ -2022,134 +2070,68 @@ UnassignResGroupOnMaster(void) ...@@ -2022,134 +2070,68 @@ UnassignResGroupOnMaster(void)
void void
SwitchResGroupOnSegment(const char *buf, int len) SwitchResGroupOnSegment(const char *buf, int len)
{ {
Oid prevGroupId; Oid newGroupId;
int prevSlotId; int newSlotId;
ResGroupCaps caps; ResGroupCaps caps;
ResGroupData *group; ResGroupData *group;
ResGroupSlotData *slot; ResGroupSlotData *slot;
ResGroupData *prevGroup = NULL;
ResGroupSlotData *prevSlot = NULL;
selfValidateResGroupInfo();
prevGroupId = self->groupId;
prevSlotId = self->slotId;
prevGroup = self->group;
prevSlot = self->slot;
/* Stop memory limit checking */ /* Stop memory limit checking */
self->doMemCheck = false; self->doMemCheck = false;
DeserializeResGroupInfo(&caps, buf, len); DeserializeResGroupInfo(&caps, &newGroupId, &newSlotId, buf, len);
AssertImply(newGroupId != InvalidOid,
newSlotId != InvalidSlotId);
AssertImply(self->groupId != InvalidOid, if (newGroupId == InvalidOid)
self->slotId != InvalidSlotId);
AssertImply(prevGroupId != InvalidOid,
prevSlotId != InvalidSlotId);
LWLockAcquire(ResGroupLock, LW_EXCLUSIVE);
if (self->groupId == InvalidOid)
{ {
/* about to switch to a none resgroup state ... */ UnassignResGroup();
self->group = NULL;
if (prevGroup)
{
/* from another resgroup, so detach from it */
Assert(prevGroup->groupId == prevGroupId);
/* Sub proc memory accounting info from group and slot */
groupDecMemUsage(prevGroup, prevSlot, self->memUsage);
/* Update info in previous slot */
pg_atomic_sub_fetch_u32((pg_atomic_uint32*)&prevSlot->nProcs, 1);
groupReleaseMemQuota(prevGroup, prevSlot);
}
else
{
/* from a none resgroup state, so nothing to do */
Assert(prevGroupId == InvalidOid);
Assert(prevSlotId == InvalidSlotId);
}
LWLockRelease(ResGroupLock);
Assert(selfIsUnassigned()); Assert(selfIsUnassigned());
return; return;
} }
/* now we know we are about to switch to some resgroup ... */ if (self->groupId != InvalidOid)
if (prevGroup && prevGroup->groupId != prevGroupId)
{ {
/* from a dropped resgroup, so behave like we are from /* it's not the first dispatch in the same transaction */
* a none resgroup state */ Assert(self->groupId == newGroupId);
Assert(self->slotId == newSlotId);
prevGroup = NULL; Assert(!memcmp((void*)&self->caps, (void*)&caps, sizeof(caps)));
prevSlot = NULL; self->doMemCheck = true;
prevGroupId = InvalidOid; return;
prevSlotId = InvalidSlotId;
} }
/* now we are sure to switch to a valid resgroup */ LWLockAcquire(ResGroupLock, LW_EXCLUSIVE);
group = ResGroupHashFind(newGroupId);
group = ResGroupHashFind(self->groupId);
Assert(group != NULL); Assert(group != NULL);
/* we don't set this group to self until end of this function */
LWLockRelease(ResGroupLock);
/* Init self */ /* Init self */
Assert(host_segments > 0); Assert(host_segments > 0);
Assert(caps.concurrency.proposed > 0); Assert(caps.concurrency.proposed > 0);
Assert(self->slotId != InvalidSlotId); selfSetGroup(group);
selfSetSlot(newSlotId);
self->caps = caps; self->caps = caps;
self->slot = &group->slots[self->slotId];
Assert(selfHasSlot()); Assert(selfHasSlot());
/* Init slot */ /* Init slot */
slot = self->slot; slot = self->slot;
slot->sessionId = gp_session_id; if (slot->nProcs != 0)
slot->caps = caps;
slot->memQuota = slotGetMemQuotaExpected(&caps);
ResGroupSetMemorySpillRatio(&caps);
Assert(slot->memQuota > 0);
if (prevGroup != group || prevSlot != slot)
{ {
/* we are switching between different resgroups */ Assert(slot->sessionId == gp_session_id);
Assert(slot->memQuota == slotGetMemQuotaExpected(&caps));
LWLockAcquire(ResGroupLock, LW_EXCLUSIVE);
if (prevGroup)
{
/* the previous one is valid, so detach from it */
Assert(prevSlot != NULL);
/* Sub proc memory accounting info from group and slot */
groupDecMemUsage(prevGroup, prevSlot, self->memUsage);
/* Update info in previous slot */
pg_atomic_sub_fetch_u32((pg_atomic_uint32*)&prevSlot->nProcs, 1);
groupReleaseMemQuota(prevGroup, prevSlot);
}
/* now attach to the new one */
groupAcquireMemQuota(group, &slot->caps);
LWLockRelease(ResGroupLock);
/* Add proc memory accounting info into group and slot */
groupIncMemUsage(group, slot, self->memUsage);
/* Update info in new slot */
pg_atomic_add_fetch_u32((pg_atomic_uint32*)&slot->nProcs, 1);
} }
else
{
Assert(!slot->inUse);
slot->inUse = true;
initSlot(slot, &caps, gp_session_id);
group->nRunning++;
}
selfAttachToSlot(group, slot);
self->group = group; ResGroupSetMemorySpillRatio(&caps);
groupAcquireMemQuota(group, &slot->caps);
LWLockRelease(ResGroupLock);
/* finally we can say we are in a valid resgroup */ /* finally we can say we are in a valid resgroup */
Assert(selfIsAssignedValidGroup()); Assert(selfIsAssignedValidGroup());
...@@ -2638,10 +2620,8 @@ selfUnsetGroup(void) ...@@ -2638,10 +2620,8 @@ selfUnsetGroup(void)
* - self must has not been set a slot before set; * - self must has not been set a slot before set;
*/ */
static void static void
selfSetSlot(void) selfSetSlot(int slotId)
{ {
int slotId = MyProc->resSlotId;
Assert(selfHasGroup()); Assert(selfHasGroup());
Assert(!selfHasSlot()); Assert(!selfHasSlot());
Assert(slotId != InvalidSlotId); Assert(slotId != InvalidSlotId);
......
...@@ -109,11 +109,15 @@ extern void FreeResGroupEntry(Oid groupId); ...@@ -109,11 +109,15 @@ extern void FreeResGroupEntry(Oid groupId);
extern void SerializeResGroupInfo(StringInfo str); extern void SerializeResGroupInfo(StringInfo str);
extern void DeserializeResGroupInfo(struct ResGroupCaps *capsOut, extern void DeserializeResGroupInfo(struct ResGroupCaps *capsOut,
const char *buf, int len); Oid *groupId,
int *slotId,
const char *buf,
int len);
extern bool ShouldAssignResGroupOnMaster(void); extern bool ShouldAssignResGroupOnMaster(void);
extern bool ShouldUnassignResGroup(void);
extern void AssignResGroupOnMaster(void); extern void AssignResGroupOnMaster(void);
extern void UnassignResGroupOnMaster(void); extern void UnassignResGroup(void);
extern void SwitchResGroupOnSegment(const char *buf, int len); extern void SwitchResGroupOnSegment(const char *buf, int len);
/* Retrieve statistic information of type from resource group */ /* Retrieve statistic information of type from resource group */
......
...@@ -124,7 +124,7 @@ SET ...@@ -124,7 +124,7 @@ SET
SELECT * FROM memory_result; SELECT * FROM memory_result;
rsgname |ismaster|avg_mem rsgname |ismaster|avg_mem
---------------+--------+------- ---------------+--------+-------
rg1_memory_test|0 |20 rg1_memory_test|0 |0
rg1_memory_test|1 |0 rg1_memory_test|1 |0
rg2_memory_test|0 |0 rg2_memory_test|0 |0
rg2_memory_test|1 |0 rg2_memory_test|1 |0
...@@ -162,7 +162,7 @@ SET ...@@ -162,7 +162,7 @@ SET
SELECT * FROM memory_result; SELECT * FROM memory_result;
rsgname |ismaster|avg_mem rsgname |ismaster|avg_mem
---------------+--------+------- ---------------+--------+-------
rg1_memory_test|0 |20 rg1_memory_test|0 |0
rg1_memory_test|1 |0 rg1_memory_test|1 |0
rg2_memory_test|0 |0 rg2_memory_test|0 |0
rg2_memory_test|1 |0 rg2_memory_test|1 |0
...@@ -179,7 +179,7 @@ rsgname |ismaster|avg_mem ...@@ -179,7 +179,7 @@ rsgname |ismaster|avg_mem
---------------+--------+------- ---------------+--------+-------
rg1_memory_test|0 |0 rg1_memory_test|0 |0
rg1_memory_test|1 |0 rg1_memory_test|1 |0
rg2_memory_test|0 |40 rg2_memory_test|0 |0
rg2_memory_test|1 |0 rg2_memory_test|1 |0
(4 rows) (4 rows)
1q: ... <quitting> 1q: ... <quitting>
...@@ -195,7 +195,7 @@ SET ...@@ -195,7 +195,7 @@ SET
SELECT * FROM memory_result; SELECT * FROM memory_result;
rsgname |ismaster|avg_mem rsgname |ismaster|avg_mem
---------------+--------+------- ---------------+--------+-------
rg1_memory_test|0 |40 rg1_memory_test|0 |0
rg1_memory_test|1 |0 rg1_memory_test|1 |0
rg2_memory_test|0 |0 rg2_memory_test|0 |0
rg2_memory_test|1 |0 rg2_memory_test|1 |0
...@@ -231,7 +231,7 @@ SET ...@@ -231,7 +231,7 @@ SET
SELECT * FROM memory_result; SELECT * FROM memory_result;
rsgname |ismaster|avg_mem rsgname |ismaster|avg_mem
---------------+--------+------- ---------------+--------+-------
rg1_memory_test|0 |80 rg1_memory_test|0 |0
rg1_memory_test|1 |0 rg1_memory_test|1 |0
rg2_memory_test|0 |0 rg2_memory_test|0 |0
rg2_memory_test|1 |0 rg2_memory_test|1 |0
...@@ -258,9 +258,9 @@ count ...@@ -258,9 +258,9 @@ count
SELECT * FROM memory_result; SELECT * FROM memory_result;
rsgname |ismaster|avg_mem rsgname |ismaster|avg_mem
---------------+--------+------- ---------------+--------+-------
rg1_memory_test|0 |40 rg1_memory_test|0 |0
rg1_memory_test|1 |0 rg1_memory_test|1 |0
rg2_memory_test|0 |40 rg2_memory_test|0 |0
rg2_memory_test|1 |0 rg2_memory_test|1 |0
(4 rows) (4 rows)
1q: ... <quitting> 1q: ... <quitting>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册