From 2c509b712a577a64291ede8f6af229fc2223d550 Mon Sep 17 00:00:00 2001 From: Gokhan Gulbiz Date: Sun, 11 Jun 2023 12:17:31 +0300 Subject: [PATCH] Tenant monitoring performance improvements (#6868) - [x] Use spinlock instead of lwlock per tenant [b437aa9](https://github.com/citusdata/citus/pull/6868/commits/b437aa9e52ea312df58d3bb5c0d324afb29c2a71) - [x] Use hashtable to store tenant stats [ccd464b](https://github.com/citusdata/citus/pull/6868/commits/ccd464ba0483de4a2af162c22609125c913ac93b) - [x] Introduce a new GUC for specifying the sampling rate of new tenant entries in the tenant monitor. [a8d3805](https://github.com/citusdata/citus/pull/6868/commits/a8d3805bd6b9ee9fc27906d8bed7287a00b45565) Below are the pgbench metrics with select-only workloads from my local machine. Here is the [script](https://gist.github.com/gokhangulbiz/7a2308470597dc06734ff7c08f87c656) I used for benchmarking. | | Connection Count | Initial Implementation (TPS) | On/Off Diff | Final Implementation -Run#1 (TPS) | On/Off Diff | Final Implementation -Run#2 (TPS) | On/Off Diff | Final Implementation -Run#3 (TPS) | On/Off Diff | Avg On/Off Diff | | --- | ---------------- | ---------------------------- | ----------- | ---------------------------------- | ----------- | ---------------------------------- | ----------- | ---------------------------------- | ----------- | --------------- | | On | 32 | 37488.69839 | \-17% | 42859.94402 | \-5% | 43379.63121 | \-2% | 42636.2264 | \-7% | \-5% | | Off | 32 | 43909.83121 | | 45139.63151 | | 44188.77425 | | 45451.9548 | | | | On | 300 | 30463.03538 | \-15% | 33265.19957 | \-7% | 34685.87233 | \-2% | 34682.5214 | \-1% | \-3% | | Off | 300 | 35105.73594 | | 35637.45423 | | 35331.33447 | | 35113.3214 | | | --- .../distributed/operations/shard_rebalancer.c | 2 +- src/backend/distributed/shared_library_init.c | 12 +- .../distributed/utils/citus_stat_tenants.c | 228 ++++++++++++------ .../distributed/utils/citus_stat_tenants.h | 32 ++- .../regress/expected/citus_stat_tenants.out | 30 ++- src/test/regress/sql/citus_stat_tenants.sql | 8 +- 6 files changed, 207 insertions(+), 105 deletions(-) diff --git a/src/backend/distributed/operations/shard_rebalancer.c b/src/backend/distributed/operations/shard_rebalancer.c index bc5b0af74..5750b9e8d 100644 --- a/src/backend/distributed/operations/shard_rebalancer.c +++ b/src/backend/distributed/operations/shard_rebalancer.c @@ -2017,7 +2017,7 @@ GenerateTaskMoveDependencyList(PlacementUpdateEvent *move, int64 colocationId, * overlaps with the current move's target node. * The earlier/first move might make space for the later/second move. * So we could run out of disk space (or at least overload the node) - * if we move the second shard to it before the first one is moved away.  + * if we move the second shard to it before the first one is moved away. */ ShardMoveSourceNodeHashEntry *shardMoveSourceNodeHashEntry = hash_search( shardMoveDependencies.nodeDependencies, &move->targetNode->nodeId, HASH_FIND, diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 8f6485c25..0ed4c17c6 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -2416,7 +2416,6 @@ RegisterCitusConfigVariables(void) PGC_POSTMASTER, GUC_STANDARD, NULL, NULL, NULL); - DefineCustomEnumVariable( "citus.stat_tenants_log_level", gettext_noop("Sets the level of citus_stat_tenants log messages"), @@ -2438,6 +2437,17 @@ RegisterCitusConfigVariables(void) GUC_STANDARD, NULL, NULL, NULL); + + DefineCustomIntVariable( + "citus.stat_tenants_sample_rate_for_new_tenants", + gettext_noop("Sampling rate for new tenants in citus_stat_tenants."), + NULL, + &StatTenantsSampleRateForNewTenants, + 100, 1, 100, + PGC_USERSET, + GUC_STANDARD, + NULL, NULL, NULL); + DefineCustomEnumVariable( "citus.stat_tenants_track", gettext_noop("Enables/Disables the stats collection for citus_stat_tenants."), diff --git a/src/backend/distributed/utils/citus_stat_tenants.c b/src/backend/distributed/utils/citus_stat_tenants.c index 0d2d0754d..68ec3dfa4 100644 --- a/src/backend/distributed/utils/citus_stat_tenants.c +++ b/src/backend/distributed/utils/citus_stat_tenants.c @@ -11,6 +11,7 @@ #include "postgres.h" #include "unistd.h" +#include "access/hash.h" #include "distributed/citus_safe_lib.h" #include "distributed/colocation_utils.h" #include "distributed/distributed_planner.h" @@ -50,7 +51,6 @@ static clock_t QueryEndClock = { 0 }; static const char *SharedMemoryNameForMultiTenantMonitor = "Shared memory for multi tenant monitor"; -static char *TenantTrancheName = "Tenant Tranche"; static char *MonitorTrancheName = "Multi Tenant Monitor Tranche"; static shmem_startup_hook_type prev_shmem_startup_hook = NULL; @@ -60,12 +60,14 @@ static void UpdatePeriodsIfNecessary(TenantStats *tenantStats, TimestampTz query static void ReduceScoreIfNecessary(TenantStats *tenantStats, TimestampTz queryTime); static void EvictTenantsIfNecessary(TimestampTz queryTime); static void RecordTenantStats(TenantStats *tenantStats, TimestampTz queryTime); -static void CreateMultiTenantMonitor(void); static MultiTenantMonitor * CreateSharedMemoryForMultiTenantMonitor(void); static MultiTenantMonitor * GetMultiTenantMonitor(void); static void MultiTenantMonitorSMInit(void); -static int CreateTenantStats(MultiTenantMonitor *monitor, TimestampTz queryTime); -static int FindTenantStats(MultiTenantMonitor *monitor); +static TenantStats * CreateTenantStats(MultiTenantMonitor *monitor, TimestampTz + queryTime); +static void FillTenantStatsHashKey(TenantStatsHashKey *key, char *tenantAttribute, uint32 + colocationGroupId); +static TenantStats * FindTenantStats(MultiTenantMonitor *monitor); static size_t MultiTenantMonitorshmemSize(void); static char * ExtractTopComment(const char *inputString); static char * EscapeCommentChars(const char *str); @@ -75,7 +77,7 @@ int StatTenantsLogLevel = CITUS_LOG_LEVEL_OFF; int StatTenantsPeriod = (time_t) 60; int StatTenantsLimit = 100; int StatTenantsTrack = STAT_TENANTS_TRACK_NONE; - +int StatTenantsSampleRateForNewTenants = 100; PG_FUNCTION_INFO_V1(citus_stat_tenants_local); PG_FUNCTION_INFO_V1(citus_stat_tenants_local_reset); @@ -113,21 +115,36 @@ citus_stat_tenants_local(PG_FUNCTION_ARGS) LWLockAcquire(&monitor->lock, LW_EXCLUSIVE); int numberOfRowsToReturn = 0; + int tenantStatsCount = hash_get_num_entries(monitor->tenants); if (returnAllTenants) { - numberOfRowsToReturn = monitor->tenantCount; + numberOfRowsToReturn = tenantStatsCount; } else { - numberOfRowsToReturn = Min(monitor->tenantCount, StatTenantsLimit); + numberOfRowsToReturn = Min(tenantStatsCount, + StatTenantsLimit); } - for (int tenantIndex = 0; tenantIndex < monitor->tenantCount; tenantIndex++) + /* Allocate an array to hold the tenants. */ + TenantStats **stats = palloc(tenantStatsCount * + sizeof(TenantStats *)); + + HASH_SEQ_STATUS hash_seq; + TenantStats *stat; + + /* Get all the tenants from the hash table. */ + int j = 0; + hash_seq_init(&hash_seq, monitor->tenants); + while ((stat = hash_seq_search(&hash_seq)) != NULL) { - UpdatePeriodsIfNecessary(&monitor->tenants[tenantIndex], monitoringTime); - ReduceScoreIfNecessary(&monitor->tenants[tenantIndex], monitoringTime); + stats[j++] = stat; + UpdatePeriodsIfNecessary(stat, monitoringTime); + ReduceScoreIfNecessary(stat, monitoringTime); } - SafeQsort(monitor->tenants, monitor->tenantCount, sizeof(TenantStats), + + /* Sort the tenants by their score. */ + SafeQsort(stats, j, sizeof(TenantStats *), CompareTenantScore); for (int i = 0; i < numberOfRowsToReturn; i++) @@ -135,10 +152,10 @@ citus_stat_tenants_local(PG_FUNCTION_ARGS) memset(values, 0, sizeof(values)); memset(isNulls, false, sizeof(isNulls)); - TenantStats *tenantStats = &monitor->tenants[i]; + TenantStats *tenantStats = stats[i]; - values[0] = Int32GetDatum(tenantStats->colocationGroupId); - values[1] = PointerGetDatum(cstring_to_text(tenantStats->tenantAttribute)); + values[0] = Int32GetDatum(tenantStats->key.colocationGroupId); + values[1] = PointerGetDatum(cstring_to_text(tenantStats->key.tenantAttribute)); values[2] = Int32GetDatum(tenantStats->readsInThisPeriod); values[3] = Int32GetDatum(tenantStats->readsInLastPeriod); values[4] = Int32GetDatum(tenantStats->readsInThisPeriod + @@ -152,6 +169,8 @@ citus_stat_tenants_local(PG_FUNCTION_ARGS) tuplestore_putvalues(tupleStore, tupleDescriptor, values, isNulls); } + pfree(stats); + LWLockRelease(&monitor->lock); PG_RETURN_VOID(); @@ -166,7 +185,25 @@ Datum citus_stat_tenants_local_reset(PG_FUNCTION_ARGS) { MultiTenantMonitor *monitor = GetMultiTenantMonitor(); - monitor->tenantCount = 0; + + /* if monitor is not created yet, there is nothing to reset */ + if (monitor == NULL) + { + PG_RETURN_VOID(); + } + + HASH_SEQ_STATUS hash_seq; + TenantStats *stats; + + LWLockAcquire(&monitor->lock, LW_EXCLUSIVE); + + hash_seq_init(&hash_seq, monitor->tenants); + while ((stats = hash_seq_search(&hash_seq)) != NULL) + { + hash_search(monitor->tenants, &stats->key, HASH_REMOVE, NULL); + } + + LWLockRelease(&monitor->lock); PG_RETURN_VOID(); } @@ -226,6 +263,24 @@ AttributeTask(char *tenantId, int colocationId, CmdType commandType) return; } + TenantStatsHashKey key = { 0 }; + FillTenantStatsHashKey(&key, tenantId, colocationId); + + MultiTenantMonitor *monitor = GetMultiTenantMonitor(); + bool found = false; + hash_search(monitor->tenants, &key, HASH_FIND, &found); + + /* If the tenant is not found in the hash table, we will track the query with a probability of StatTenantsSampleRateForNewTenants. */ + if (!found) + { + int randomValue = rand() % 100; + bool shouldTrackQuery = randomValue < StatTenantsSampleRateForNewTenants; + if (!shouldTrackQuery) + { + return; + } + } + AttributeToColocationGroupId = colocationId; strncpy_s(AttributeToTenant, MAX_TENANT_ATTRIBUTE_LENGTH, tenantId, MAX_TENANT_ATTRIBUTE_LENGTH - 1); @@ -295,14 +350,14 @@ CitusAttributeToEnd(QueryDesc *queryDesc) static int CompareTenantScore(const void *leftElement, const void *rightElement) { - const TenantStats *leftTenant = (const TenantStats *) leftElement; - const TenantStats *rightTenant = (const TenantStats *) rightElement; + double l_usage = (*(TenantStats *const *) leftElement)->score; + double r_usage = (*(TenantStats *const *) rightElement)->score; - if (leftTenant->score > rightTenant->score) + if (l_usage > r_usage) { return -1; } - else if (leftTenant->score < rightTenant->score) + else if (l_usage < r_usage) { return 1; } @@ -353,45 +408,43 @@ AttributeMetricsIfApplicable() */ LWLockAcquire(&monitor->lock, LW_SHARED); - int currentTenantIndex = FindTenantStats(monitor); + TenantStats *tenantStats = FindTenantStats(monitor); - if (currentTenantIndex != -1) + if (tenantStats != NULL) { - TenantStats *tenantStats = &monitor->tenants[currentTenantIndex]; - LWLockAcquire(&tenantStats->lock, LW_EXCLUSIVE); + SpinLockAcquire(&tenantStats->lock); UpdatePeriodsIfNecessary(tenantStats, queryTime); ReduceScoreIfNecessary(tenantStats, queryTime); RecordTenantStats(tenantStats, queryTime); - LWLockRelease(&tenantStats->lock); + SpinLockRelease(&tenantStats->lock); } else { LWLockRelease(&monitor->lock); LWLockAcquire(&monitor->lock, LW_EXCLUSIVE); - currentTenantIndex = FindTenantStats(monitor); + tenantStats = FindTenantStats(monitor); - if (currentTenantIndex == -1) + if (tenantStats == NULL) { - currentTenantIndex = CreateTenantStats(monitor, queryTime); + tenantStats = CreateTenantStats(monitor, queryTime); } LWLockRelease(&monitor->lock); LWLockAcquire(&monitor->lock, LW_SHARED); - currentTenantIndex = FindTenantStats(monitor); - if (currentTenantIndex != -1) + tenantStats = FindTenantStats(monitor); + if (tenantStats != NULL) { - TenantStats *tenantStats = &monitor->tenants[currentTenantIndex]; - LWLockAcquire(&tenantStats->lock, LW_EXCLUSIVE); + SpinLockAcquire(&tenantStats->lock); UpdatePeriodsIfNecessary(tenantStats, queryTime); ReduceScoreIfNecessary(tenantStats, queryTime); RecordTenantStats(tenantStats, queryTime); - LWLockRelease(&tenantStats->lock); + SpinLockRelease(&tenantStats->lock); } } LWLockRelease(&monitor->lock); @@ -507,15 +560,29 @@ EvictTenantsIfNecessary(TimestampTz queryTime) * * Every time tenant count hits StatTenantsLimit * 3, we reduce it back to StatTenantsLimit * 2. */ - if (monitor->tenantCount >= StatTenantsLimit * 3) + long tenantStatsCount = hash_get_num_entries(monitor->tenants); + if (tenantStatsCount >= StatTenantsLimit * 3) { - for (int tenantIndex = 0; tenantIndex < monitor->tenantCount; tenantIndex++) + HASH_SEQ_STATUS hash_seq; + TenantStats *stat; + TenantStats **stats = palloc(tenantStatsCount * + sizeof(TenantStats *)); + + int i = 0; + hash_seq_init(&hash_seq, monitor->tenants); + while ((stat = hash_seq_search(&hash_seq)) != NULL) { - ReduceScoreIfNecessary(&monitor->tenants[tenantIndex], queryTime); + stats[i++] = stat; } - SafeQsort(monitor->tenants, monitor->tenantCount, sizeof(TenantStats), - CompareTenantScore); - monitor->tenantCount = StatTenantsLimit * 2; + + SafeQsort(stats, i, sizeof(TenantStats *), CompareTenantScore); + + for (i = StatTenantsLimit * 2; i < tenantStatsCount; i++) + { + hash_search(monitor->tenants, &stats[i]->key, HASH_REMOVE, NULL); + } + + pfree(stats); } } @@ -553,17 +620,6 @@ RecordTenantStats(TenantStats *tenantStats, TimestampTz queryTime) } -/* - * CreateMultiTenantMonitor creates the data structure for multi tenant monitor. - */ -static void -CreateMultiTenantMonitor() -{ - MultiTenantMonitor *monitor = CreateSharedMemoryForMultiTenantMonitor(); - monitor->tenantCount = 0; -} - - /* * CreateSharedMemoryForMultiTenantMonitor creates a dynamic shared memory segment for multi tenant monitor. */ @@ -586,6 +642,17 @@ CreateSharedMemoryForMultiTenantMonitor() monitor->namedLockTranche.trancheName); LWLockInitialize(&monitor->lock, monitor->namedLockTranche.trancheId); + HASHCTL info; + + memset(&info, 0, sizeof(info)); + info.keysize = sizeof(TenantStatsHashKey); + info.entrysize = sizeof(TenantStats); + + monitor->tenants = ShmemInitHash("citus_stats_tenants hash", + StatTenantsLimit * 3, StatTenantsLimit * 3, + &info, HASH_ELEM | + HASH_SHARED_MEM | HASH_BLOBS); + return monitor; } @@ -629,7 +696,7 @@ InitializeMultiTenantMonitorSMHandleManagement() static void MultiTenantMonitorSMInit() { - CreateMultiTenantMonitor(); + CreateSharedMemoryForMultiTenantMonitor(); if (prev_shmem_startup_hook != NULL) { @@ -643,7 +710,7 @@ MultiTenantMonitorSMInit() * * Calling this function should be protected by the monitor->lock in LW_EXCLUSIVE mode. */ -static int +static TenantStats * CreateTenantStats(MultiTenantMonitor *monitor, TimestampTz queryTime) { /* @@ -652,45 +719,50 @@ CreateTenantStats(MultiTenantMonitor *monitor, TimestampTz queryTime) */ EvictTenantsIfNecessary(queryTime); - int tenantIndex = monitor->tenantCount; + TenantStatsHashKey key = { 0 }; + FillTenantStatsHashKey(&key, AttributeToTenant, AttributeToColocationGroupId); - memset(&monitor->tenants[tenantIndex], 0, sizeof(monitor->tenants[tenantIndex])); + TenantStats *stats = (TenantStats *) hash_search(monitor->tenants, &key, + HASH_ENTER, NULL); - strcpy_s(monitor->tenants[tenantIndex].tenantAttribute, - sizeof(monitor->tenants[tenantIndex].tenantAttribute), AttributeToTenant); - monitor->tenants[tenantIndex].colocationGroupId = AttributeToColocationGroupId; + stats->writesInLastPeriod = 0; + stats->writesInThisPeriod = 0; + stats->readsInLastPeriod = 0; + stats->readsInThisPeriod = 0; + stats->cpuUsageInLastPeriod = 0; + stats->cpuUsageInThisPeriod = 0; + stats->score = 0; + stats->lastScoreReduction = 0; - monitor->tenants[tenantIndex].namedLockTranche.trancheId = LWLockNewTrancheId(); - monitor->tenants[tenantIndex].namedLockTranche.trancheName = TenantTrancheName; + SpinLockInit(&stats->lock); - LWLockRegisterTranche(monitor->tenants[tenantIndex].namedLockTranche.trancheId, - monitor->tenants[tenantIndex].namedLockTranche.trancheName); - LWLockInitialize(&monitor->tenants[tenantIndex].lock, - monitor->tenants[tenantIndex].namedLockTranche.trancheId); - - monitor->tenantCount++; - - return tenantIndex; + return stats; } /* - * FindTenantStats finds the index for the current tenant's statistics. + * FindTenantStats finds the current tenant's statistics. */ -static int +static TenantStats * FindTenantStats(MultiTenantMonitor *monitor) { - for (int i = 0; i < monitor->tenantCount; i++) - { - TenantStats *tenantStats = &monitor->tenants[i]; - if (strcmp(tenantStats->tenantAttribute, AttributeToTenant) == 0 && - tenantStats->colocationGroupId == AttributeToColocationGroupId) - { - return i; - } - } + TenantStatsHashKey key = { 0 }; + FillTenantStatsHashKey(&key, AttributeToTenant, AttributeToColocationGroupId); - return -1; + TenantStats *stats = (TenantStats *) hash_search(monitor->tenants, &key, + HASH_FIND, NULL); + + return stats; +} + + +static void +FillTenantStatsHashKey(TenantStatsHashKey *key, char *tenantAttribute, uint32 + colocationGroupId) +{ + memset(key->tenantAttribute, 0, MAX_TENANT_ATTRIBUTE_LENGTH); + strlcpy(key->tenantAttribute, tenantAttribute, MAX_TENANT_ATTRIBUTE_LENGTH); + key->colocationGroupId = colocationGroupId; } diff --git a/src/include/distributed/utils/citus_stat_tenants.h b/src/include/distributed/utils/citus_stat_tenants.h index aa413c29d..8dac393a8 100644 --- a/src/include/distributed/utils/citus_stat_tenants.h +++ b/src/include/distributed/utils/citus_stat_tenants.h @@ -11,24 +11,33 @@ #ifndef CITUS_ATTRIBUTE_H #define CITUS_ATTRIBUTE_H +#include "distributed/hash_helpers.h" #include "executor/execdesc.h" #include "executor/executor.h" #include "storage/lwlock.h" #include "utils/datetime.h" +#include "utils/hsearch.h" #define MAX_TENANT_ATTRIBUTE_LENGTH 100 +/* + * Hashtable key that defines the identity of a hashtable entry. + * The key is the attribute value, e.g distribution column and the colocation group id of the tenant. + */ +typedef struct TenantStatsHashKey +{ + char tenantAttribute[MAX_TENANT_ATTRIBUTE_LENGTH]; + int colocationGroupId; +} TenantStatsHashKey; +assert_valid_hash_key2(TenantStatsHashKey, tenantAttribute, colocationGroupId); + /* * TenantStats is the struct that keeps statistics about one tenant. */ typedef struct TenantStats { - /* - * The attribute value, e.g distribution column, and colocation group id - * of the tenant. - */ - char tenantAttribute[MAX_TENANT_ATTRIBUTE_LENGTH]; - int colocationGroupId; + TenantStatsHashKey key; /* hash key of entry - MUST BE FIRST */ + /* * Number of SELECT queries this tenant ran in this and last periods. @@ -70,8 +79,7 @@ typedef struct TenantStats /* * Locks needed to update this tenant's statistics. */ - NamedLWLockTranche namedLockTranche; - LWLock lock; + slock_t lock; } TenantStats; /* @@ -89,12 +97,9 @@ typedef struct MultiTenantMonitor LWLock lock; /* - * tenantCount is the number of items in the tenants array. - * The total length of tenants array is set up at CreateSharedMemoryForMultiTenantMonitor - * and is 3 * citus.stat_tenants_limit + * The max length of tenants hashtable is 3 * citus.stat_tenants_limit */ - int tenantCount; - TenantStats tenants[FLEXIBLE_ARRAY_MEMBER]; + HTAB *tenants; } MultiTenantMonitor; typedef enum @@ -116,5 +121,6 @@ extern int StatTenantsLogLevel; extern int StatTenantsPeriod; extern int StatTenantsLimit; extern int StatTenantsTrack; +extern int StatTenantsSampleRateForNewTenants; #endif /*CITUS_ATTRIBUTE_H */ diff --git a/src/test/regress/expected/citus_stat_tenants.out b/src/test/regress/expected/citus_stat_tenants.out index 102f5e9a3..3b3c728f8 100644 --- a/src/test/regress/expected/citus_stat_tenants.out +++ b/src/test/regress/expected/citus_stat_tenants.out @@ -137,6 +137,18 @@ SELECT count(*)>=0 FROM dist_tbl WHERE a = 2; t (1 row) +SELECT count(*)>=0 FROM dist_tbl WHERE a = 2; + ?column? +--------------------------------------------------------------------- + t +(1 row) + +SELECT count(*)>=0 FROM dist_tbl WHERE a = 3; + ?column? +--------------------------------------------------------------------- + t +(1 row) + SELECT count(*)>=0 FROM dist_tbl WHERE a = 3; ?column? --------------------------------------------------------------------- @@ -158,8 +170,8 @@ SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'abcd'; SELECT tenant_attribute, query_count_in_this_period, score FROM citus_stat_tenants(true) WHERE nodeid = :worker_2_nodeid ORDER BY score DESC, tenant_attribute; tenant_attribute | query_count_in_this_period | score --------------------------------------------------------------------- - 2 | 1 | 1000000000 - 3 | 1 | 1000000000 + 2 | 2 | 2000000000 + 3 | 2 | 2000000000 4 | 1 | 1000000000 abcd | 1 | 1000000000 (4 rows) @@ -192,8 +204,8 @@ SELECT tenant_attribute, query_count_in_this_period, score FROM citus_stat_tenan tenant_attribute | query_count_in_this_period | score --------------------------------------------------------------------- abcd | 3 | 3000000000 - 2 | 1 | 1000000000 - 3 | 1 | 1000000000 + 2 | 2 | 2000000000 + 3 | 2 | 2000000000 4 | 1 | 1000000000 bcde | 1 | 1000000000 cdef | 1 | 1000000000 @@ -222,8 +234,8 @@ SELECT tenant_attribute, query_count_in_this_period, score FROM citus_stat_tenan --------------------------------------------------------------------- abcd | 3 | 3000000000 bcde | 3 | 3000000000 - 2 | 1 | 1000000000 - 3 | 1 | 1000000000 + 2 | 2 | 2000000000 + 3 | 2 | 2000000000 defg | 1 | 1000000000 (5 rows) @@ -789,7 +801,7 @@ SELECT select_from_dist_tbl_text(U&'\0061\0308bc'); t (1 row) -SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; +SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants ORDER BY tenant_attribute; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- /b*c/de | 2 @@ -815,7 +827,7 @@ CALL citus_stat_tenants.select_from_dist_tbl_text_proc(U&'\0061\0308bc'); CALL citus_stat_tenants.select_from_dist_tbl_text_proc(U&'\0061\0308bc'); CALL citus_stat_tenants.select_from_dist_tbl_text_proc(U&'\0061\0308bc'); CALL citus_stat_tenants.select_from_dist_tbl_text_proc(NULL); -SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; +SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants ORDER BY tenant_attribute; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- /b*c/de | 8 @@ -862,7 +874,7 @@ SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = U&'\0061\0308bc t (1 row) -SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; +SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants ORDER BY tenant_attribute; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- /b*c/de | 11 diff --git a/src/test/regress/sql/citus_stat_tenants.sql b/src/test/regress/sql/citus_stat_tenants.sql index 61d9f19b3..efe77ec84 100644 --- a/src/test/regress/sql/citus_stat_tenants.sql +++ b/src/test/regress/sql/citus_stat_tenants.sql @@ -61,6 +61,8 @@ SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants(true SELECT nodeid AS worker_2_nodeid FROM pg_dist_node WHERE nodeport = :worker_2_port \gset SELECT count(*)>=0 FROM dist_tbl WHERE a = 2; +SELECT count(*)>=0 FROM dist_tbl WHERE a = 2; +SELECT count(*)>=0 FROM dist_tbl WHERE a = 3; SELECT count(*)>=0 FROM dist_tbl WHERE a = 3; SELECT count(*)>=0 FROM dist_tbl WHERE a = 4; SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'abcd'; @@ -272,7 +274,7 @@ SELECT select_from_dist_tbl_text('/b*c/de'); SELECT select_from_dist_tbl_text(U&'\0061\0308bc'); SELECT select_from_dist_tbl_text(U&'\0061\0308bc'); -SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; +SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants ORDER BY tenant_attribute; CREATE OR REPLACE PROCEDURE select_from_dist_tbl_text_proc( p_keyword text @@ -295,7 +297,7 @@ CALL citus_stat_tenants.select_from_dist_tbl_text_proc(U&'\0061\0308bc'); CALL citus_stat_tenants.select_from_dist_tbl_text_proc(U&'\0061\0308bc'); CALL citus_stat_tenants.select_from_dist_tbl_text_proc(NULL); -SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; +SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants ORDER BY tenant_attribute; CREATE OR REPLACE VIEW select_from_dist_tbl_text_view @@ -309,7 +311,7 @@ SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = U&'\0061\0308bc SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = U&'\0061\0308bc'; SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = U&'\0061\0308bc'; -SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; +SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants ORDER BY tenant_attribute; SET client_min_messages TO ERROR; DROP SCHEMA citus_stat_tenants CASCADE;