未验证 提交 3be31490 编写于 作者: J Jialun 提交者: GitHub

User query can use global shared memory across resource group when...

User query can use global shared memory across resource group when available(Same as the PR 4843, just made the test cases stable) (#4866)

1) Global shared memory will be used if the query has run out of
	the group shared memory.
2) The limit of memory_spill_ratio changes to [0, INT_MAX], because
	global shared memory can be allocated, 100% limitation is not
	make sense.
3) Using Atomic Operation & "Compare And Save" instead of lock to
	get high performance.
4) Modify the test cases according to the new rules.
上级 4c8f28b0
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
#define RESGROUP_MAX_MEMORY_SHARED_QUOTA (100) #define RESGROUP_MAX_MEMORY_SHARED_QUOTA (100)
#define RESGROUP_MIN_MEMORY_SPILL_RATIO (0) #define RESGROUP_MIN_MEMORY_SPILL_RATIO (0)
#define RESGROUP_MAX_MEMORY_SPILL_RATIO (100) #define RESGROUP_MAX_MEMORY_SPILL_RATIO (INT_MAX)
/* /*
* The names must be in the same order as ResGroupMemAuditorType. * The names must be in the same order as ResGroupMemAuditorType.
......
...@@ -2974,7 +2974,7 @@ struct config_int ConfigureNamesInt_gp[] = ...@@ -2974,7 +2974,7 @@ struct config_int ConfigureNamesInt_gp[] =
NULL NULL
}, },
&memory_spill_ratio, &memory_spill_ratio,
20, 0, 100, NULL, NULL 20, 0, INT_MAX, NULL, NULL
}, },
{ {
......
...@@ -169,7 +169,7 @@ struct ResGroupData ...@@ -169,7 +169,7 @@ struct ResGroupData
{ {
Oid groupId; /* Id for this group */ Oid groupId; /* Id for this group */
ResGroupCaps caps; /* capabilities of this group */ ResGroupCaps caps; /* capabilities of this group */
int nRunning; /* number of running trans */ volatile int nRunning; /* number of running trans */
PROC_QUEUE waitProcs; /* list of PGPROC objects waiting on this group */ PROC_QUEUE waitProcs; /* list of PGPROC objects waiting on this group */
int totalExecuted; /* total number of executed trans */ int totalExecuted; /* total number of executed trans */
int totalQueued; /* total number of queued trans */ int totalQueued; /* total number of queued trans */
...@@ -191,15 +191,15 @@ struct ResGroupData ...@@ -191,15 +191,15 @@ struct ResGroupData
int32 memQuotaGranted; /* memory chunks for quota part */ int32 memQuotaGranted; /* memory chunks for quota part */
int32 memSharedGranted; /* memory chunks for shared part */ int32 memSharedGranted; /* memory chunks for shared part */
int32 memQuotaUsed; /* memory chunks assigned to all the running slots */ volatile int32 memQuotaUsed; /* memory chunks assigned to all the running slots */
/* /*
* memory usage of this group, should always equal to the * memory usage of this group, should always equal to the
* sum of session memory(session_state->sessionVmem) that * sum of session memory(session_state->sessionVmem) that
* belongs to this group * belongs to this group
*/ */
int32 memUsage; volatile int32 memUsage;
int32 memSharedUsage; volatile int32 memSharedUsage;
/* /*
* operation functions for resource group * operation functions for resource group
...@@ -219,7 +219,9 @@ struct ResGroupControl ...@@ -219,7 +219,9 @@ struct ResGroupControl
bool loaded; bool loaded;
int32 totalChunks; /* total memory chunks on this segment */ int32 totalChunks; /* total memory chunks on this segment */
int32 freeChunks; /* memory chunks not allocated to any group */ volatile int32 freeChunks; /* memory chunks not allocated to any group,
will be used for the query which group share
memory is not enough*/
int32 chunkSizeInBits; int32 chunkSizeInBits;
...@@ -279,9 +281,9 @@ static void groupReleaseMemQuota(ResGroupData *group, ResGroupSlotData *slot); ...@@ -279,9 +281,9 @@ static void groupReleaseMemQuota(ResGroupData *group, ResGroupSlotData *slot);
static int32 groupIncMemUsage(ResGroupData *group, static int32 groupIncMemUsage(ResGroupData *group,
ResGroupSlotData *slot, ResGroupSlotData *slot,
int32 chunks); int32 chunks);
static void groupDecMemUsage(ResGroupData *group, static int32 groupDecMemUsage(ResGroupData *group,
ResGroupSlotData *slot, ResGroupSlotData *slot,
int32 chunks); int32 chunks);
static void initSlot(ResGroupSlotData *slot, ResGroupData *group, static void initSlot(ResGroupSlotData *slot, ResGroupData *group,
int32 slotMemQuota); int32 slotMemQuota);
static void selfAttachResGroup(ResGroupData *group, ResGroupSlotData *slot); static void selfAttachResGroup(ResGroupData *group, ResGroupSlotData *slot);
...@@ -954,24 +956,27 @@ ResGroupReserveMemory(int32 memoryChunks, int32 overuseChunks, bool *waiverUsed) ...@@ -954,24 +956,27 @@ ResGroupReserveMemory(int32 memoryChunks, int32 overuseChunks, bool *waiverUsed)
overuseMem = groupIncMemUsage(group, slot, memoryChunks); overuseMem = groupIncMemUsage(group, slot, memoryChunks);
/* then check whether there is over usage */ /* then check whether there is over usage */
if (CritSectionCount == 0 && overuseMem > overuseChunks) if (CritSectionCount == 0)
{ {
/* if the over usage is larger than allowed then revert the change */ if (overuseMem > overuseChunks)
groupDecMemUsage(group, slot, memoryChunks); {
/* if the over usage is larger than allowed then revert the change */
groupDecMemUsage(group, slot, memoryChunks);
/* also revert in proc */ /* also revert in proc */
self->memUsage -= memoryChunks; self->memUsage -= memoryChunks;
Assert(self->memUsage >= 0); Assert(self->memUsage >= 0);
if (overuseChunks == 0) if (overuseChunks == 0)
ResGroupDumpMemoryInfo(); ResGroupDumpMemoryInfo();
return false; return false;
} }
else if (CritSectionCount == 0 && overuseMem > 0) else if (overuseMem > 0)
{ {
/* the over usage is within the allowed threshold */ /* the over usage is within the allowed threshold */
*waiverUsed = true; *waiverUsed = true;
}
} }
return true; return true;
...@@ -1106,14 +1111,15 @@ bindGroupOperation(ResGroupData *group) ...@@ -1106,14 +1111,15 @@ bindGroupOperation(ResGroupData *group)
/* /*
* Add chunks into group and slot memory usage. * Add chunks into group and slot memory usage.
* *
* Return the over used chunks. * Return the total over used chunks of global share
*/ */
static int32 static int32
groupIncMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks) groupIncMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks)
{ {
int32 slotMemUsage; int32 slotMemUsage; /* the memory current slot has been used */
int32 sharedMemUsage; int32 sharedMemUsage; /* the total shared memory usage,
int32 overuseMem = 0; sum of group share and global share */
int32 globalOveruse = 0; /* the total over used chunks of global share*/
/* Add the chunks to memUsage in slot */ /* Add the chunks to memUsage in slot */
slotMemUsage = pg_atomic_add_fetch_u32((pg_atomic_uint32 *) &slot->memUsage, slotMemUsage = pg_atomic_add_fetch_u32((pg_atomic_uint32 *) &slot->memUsage,
...@@ -1123,30 +1129,40 @@ groupIncMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks) ...@@ -1123,30 +1129,40 @@ groupIncMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks)
sharedMemUsage = slotMemUsage - slot->memQuota; sharedMemUsage = slotMemUsage - slot->memQuota;
if (sharedMemUsage > 0) if (sharedMemUsage > 0)
{ {
int32 total;
/* Decide how many chunks should be counted as shared memory */ /* Decide how many chunks should be counted as shared memory */
sharedMemUsage = Min(sharedMemUsage, chunks); int32 deltaSharedMemUsage = Min(sharedMemUsage, chunks);
/* Add these chunks to memSharedUsage in group */ /* Add these chunks to memSharedUsage in group,
total = pg_atomic_add_fetch_u32((pg_atomic_uint32 *) &group->memSharedUsage, * and record the old value*/
sharedMemUsage); int32 oldSharedUsage = pg_atomic_fetch_add_u32((pg_atomic_uint32 *)
&group->memSharedUsage,
/* Calculate the over used chunks */ deltaSharedMemUsage);
overuseMem = Max(0, total - group->memSharedGranted); /* the free space of group share */
int32 oldSharedFree = Max(0, group->memSharedGranted - oldSharedUsage);
/* Calculate the global over used chunks */
int32 deltaGlobalSharedMemUsage = Max(0, deltaSharedMemUsage - oldSharedFree);
/* freeChunks -= deltaGlobalSharedMemUsage and get the new value */
int32 newFreeChunks = pg_atomic_sub_fetch_u32((pg_atomic_uint32 *)
&pResGroupControl->freeChunks,
deltaGlobalSharedMemUsage);
/* calculate the total over used chunks of global share */
globalOveruse = Max(0, 0 - newFreeChunks);
} }
/* Add the chunks to memUsage in group */ /* Add the chunks to memUsage in group */
pg_atomic_add_fetch_u32((pg_atomic_uint32 *) &group->memUsage, pg_atomic_add_fetch_u32((pg_atomic_uint32 *) &group->memUsage,
chunks); chunks);
return overuseMem; return globalOveruse;
} }
/* /*
* Sub chunks from group and slot memory usage. * Sub chunks from group ,slot memory usage and global shared memory.
* return memory chunks of global shared released this time
*/ */
static void static int32
groupDecMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks) groupDecMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks)
{ {
int32 value; int32 value;
...@@ -1168,13 +1184,25 @@ groupDecMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks) ...@@ -1168,13 +1184,25 @@ groupDecMemUsage(ResGroupData *group, ResGroupSlotData *slot, int32 chunks)
if (sharedMemUsage > 0) if (sharedMemUsage > 0)
{ {
/* Decide how many chunks should be counted as shared memory */ /* Decide how many chunks should be counted as shared memory */
sharedMemUsage = Min(sharedMemUsage, chunks); int32 deltaSharedMemUsage = Min(sharedMemUsage, chunks);
/* Sub chunks from memSharedUsage in group */ /* Sub chunks from memSharedUsage in group */
value = pg_atomic_sub_fetch_u32((pg_atomic_uint32 *) &group->memSharedUsage, int32 oldSharedUsage = pg_atomic_fetch_sub_u32((pg_atomic_uint32 *) &group->memSharedUsage,
sharedMemUsage); deltaSharedMemUsage);
Assert(value >= 0); Assert(oldSharedUsage >= deltaSharedMemUsage);
/* record the total global share usage of current group */
int32 grpTotalGlobalUsage = Max(0, oldSharedUsage - group->memSharedGranted);
/* calculate the global share usage of current release */
int32 deltaGlobalSharedMemUsage = Min(grpTotalGlobalUsage, deltaSharedMemUsage);
/* add chunks to global shared memory */
pg_atomic_add_fetch_u32((pg_atomic_uint32 *)
&pResGroupControl->freeChunks,
deltaGlobalSharedMemUsage);
return deltaGlobalSharedMemUsage;
} }
return 0;
} }
/* /*
...@@ -1593,18 +1621,34 @@ groupApplyMemCaps(ResGroupData *group) ...@@ -1593,18 +1621,34 @@ groupApplyMemCaps(ResGroupData *group)
static int32 static int32
mempoolReserve(Oid groupId, int32 chunks) mempoolReserve(Oid groupId, int32 chunks)
{ {
int32 oldFreeChunks;
int32 newFreeChunks;
int32 reserved = 0;
Assert(LWLockHeldExclusiveByMe(ResGroupLock)); Assert(LWLockHeldExclusiveByMe(ResGroupLock));
LOG_RESGROUP_DEBUG(LOG, "allocate %u out of %u chunks to group %d", /* Compare And Save to avoid concurrency problem without using lock */
chunks, pResGroupControl->freeChunks, groupId); while (true)
{
oldFreeChunks = pg_atomic_read_u32((pg_atomic_uint32 *)
&pResGroupControl->freeChunks);
reserved = Min(Max(0, oldFreeChunks), chunks);
newFreeChunks = oldFreeChunks - reserved;
if (reserved == 0)
break;
if (pg_atomic_compare_exchange_u32((pg_atomic_uint32 *)
&pResGroupControl->freeChunks,
(uint32 *) &oldFreeChunks,
(uint32) newFreeChunks))
break;
}
chunks = Min(pResGroupControl->freeChunks, chunks); LOG_RESGROUP_DEBUG(LOG, "allocate %u out of %u chunks to group %d",
pResGroupControl->freeChunks -= chunks; reserved, oldFreeChunks, groupId);
Assert(pResGroupControl->freeChunks >= 0); Assert(newFreeChunks <= pResGroupControl->totalChunks);
Assert(pResGroupControl->freeChunks <= pResGroupControl->totalChunks);
return chunks; return reserved;
} }
/* /*
...@@ -1613,16 +1657,19 @@ mempoolReserve(Oid groupId, int32 chunks) ...@@ -1613,16 +1657,19 @@ mempoolReserve(Oid groupId, int32 chunks)
static void static void
mempoolRelease(Oid groupId, int32 chunks) mempoolRelease(Oid groupId, int32 chunks)
{ {
LOG_RESGROUP_DEBUG(LOG, "free %u to pool(%u) chunks from group %d", int32 newFreeChunks;
chunks, pResGroupControl->freeChunks, groupId);
Assert(LWLockHeldExclusiveByMe(ResGroupLock)); Assert(LWLockHeldExclusiveByMe(ResGroupLock));
Assert(chunks >= 0); Assert(chunks >= 0);
pResGroupControl->freeChunks += chunks; newFreeChunks = pg_atomic_add_fetch_u32((pg_atomic_uint32 *)
&pResGroupControl->freeChunks,
chunks);
LOG_RESGROUP_DEBUG(LOG, "free %u to pool(%u) chunks from group %d",
chunks, newFreeChunks - chunks, groupId);
Assert(pResGroupControl->freeChunks >= 0); Assert(newFreeChunks <= pResGroupControl->totalChunks);
Assert(pResGroupControl->freeChunks <= pResGroupControl->totalChunks);
} }
/* /*
......
...@@ -25,7 +25,7 @@ groupname |memory_shared_quota|proposed_memory_shared_quota|memory_spill_rati ...@@ -25,7 +25,7 @@ groupname |memory_shared_quota|proposed_memory_shared_quota|memory_spill_rati
rg_spill_test|20 |20 |20 |20 rg_spill_test|20 |20 |20 |20
(1 row) (1 row)
-- positive, memory_spill_ratio range is [0, 100] -- positive, memory_spill_ratio range is [0, 2147483647]
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 0; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 0;
ALTER ALTER
SELECT * FROM rg_spill_status; SELECT * FROM rg_spill_status;
...@@ -58,9 +58,9 @@ groupname |memory_shared_quota|proposed_memory_shared_quota|memory_spill_rati ...@@ -58,9 +58,9 @@ groupname |memory_shared_quota|proposed_memory_shared_quota|memory_spill_rati
rg_spill_test|20 |20 |81 |81 rg_spill_test|20 |20 |81 |81
(1 row) (1 row)
-- negative: memory_spill_ratio is larger than RESGROUP_MAX_MEMORY_SPILL_RATIO -- negative: memory_spill_ratio is negative
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 101; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO -1;
ERROR: memory_spill_ratio range is [0, 100] ERROR: memory_spill_ratio range is [0, 2147483647]
SELECT * FROM rg_spill_status; SELECT * FROM rg_spill_status;
groupname |memory_shared_quota|proposed_memory_shared_quota|memory_spill_ratio|proposed_memory_spill_ratio groupname |memory_shared_quota|proposed_memory_shared_quota|memory_spill_ratio|proposed_memory_spill_ratio
-------------+-------------------+----------------------------+------------------+--------------------------- -------------+-------------------+----------------------------+------------------+---------------------------
......
...@@ -63,8 +63,8 @@ SELECT 1; ...@@ -63,8 +63,8 @@ SELECT 1;
(1 row) (1 row)
-- negative set to session level -- negative set to session level
SET MEMORY_SPILL_RATIO TO 101; SET MEMORY_SPILL_RATIO TO -1;
ERROR: 101 is outside the valid range for parameter "memory_spill_ratio" (0 .. 100) ERROR: -1 is outside the valid range for parameter "memory_spill_ratio" (0 .. 2147483647)
SHOW MEMORY_SPILL_RATIO; SHOW MEMORY_SPILL_RATIO;
memory_spill_ratio memory_spill_ratio
------------------ ------------------
......
...@@ -176,7 +176,7 @@ ERROR: memory_auditor should be "vmtracker" or "cgroup" ...@@ -176,7 +176,7 @@ ERROR: memory_auditor should be "vmtracker" or "cgroup"
CREATE RESOURCE GROUP rg_test_group WITH (concurrency=1, cpu_rate_limit=10, memory_limit=10, memory_auditor="cgroup"); CREATE RESOURCE GROUP rg_test_group WITH (concurrency=1, cpu_rate_limit=10, memory_limit=10, memory_auditor="cgroup");
ERROR: resource group concurrency must be 0 when group memory_auditor is cgroup ERROR: resource group concurrency must be 0 when group memory_auditor is cgroup
-- memory_spill_ratio range is [0, 100] -- memory_spill_ratio range is [0, 2147483647]
-- no limit on the sum of memory_shared_quota and memory_spill_ratio -- no limit on the sum of memory_shared_quota and memory_spill_ratio
CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=10, memory_spill_ratio=0); CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=10, memory_spill_ratio=0);
CREATE CREATE
...@@ -187,7 +187,7 @@ CREATE ...@@ -187,7 +187,7 @@ CREATE
DROP RESOURCE GROUP rg_test_group; DROP RESOURCE GROUP rg_test_group;
DROP DROP
CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=10, memory_spill_ratio=-1); CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=10, memory_spill_ratio=-1);
ERROR: memory_spill_ratio range is [0, 100] ERROR: memory_spill_ratio range is [0, 2147483647]
CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=-1, memory_spill_ratio=10); CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=-1, memory_spill_ratio=10);
ERROR: memory_shared_quota range is [0, 100] ERROR: memory_shared_quota range is [0, 100]
...@@ -251,7 +251,7 @@ CREATE ...@@ -251,7 +251,7 @@ CREATE
DROP RESOURCE GROUP rg_test_group; DROP RESOURCE GROUP rg_test_group;
DROP DROP
-- memory_spill_ratio range is [0, 100] -- memory_spill_ratio range is [0, 2147483647]
-- no limit on the sum of memory_shared_quota and memory_spill_ratio -- no limit on the sum of memory_shared_quota and memory_spill_ratio
CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=0, memory_spill_ratio=1); CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=0, memory_spill_ratio=1);
CREATE CREATE
......
...@@ -20,12 +20,7 @@ DROP RESOURCE GROUP rg_spill_test; ...@@ -20,12 +20,7 @@ DROP RESOURCE GROUP rg_spill_test;
DROP DROP
CREATE RESOURCE GROUP rg_spill_test WITH (concurrency=10, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50, memory_spill_ratio=-1); CREATE RESOURCE GROUP rg_spill_test WITH (concurrency=10, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50, memory_spill_ratio=-1);
ERROR: memory_spill_ratio range is [0, 100] ERROR: memory_spill_ratio range is [0, 2147483647]
DROP RESOURCE GROUP rg_spill_test;
ERROR: resource group "rg_spill_test" does not exist
CREATE RESOURCE GROUP rg_spill_test WITH (concurrency=10, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50, memory_spill_ratio=101);
ERROR: memory_spill_ratio range is [0, 100]
DROP RESOURCE GROUP rg_spill_test; DROP RESOURCE GROUP rg_spill_test;
ERROR: resource group "rg_spill_test" does not exist ERROR: resource group "rg_spill_test" does not exist
...@@ -40,9 +35,9 @@ ALTER ...@@ -40,9 +35,9 @@ ALTER
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 100; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 100;
ALTER ALTER
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO -1; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO -1;
ERROR: memory_spill_ratio range is [0, 100] ERROR: memory_spill_ratio range is [0, 2147483647]
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 101; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 10000;
ERROR: memory_spill_ratio range is [0, 100] ALTER
DROP RESOURCE GROUP rg_spill_test; DROP RESOURCE GROUP rg_spill_test;
DROP DROP
...@@ -91,7 +86,7 @@ SELECT 1; ...@@ -91,7 +86,7 @@ SELECT 1;
(1 row) (1 row)
SET MEMORY_SPILL_RATIO TO -1; SET MEMORY_SPILL_RATIO TO -1;
ERROR: -1 is outside the valid range for parameter "memory_spill_ratio" (0 .. 100) ERROR: -1 is outside the valid range for parameter "memory_spill_ratio" (0 .. 2147483647)
SHOW MEMORY_SPILL_RATIO; SHOW MEMORY_SPILL_RATIO;
memory_spill_ratio memory_spill_ratio
------------------ ------------------
...@@ -103,12 +98,12 @@ SELECT 1; ...@@ -103,12 +98,12 @@ SELECT 1;
1 1
(1 row) (1 row)
SET MEMORY_SPILL_RATIO TO 101; SET MEMORY_SPILL_RATIO TO 10000;
ERROR: 101 is outside the valid range for parameter "memory_spill_ratio" (0 .. 100) SET
SHOW MEMORY_SPILL_RATIO; SHOW MEMORY_SPILL_RATIO;
memory_spill_ratio memory_spill_ratio
------------------ ------------------
100 10000
(1 row) (1 row)
SELECT 1; SELECT 1;
?column? ?column?
......
-- start_ignore -- start_ignore
DROP ROLE IF EXISTS role1_memory_test; DROP ROLE IF EXISTS role1_memory_test;
DROP RESOURCE GROUP rg1_memory_test; DROP RESOURCE GROUP rg1_memory_test;
DROP RESOURCE GROUP rg2_memory_test;
-- end_ignore -- end_ignore
CREATE OR REPLACE FUNCTION resGroupPalloc(float) RETURNS int AS CREATE OR REPLACE FUNCTION resGroupPalloc(float) RETURNS int AS
'@abs_builddir@/../regress/regress@DLSUFFIX@', 'resGroupPalloc' '@abs_builddir@/../regress/regress@DLSUFFIX@', 'resGroupPalloc'
LANGUAGE C READS SQL DATA; LANGUAGE C READS SQL DATA;
CREATE OR REPLACE FUNCTION hold_memory_by_percent(int, float) RETURNS int AS $$ CREATE OR REPLACE FUNCTION hold_memory_by_percent(float) RETURNS int AS $$
SELECT * FROM resGroupPalloc($2) SELECT * FROM resGroupPalloc($1)
$$ LANGUAGE sql; $$ LANGUAGE sql;
-- CREATE OR REPLACE VIEW rg_mem_status AS
-- first create the resgroup with memory_shared_quota == 0. SELECT groupname, memory_limit, proposed_memory_limit,
-- so each resgroup slot gets a fixed memory quota of 0.5. memory_shared_quota, proposed_memory_shared_quota
-- FROM gp_toolkit.gp_resgroup_config
WHERE groupname='rg1_memory_test' OR groupname='rg2_memory_test'
ORDER BY groupid;
CREATE OR REPLACE VIEW memory_result AS SELECT rsgname, memory_usage from gp_toolkit.gp_resgroup_status;
-- 1) single allocation
-- Group Share Quota = 0
-- Global Share Quota > 0
-- Slot Quota > 0
-- -----------------------
-- we assume system total chunks is 100%
-- rg1's expected: 100% * 52% => 52%
-- rg1's slot quota: 52% / 2 * 2 => 52%
-- rg1's single slot quota: 52% / 2 => 26%
-- rg1's shared quota: %52 - %52 => %0
-- system free chunks: 100% - 10% - 30% - 52% => 8%
-- memory available to one slot in rg1: 52%/2 + 0% + 8% => 34%
CREATE RESOURCE GROUP rg1_memory_test CREATE RESOURCE GROUP rg1_memory_test
WITH (concurrency=2, cpu_rate_limit=10, WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=50, memory_shared_quota=0); memory_limit=52, memory_shared_quota=0);
CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test; CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test;
-- 1) on QD only with memory_shared_quota == 0 -- 1a) on QD
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(1,0.2); 1: SELECT hold_memory_by_percent(0.14 / 0.52);
1: SELECT hold_memory_by_percent(1,0.2); 1: SELECT hold_memory_by_percent(0.14 / 0.52);
1: SELECT hold_memory_by_percent(1,0.2); 1: SELECT hold_memory_by_percent(0.14 / 0.52);
1q: 1q:
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: BEGIN; 1: BEGIN;
1: SELECT hold_memory_by_percent(1,0.2); 1: SELECT hold_memory_by_percent(0.14 / 0.52);
1: SELECT hold_memory_by_percent(1,0.2); 1: SELECT hold_memory_by_percent(0.14 / 0.52);
1: SELECT hold_memory_by_percent(1,0.2); 1: SELECT hold_memory_by_percent(0.14 / 0.52);
1q: 1q:
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(1,0.45); 1: SELECT hold_memory_by_percent(0.42 / 0.52);
1: SELECT hold_memory_by_percent(1,0.45);
1q: 1q:
-- 1b) on QEs
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: BEGIN; 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.14 / 0.52)=0;
1: SELECT hold_memory_by_percent(1,0.45); 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.14 / 0.52)=0;
1: SELECT hold_memory_by_percent(1,0.45); 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.14 / 0.52)=0;
1q: 1q:
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(1,0.55); 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.42 / 0.52)=0;
1q: 1q:
-- 2) on QEs with memory_shared_quota == 0 DROP ROLE role1_memory_test;
DROP RESOURCE GROUP rg1_memory_test;
-- 2) single allocation
-- Group Share Quota > 0
-- Global Share Quota > 0
-- Slot Quota > 0
-- -----------------------
-- we assume system total chunks is 100%
-- rg1's expected: 100% * 52 / 100 => 52%
-- rg1's slot quota: 52% * 60 /100 => 31%
-- rg1's single slot quota: 31% / 2 => 15.5%
-- rg1's shared quota: 52% - 31% => 21%
-- system free chunks: 100% - 10% - 30% - 52% => 8%
-- memory available to one slot in rg1: 15.5% + 21% + 8% => 44.5%
CREATE RESOURCE GROUP rg1_memory_test
WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=52, memory_shared_quota=40);
CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test;
-- 2a) on QD
1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(0.12 / 0.52);
1: SELECT hold_memory_by_percent(0.12 / 0.52);
1: SELECT hold_memory_by_percent(0.12 / 0.52);
1: SELECT hold_memory_by_percent(0.12 / 0.52);
1q:
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0; 1: BEGIN;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0; 1: SELECT hold_memory_by_percent(0.12 / 0.52);
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0; 1: SELECT hold_memory_by_percent(0.12 / 0.52);
1: SELECT hold_memory_by_percent(0.12 / 0.52);
1: SELECT hold_memory_by_percent(0.12 / 0.52);
1q: 1q:
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.45)=0; 1: SELECT hold_memory_by_percent(0.48 / 0.52);
1q: 1q:
-- 2b) on QEs
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.55)=0; 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.12 / 0.52)=0;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.12 / 0.52)=0;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.12 / 0.52)=0;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.12 / 0.52)=0;
1q: 1q:
-- 1: SET ROLE TO role1_memory_test;
-- now recreate the resgroup with memory_shared_quota > 0. 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.48 / 0.52)=0;
-- so each resgroup slot gets a fixed memory quota of 0.3, 1q:
-- there is also a shared memory pool of 0.4, so the actual
-- memory usage in each slot can be 0.3~0.7.
--
DROP ROLE role1_memory_test; DROP ROLE role1_memory_test;
DROP RESOURCE GROUP rg1_memory_test; DROP RESOURCE GROUP rg1_memory_test;
-- 3) single allocation
-- Group Share Quota > 0
-- Global Share Quota > 0
-- Slot Quota = 0
-- -----------------------
-- we assume system total chunks is 100%
-- rg1's expected: 100% * 52 / 100 => 52%
-- rg1's slot quota: 0
-- rg1's shared quota: 52%
-- system free chunks: 100% - 10% - 30% - 52% => 8%
-- memory available to one slot in rg1: 52% + 8% => 60%
CREATE RESOURCE GROUP rg1_memory_test CREATE RESOURCE GROUP rg1_memory_test
WITH (concurrency=2, cpu_rate_limit=10, WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=10, memory_shared_quota=40); memory_limit=52, memory_shared_quota=100);
CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test; CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test;
-- 3) on QD with memory_shared_quota > 0 -- 3a) on QD
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(1,0.65); 1: SELECT hold_memory_by_percent(0.25 / 0.52);
1: SELECT hold_memory_by_percent(0.25 / 0.52);
1: SELECT hold_memory_by_percent(0.25 / 0.52);
1q: 1q:
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(1,0.75); 1: BEGIN;
1: SELECT hold_memory_by_percent(0.25 / 0.52);
1: SELECT hold_memory_by_percent(0.25 / 0.52);
1: SELECT hold_memory_by_percent(0.25 / 0.52);
1q: 1q:
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(1,0.2); 1: SELECT hold_memory_by_percent(0.75 / 0.52);
1: SELECT hold_memory_by_percent(1,0.2);
1: SELECT hold_memory_by_percent(1,0.2);
1: SELECT hold_memory_by_percent(1,0.2);
1q: 1q:
-- 4) on QEs with memory_shared_quota > 0 -- 3b) on QEs
1: SET ROLE TO role1_memory_test;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.25 / 0.52)=0;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.25 / 0.52)=0;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.25 / 0.52)=0;
1q:
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0; 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.75 / 0.52)=0;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0;
1q: 1q:
-- 5) QD: concurrent transactions in same group with memory_shared_quota > 0 DROP ROLE role1_memory_test;
DROP RESOURCE GROUP rg1_memory_test;
-- 4) multi allocation in one group
-- Group Share Quota = 0
-- Global Share Quota > 0
-- Slot Quota > 0
-- -----------------------
-- we assume system total chunks is 100%
-- rg1's expected: 100% * 52 / 100 => 52%
-- rg1's slot quota: 52% / 2 * 2 => 52%
-- rg1's single slot quota: 52% / 2 => 26%
-- rg1's shared quota: 0
-- system free chunks: 100% - 10% - 30% - 52% => 8%
-- memory available to one slot in rg1: 26% + 8% => 34%
CREATE RESOURCE GROUP rg1_memory_test
WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=52, memory_shared_quota=0);
CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test;
-- 4a) on QD
-- not exceed the global share
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
1: BEGIN;
1: SELECT hold_memory_by_percent(1,0.6);
2: SET ROLE TO role1_memory_test; 2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN; 2: BEGIN;
2: SELECT hold_memory_by_percent(1,0.3); 1: SELECT hold_memory_by_percent(0.28 / 0.52);
2: SELECT hold_memory_by_percent(0.28 / 0.52);
1q:
2q: 2q:
-- exceed the global share
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test; 2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN; 2: BEGIN;
2: SELECT hold_memory_by_percent(1,0.3); 1: SELECT hold_memory_by_percent(0.32 / 0.52);
2: SELECT hold_memory_by_percent(1,0.2); 2: SELECT hold_memory_by_percent(0.32 / 0.52);
2q:
1q: 1q:
2q:
-- 6) QE: concurrent transactions in same group with memory_shared_quota > 0 -- allocate serially
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN;
1: SELECT hold_memory_by_percent(0.32 / 0.52);
1q:
SELECT pg_sleep(1);
2: SELECT hold_memory_by_percent(0.32 / 0.52);
2q:
-- 4b) on QEs
-- not exceed the global share
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test;
1: BEGIN; 1: BEGIN;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.6)=0; 2: BEGIN;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.28 / 0.52)=0;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.28 / 0.52)=0;
1q:
2q:
-- exceed the global share
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test; 2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN; 2: BEGIN;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.3)=0; 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.32 / 0.52)=0;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.32 / 0.52)=0;
1q:
2q: 2q:
-- allocate serially
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test; 2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN; 2: BEGIN;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.3)=0; 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.32 / 0.52)=0;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0; 1q:
SELECT pg_sleep(1);
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.32 / 0.52)=0;
2q: 2q:
DROP ROLE role1_memory_test;
DROP RESOURCE GROUP rg1_memory_test;
-- 5) multi allocation in one group
-- Group Share Quota > 0
-- Global Share Quota > 0
-- Slot Quota > 0
-- -----------------------
-- we assume system total chunks is 100%
-- rg1's expected: 100% * 52 / 100 => 52%
-- rg1's slot quota: 52% * 50 / 100 => 26%
-- rg1's single slot quota: 26% / 2 => 13%
-- rg1's shared quota: 52% - 13% * 2 => 26%
-- system free chunks: 100% - 10% - 30% - 52% => 8%
-- memory available to one slot in rg1: 13% + 26% + 8% => 47%
CREATE RESOURCE GROUP rg1_memory_test
WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=52, memory_shared_quota=50);
CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test;
-- 5a) on QD
-- not exceed the global share
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN;
-- reserve all the group shared quota
1: SELECT hold_memory_by_percent(0.39 / 0.52);
-- must allocate from global share
2: SELECT hold_memory_by_percent(0.2 / 0.52);
1q: 1q:
2q:
-- 7) QD: concurrent transactions in same group with memory_shared_quota = 100 -- exceed the global share
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN;
1: SELECT hold_memory_by_percent(0.39 / 0.52);
2: SELECT hold_memory_by_percent(0.39 / 0.52);
1q:
2q:
ALTER RESOURCE GROUP rg1_memory_test SET memory_shared_quota 100; -- allocate serially
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN;
1: SELECT hold_memory_by_percent(0.39 / 0.52);
1q:
SELECT pg_sleep(1);
2: SELECT hold_memory_by_percent(0.39 / 0.52);
2q:
-- 5b) on QEs
-- not exceed the global share
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test;
1: BEGIN; 1: BEGIN;
1: SELECT hold_memory_by_percent(1,0.6); 2: BEGIN;
-- reserve all the group shared quota
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.39 / 0.52)=0;
-- must allocate from global share
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.2 / 0.52)=0;
1q:
2q:
-- exceed the global share
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test; 2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN; 2: BEGIN;
2: SELECT hold_memory_by_percent(1,0.3); 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.39 / 0.52)=0;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.39 / 0.52)=0;
1q:
2q: 2q:
-- allocate serially
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role1_memory_test; 2: SET ROLE TO role1_memory_test;
1: BEGIN;
2: BEGIN; 2: BEGIN;
2: SELECT hold_memory_by_percent(1,0.3); 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.39 / 0.52)=0;
2: SELECT hold_memory_by_percent(1,0.2); 1q:
SELECT pg_sleep(1);
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.39 / 0.52)=0;
2q: 2q:
DROP ROLE role1_memory_test;
DROP RESOURCE GROUP rg1_memory_test;
-- 6) multi allocation in different group
-- Group Share Quota > 0
-- Global Share Quota > 0
-- Slot Quota > 0
-- -----------------------
-- we assume system total chunks is 100%
-- rg1's expected: 100% * 20 / 100 => 20%
-- rg1's slot quota: 20% * 60 / 100 / 2 * 2 => 12%
-- rg1's single slot quota: 12% / 2 => 6%
-- rg1's shared quota: 20% - 6% * 2 => 8%
-- rg2 same as rg1
-- system free chunks: 100% - 10% - 30% - 100%*20/100 - 100%*20/100 => 20%
-- memory available to one slot in rg1/rg2: 6% + 8% + 20% => 34%
CREATE RESOURCE GROUP rg1_memory_test
WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=20, memory_shared_quota=40);
CREATE RESOURCE GROUP rg2_memory_test
WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=20, memory_shared_quota=40);
CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test;
CREATE ROLE role2_memory_test RESOURCE GROUP rg2_memory_test;
-- 6a) on QD
-- not exceed the global share
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role2_memory_test;
1: BEGIN;
2: BEGIN;
1: SELECT hold_memory_by_percent(0.2 / 0.2);
2: SELECT hold_memory_by_percent(0.2 / 0.2);
1q: 1q:
2q:
-- 8) QE: concurrent transactions in same group with memory_shared_quota = 100 -- exceed the global share
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role2_memory_test;
1: BEGIN;
2: BEGIN;
1: SELECT hold_memory_by_percent(0.3 / 0.2);
2: SELECT hold_memory_by_percent(0.3 / 0.2);
1q:
2q:
ALTER RESOURCE GROUP rg1_memory_test SET memory_shared_quota 100; -- allocate serially
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role2_memory_test;
1: BEGIN;
2: BEGIN;
1: SELECT hold_memory_by_percent(0.3 / 0.2);
1q:
SELECT pg_sleep(1);
2: SELECT hold_memory_by_percent(0.3 / 0.2);
2q:
-- 6b) on QEs
-- not exceed the global share
1: SET ROLE TO role1_memory_test; 1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role2_memory_test;
1: BEGIN; 1: BEGIN;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.6)=0;
2: SET ROLE TO role1_memory_test;
2: BEGIN; 2: BEGIN;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.3)=0; 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.2 / 0.2)=0;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.2 / 0.2)=0;
1q:
2q: 2q:
2: SET ROLE TO role1_memory_test;
-- exceed the global share
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role2_memory_test;
1: BEGIN;
2: BEGIN; 2: BEGIN;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.3)=0; 1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.3 / 0.2)=0;
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(t1.dbid,0.2)=0; 2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.3 / 0.2)=0;
1q:
2q: 2q:
-- allocate serially
1: SET ROLE TO role1_memory_test;
2: SET ROLE TO role2_memory_test;
1: BEGIN;
2: BEGIN;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.3 / 0.2)=0;
1q: 1q:
SELECT pg_sleep(1);
2: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.3 / 0.2)=0;
2q:
-- cleanup
DROP ROLE role1_memory_test; DROP ROLE role1_memory_test;
DROP ROLE role2_memory_test;
DROP RESOURCE GROUP rg1_memory_test; DROP RESOURCE GROUP rg1_memory_test;
DROP RESOURCE GROUP rg2_memory_test;
-- 7) DBA can increase global shared memory by decreasing
-- any existing group_memory_limit
-- -----------------------
-- we assume system total chunks is 100%
-- rg1's expected: 100% * 30 / 100 => 30%
-- rg1's slot quota: 30%
-- rg1's single slot quota: 30% / 2 => 15%
-- rg1's shared quota: 0
-- rg2 same as rg1
-- system free chunks: 100% - 10% - 30% - 30% - 30% => 0
-- memory available to one slot in rg1/rg2: 15% + 0 + 0 => 15%
CREATE RESOURCE GROUP rg1_memory_test
WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=30, memory_shared_quota=0);
CREATE RESOURCE GROUP rg2_memory_test
WITH (concurrency=2, cpu_rate_limit=10,
memory_limit=30, memory_shared_quota=0);
CREATE ROLE role1_memory_test RESOURCE GROUP rg1_memory_test;
CREATE ROLE role2_memory_test RESOURCE GROUP rg2_memory_test;
-- 7a) on QD
-- not enough memory
1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(0.2 / 0.3);
1q:
-- alter rg2 memory_limit so last query has enough memory
ALTER RESOURCE GROUP rg2_memory_test SET memory_limit 20;
-- system free chunks: 100% - 10% - 30% - 30% - 20% => 10%
-- memory available to one slot in rg1/rg2: 15% + 0 + 10% => 25%
-- enough memory for allocating
1: SET ROLE TO role1_memory_test;
1: SELECT hold_memory_by_percent(0.2 / 0.3);
1q:
-- 7b) on QEs
-- not enough memory
ALTER RESOURCE GROUP rg2_memory_test SET memory_limit 30;
1: SET ROLE TO role1_memory_test;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.2 / 0.3)=0;
1q:
-- alter rg2 memory_limit so last query has enough memory
ALTER RESOURCE GROUP rg2_memory_test SET memory_limit 20;
-- system free chunks: 100% - 10% - 30% - 30% - 20% => 10%
-- memory available to one slot in rg1/rg2: 15% + 0 + 10% => 25%
-- enough memory for allocating
1: SET ROLE TO role1_memory_test;
1: SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory_by_percent(0.2 / 0.3)=0;
1q:
DROP ROLE role1_memory_test;
DROP ROLE role2_memory_test;
DROP RESOURCE GROUP rg1_memory_test;
DROP RESOURCE GROUP rg2_memory_test;
...@@ -152,3 +152,4 @@ DROP ROLE role1_memory_test; ...@@ -152,3 +152,4 @@ DROP ROLE role1_memory_test;
DROP ROLE role2_memory_test; DROP ROLE role2_memory_test;
DROP RESOURCE GROUP rg1_memory_test; DROP RESOURCE GROUP rg1_memory_test;
DROP RESOURCE GROUP rg2_memory_test; DROP RESOURCE GROUP rg2_memory_test;
DROP VIEW memory_result;
...@@ -298,3 +298,5 @@ DROP RESOURCE GROUP rg1_memory_test; ...@@ -298,3 +298,5 @@ DROP RESOURCE GROUP rg1_memory_test;
DROP DROP
DROP RESOURCE GROUP rg2_memory_test; DROP RESOURCE GROUP rg2_memory_test;
DROP DROP
DROP VIEW memory_result;
DROP
...@@ -17,7 +17,7 @@ SELECT * FROM rg_spill_status; ...@@ -17,7 +17,7 @@ SELECT * FROM rg_spill_status;
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 20; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 20;
SELECT * FROM rg_spill_status; SELECT * FROM rg_spill_status;
-- positive, memory_spill_ratio range is [0, 100] -- positive, memory_spill_ratio range is [0, 2147483647]
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 0; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 0;
SELECT * FROM rg_spill_status; SELECT * FROM rg_spill_status;
...@@ -30,8 +30,8 @@ ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 20.0; ...@@ -30,8 +30,8 @@ ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 20.0;
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO a; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO a;
SELECT * FROM rg_spill_status; SELECT * FROM rg_spill_status;
-- negative: memory_spill_ratio is larger than RESGROUP_MAX_MEMORY_SPILL_RATIO -- negative: memory_spill_ratio is negative
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 101; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO -1;
SELECT * FROM rg_spill_status; SELECT * FROM rg_spill_status;
-- cleanup -- cleanup
......
...@@ -30,7 +30,7 @@ SHOW MEMORY_SPILL_RATIO; ...@@ -30,7 +30,7 @@ SHOW MEMORY_SPILL_RATIO;
SELECT 1; SELECT 1;
-- negative set to session level -- negative set to session level
SET MEMORY_SPILL_RATIO TO 101; SET MEMORY_SPILL_RATIO TO -1;
SHOW MEMORY_SPILL_RATIO; SHOW MEMORY_SPILL_RATIO;
SELECT 1; SELECT 1;
......
...@@ -95,7 +95,7 @@ CREATE RESOURCE GROUP rg_test_group WITH (concurrency=0, cpu_rate_limit=10, memo ...@@ -95,7 +95,7 @@ CREATE RESOURCE GROUP rg_test_group WITH (concurrency=0, cpu_rate_limit=10, memo
-- negative: concurrency should be zero for cgroup audited resource group -- negative: concurrency should be zero for cgroup audited resource group
CREATE RESOURCE GROUP rg_test_group WITH (concurrency=1, cpu_rate_limit=10, memory_limit=10, memory_auditor="cgroup"); CREATE RESOURCE GROUP rg_test_group WITH (concurrency=1, cpu_rate_limit=10, memory_limit=10, memory_auditor="cgroup");
-- memory_spill_ratio range is [0, 100] -- memory_spill_ratio range is [0, 2147483647]
-- no limit on the sum of memory_shared_quota and memory_spill_ratio -- no limit on the sum of memory_shared_quota and memory_spill_ratio
CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=10, memory_spill_ratio=0); CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=10, memory_spill_ratio=0);
DROP RESOURCE GROUP rg_test_group; DROP RESOURCE GROUP rg_test_group;
...@@ -136,7 +136,7 @@ DROP RESOURCE GROUP rg2_test_group; ...@@ -136,7 +136,7 @@ DROP RESOURCE GROUP rg2_test_group;
CREATE RESOURCE GROUP rg_test_group WITH (concurrency=0, cpu_rate_limit=10, memory_limit=10, memory_auditor="cgroup"); CREATE RESOURCE GROUP rg_test_group WITH (concurrency=0, cpu_rate_limit=10, memory_limit=10, memory_auditor="cgroup");
DROP RESOURCE GROUP rg_test_group; DROP RESOURCE GROUP rg_test_group;
-- memory_spill_ratio range is [0, 100] -- memory_spill_ratio range is [0, 2147483647]
-- no limit on the sum of memory_shared_quota and memory_spill_ratio -- no limit on the sum of memory_shared_quota and memory_spill_ratio
CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=0, memory_spill_ratio=1); CREATE RESOURCE GROUP rg_test_group WITH (cpu_rate_limit=10, memory_limit=10, memory_shared_quota=0, memory_spill_ratio=1);
DROP RESOURCE GROUP rg_test_group; DROP RESOURCE GROUP rg_test_group;
......
...@@ -19,10 +19,6 @@ CREATE RESOURCE GROUP rg_spill_test WITH ...@@ -19,10 +19,6 @@ CREATE RESOURCE GROUP rg_spill_test WITH
(concurrency=10, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50, memory_spill_ratio=-1); (concurrency=10, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50, memory_spill_ratio=-1);
DROP RESOURCE GROUP rg_spill_test; DROP RESOURCE GROUP rg_spill_test;
CREATE RESOURCE GROUP rg_spill_test WITH
(concurrency=10, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50, memory_spill_ratio=101);
DROP RESOURCE GROUP rg_spill_test;
-- alter -- alter
CREATE RESOURCE GROUP rg_spill_test WITH CREATE RESOURCE GROUP rg_spill_test WITH
(concurrency=10, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50, memory_spill_ratio=20); (concurrency=10, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50, memory_spill_ratio=20);
...@@ -31,7 +27,7 @@ ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 60; ...@@ -31,7 +27,7 @@ ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 60;
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 0; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 0;
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 100; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 100;
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO -1; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO -1;
ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 101; ALTER RESOURCE GROUP rg_spill_test SET MEMORY_SPILL_RATIO 10000;
DROP RESOURCE GROUP rg_spill_test; DROP RESOURCE GROUP rg_spill_test;
...@@ -55,7 +51,7 @@ SET MEMORY_SPILL_RATIO TO -1; ...@@ -55,7 +51,7 @@ SET MEMORY_SPILL_RATIO TO -1;
SHOW MEMORY_SPILL_RATIO; SHOW MEMORY_SPILL_RATIO;
SELECT 1; SELECT 1;
SET MEMORY_SPILL_RATIO TO 101; SET MEMORY_SPILL_RATIO TO 10000;
SHOW MEMORY_SPILL_RATIO; SHOW MEMORY_SPILL_RATIO;
SELECT 1; SELECT 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册