CREATE SCHEMA citus_stat_tenants; SET search_path TO citus_stat_tenants; SET citus.next_shard_id TO 5797500; SET citus.shard_replication_factor TO 1; -- make sure that we are tracking the tenant stats SELECT result FROM run_command_on_all_nodes('SHOW citus.stat_tenants_track'); result --------------------------------------------------------------------- all all all (3 rows) CREATE OR REPLACE FUNCTION pg_catalog.sleep_until_next_period() RETURNS VOID LANGUAGE C AS 'citus', $$sleep_until_next_period$$; SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) -- set period to upper limit to prevent stats from being reset SELECT result FROM run_command_on_all_nodes('ALTER SYSTEM SET citus.stat_tenants_period TO 86400'); result --------------------------------------------------------------------- ALTER SYSTEM ALTER SYSTEM ALTER SYSTEM (3 rows) SELECT result FROM run_command_on_all_nodes('SELECT pg_reload_conf()'); result --------------------------------------------------------------------- t t t (3 rows) CREATE TABLE dist_tbl (a INT, b TEXT); SELECT create_distributed_table('dist_tbl', 'a', shard_count:=4, colocate_with:='none'); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE TABLE dist_tbl_2 (a INT, b INT); SELECT create_distributed_table('dist_tbl_2', 'a', colocate_with:='dist_tbl'); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE TABLE dist_tbl_text (a TEXT, b INT); SELECT create_distributed_table('dist_tbl_text', 'a', shard_count:=4, colocate_with:='none'); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE TABLE ref_tbl (a INT, b INT); SELECT create_reference_table('ref_tbl'); create_reference_table --------------------------------------------------------------------- (1 row) INSERT INTO dist_tbl VALUES (1, 'abcd'); INSERT INTO dist_tbl VALUES (2, 'abcd'); UPDATE dist_tbl SET b = a + 1 WHERE a = 3; UPDATE dist_tbl SET b = a + 1 WHERE a = 4; DELETE FROM dist_tbl WHERE a = 5; SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period, (cpu_usage_in_this_period>0) AS cpu_is_used_in_this_period, (cpu_usage_in_last_period>0) AS cpu_is_used_in_last_period FROM citus_stat_tenants(true) ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period | cpu_is_used_in_this_period | cpu_is_used_in_last_period --------------------------------------------------------------------- 1 | 0 | 0 | 1 | 0 | t | f 2 | 0 | 0 | 1 | 0 | t | f 3 | 0 | 0 | 1 | 0 | t | f 4 | 0 | 0 | 1 | 0 | t | f 5 | 0 | 0 | 1 | 0 | t | f (5 rows) SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) -- queries with multiple tenants should not be counted SELECT count(*)>=0 FROM dist_tbl WHERE a IN (1, 5); ?column? --------------------------------------------------------------------- t (1 row) -- queries with reference tables should not be counted SELECT count(*)>=0 FROM ref_tbl WHERE a = 1; ?column? --------------------------------------------------------------------- t (1 row) SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants(true) ORDER BY tenant_attribute; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- (0 rows) -- queries with multiple tables but one tenant should be counted SELECT count(*)>=0 FROM dist_tbl, dist_tbl_2 WHERE dist_tbl.a = 1 AND dist_tbl_2.a = 1; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl JOIN dist_tbl_2 ON dist_tbl.a = dist_tbl_2.a WHERE dist_tbl.a = 1; ?column? --------------------------------------------------------------------- t (1 row) SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants(true) WHERE tenant_attribute = '1'; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- 1 | 2 (1 row) -- test scoring -- all of these distribution column values are from second worker 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; ?column? --------------------------------------------------------------------- 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? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl WHERE a = 4; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'abcd'; ?column? --------------------------------------------------------------------- t (1 row) 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 | 2 | 2000000000 3 | 2 | 2000000000 4 | 1 | 1000000000 abcd | 1 | 1000000000 (4 rows) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'abcd'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'abcd'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'bcde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'cdef'; ?column? --------------------------------------------------------------------- t (1 row) 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 --------------------------------------------------------------------- abcd | 3 | 3000000000 2 | 2 | 2000000000 3 | 2 | 2000000000 4 | 1 | 1000000000 bcde | 1 | 1000000000 cdef | 1 | 1000000000 (6 rows) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'bcde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'bcde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'defg'; ?column? --------------------------------------------------------------------- t (1 row) 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 --------------------------------------------------------------------- abcd | 3 | 3000000000 bcde | 3 | 3000000000 2 | 2 | 2000000000 3 | 2 | 2000000000 defg | 1 | 1000000000 (5 rows) -- test period passing \c - - - :worker_1_port SET search_path TO citus_stat_tenants; SET citus.stat_tenants_period TO 2; SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) SELECT sleep_until_next_period(); sleep_until_next_period --------------------------------------------------------------------- (1 row) SELECT count(*)>=0 FROM dist_tbl WHERE a = 1; ?column? --------------------------------------------------------------------- t (1 row) INSERT INTO dist_tbl VALUES (5, 'abcd'); SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period, (cpu_usage_in_this_period>0) AS cpu_is_used_in_this_period, (cpu_usage_in_last_period>0) AS cpu_is_used_in_last_period FROM citus_stat_tenants_local ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period | cpu_is_used_in_this_period | cpu_is_used_in_last_period --------------------------------------------------------------------- 1 | 1 | 0 | 1 | 0 | t | f 5 | 0 | 0 | 1 | 0 | t | f (2 rows) -- simulate passing the period SELECT sleep_until_next_period(); sleep_until_next_period --------------------------------------------------------------------- (1 row) SELECT pg_sleep(1); pg_sleep --------------------------------------------------------------------- (1 row) SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period, (cpu_usage_in_this_period>0) AS cpu_is_used_in_this_period, (cpu_usage_in_last_period>0) AS cpu_is_used_in_last_period FROM citus_stat_tenants_local ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period | cpu_is_used_in_this_period | cpu_is_used_in_last_period --------------------------------------------------------------------- 1 | 0 | 1 | 0 | 1 | f | t 5 | 0 | 0 | 0 | 1 | f | t (2 rows) SELECT sleep_until_next_period(); sleep_until_next_period --------------------------------------------------------------------- (1 row) SELECT pg_sleep(1); pg_sleep --------------------------------------------------------------------- (1 row) SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period, (cpu_usage_in_this_period>0) AS cpu_is_used_in_this_period, (cpu_usage_in_last_period>0) AS cpu_is_used_in_last_period FROM citus_stat_tenants_local ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period | cpu_is_used_in_this_period | cpu_is_used_in_last_period --------------------------------------------------------------------- 1 | 0 | 0 | 0 | 0 | f | f 5 | 0 | 0 | 0 | 0 | f | f (2 rows) \c - - - :master_port SET search_path TO citus_stat_tenants; -- test logs SET client_min_messages TO LOG; SELECT count(*)>=0 FROM citus_stat_tenants; ?column? --------------------------------------------------------------------- t (1 row) SET citus.stat_tenants_log_level TO ERROR; SELECT count(*)>=0 FROM citus_stat_tenants; ?column? --------------------------------------------------------------------- t (1 row) SET citus.stat_tenants_log_level TO OFF; SELECT count(*)>=0 FROM citus_stat_tenants; ?column? --------------------------------------------------------------------- t (1 row) SET citus.stat_tenants_log_level TO LOG; SELECT count(*)>=0 FROM citus_stat_tenants; LOG: Generating citus_stat_tenants CONTEXT: PL/pgSQL function citus_stat_tenants(boolean) line XX at RAISE ?column? --------------------------------------------------------------------- t (1 row) SET citus.stat_tenants_log_level TO DEBUG; SELECT count(*)>=0 FROM citus_stat_tenants; LOG: Generating citus_stat_tenants CONTEXT: PL/pgSQL function citus_stat_tenants(boolean) line XX at RAISE ?column? --------------------------------------------------------------------- t (1 row) RESET client_min_messages; SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) -- test turning monitoring on/off SET citus.stat_tenants_track TO "NONE"; SELECT count(*)>=0 FROM dist_tbl WHERE a = 1; ?column? --------------------------------------------------------------------- t (1 row) INSERT INTO dist_tbl VALUES (1, 1); SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- (0 rows) SET citus.stat_tenants_track TO "ALL"; SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- (0 rows) SELECT count(*)>=0 FROM dist_tbl WHERE a = 1; ?column? --------------------------------------------------------------------- t (1 row) INSERT INTO dist_tbl VALUES (1, 1); SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- 1 | 2 (1 row) -- test special and multibyte characters in tenant attribute SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) TRUNCATE TABLE dist_tbl_text; SELECT count(*)>=0 FROM dist_tbl_text WHERE a = '/bcde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = '/*bcde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = '/b*cde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = '/b*c/de'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'b/*//cde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = '/b/*/cde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = '/b/**/cde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'bcde*'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'bcde*/'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = U&'\0061\0308bc'; ?column? --------------------------------------------------------------------- t (1 row) \c - - - :worker_1_port SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants(true) ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- /*bcde | 1 | 0 | 1 | 0 /b*c/de | 1 | 0 | 1 | 0 /b*cde | 1 | 0 | 1 | 0 /b/**/cde | 1 | 0 | 1 | 0 /b/*/cde | 1 | 0 | 1 | 0 /bcde | 1 | 0 | 1 | 0 äbc | 1 | 0 | 1 | 0 b/*//cde | 1 | 0 | 1 | 0 bcde* | 1 | 0 | 1 | 0 bcde*/ | 1 | 0 | 1 | 0 (10 rows) \c - - - :worker_2_port SET search_path TO citus_stat_tenants; SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants(true) ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- /*bcde | 1 | 0 | 1 | 0 /b*c/de | 1 | 0 | 1 | 0 /b*cde | 1 | 0 | 1 | 0 /b/**/cde | 1 | 0 | 1 | 0 /b/*/cde | 1 | 0 | 1 | 0 /bcde | 1 | 0 | 1 | 0 äbc | 1 | 0 | 1 | 0 b/*//cde | 1 | 0 | 1 | 0 bcde* | 1 | 0 | 1 | 0 bcde*/ | 1 | 0 | 1 | 0 (10 rows) SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) -- test local queries -- all of these distribution column values are from second worker SELECT count(*)>=0 FROM dist_tbl_text WHERE a = '/b*c/de'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = '/bcde'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = U&'\0061\0308bc'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'bcde*'; ?column? --------------------------------------------------------------------- t (1 row) DELETE FROM dist_tbl_text WHERE a = '/b*c/de'; DELETE FROM dist_tbl_text WHERE a = '/bcde'; DELETE FROM dist_tbl_text WHERE a = U&'\0061\0308bc'; DELETE FROM dist_tbl_text WHERE a = 'bcde*'; SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants_local(true) ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- /b*c/de | 1 | 0 | 2 | 0 /bcde | 1 | 0 | 2 | 0 äbc | 1 | 0 | 2 | 0 bcde* | 1 | 0 | 2 | 0 (4 rows) -- test local cached queries & prepared statements PREPARE dist_tbl_text_select_plan (text) AS SELECT count(*)>=0 FROM dist_tbl_text WHERE a = $1; EXECUTE dist_tbl_text_select_plan('/b*c/de'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/bcde'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan(U&'\0061\0308bc'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('bcde*'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/b*c/de'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/bcde'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan(U&'\0061\0308bc'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('bcde*'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/b*c/de'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/bcde'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan(U&'\0061\0308bc'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('bcde*'); ?column? --------------------------------------------------------------------- t (1 row) SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants_local(true) ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- /b*c/de | 4 | 0 | 5 | 0 /bcde | 4 | 0 | 5 | 0 äbc | 4 | 0 | 5 | 0 bcde* | 4 | 0 | 5 | 0 (4 rows) \c - - - :master_port SET search_path TO citus_stat_tenants; PREPARE dist_tbl_text_select_plan (text) AS SELECT count(*)>=0 FROM dist_tbl_text WHERE a = $1; EXECUTE dist_tbl_text_select_plan('/b*c/de'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/bcde'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan(U&'\0061\0308bc'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('bcde*'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/b*c/de'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/bcde'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan(U&'\0061\0308bc'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('bcde*'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/b*c/de'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('/bcde'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan(U&'\0061\0308bc'); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE dist_tbl_text_select_plan('bcde*'); ?column? --------------------------------------------------------------------- t (1 row) \c - - - :worker_2_port SET search_path TO citus_stat_tenants; SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants(true) ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- /b*c/de | 7 | 0 | 8 | 0 /bcde | 7 | 0 | 8 | 0 äbc | 7 | 0 | 8 | 0 bcde* | 7 | 0 | 8 | 0 (4 rows) \c - - - :master_port SET search_path TO citus_stat_tenants; SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) SELECT count(*)>=0 FROM dist_tbl_text WHERE a = 'thisisaveryloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongname'; ?column? --------------------------------------------------------------------- t (1 row) SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- thisisaverylooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo | 1 | 0 | 1 | 0 (1 row) -- test role permissions CREATE ROLE stats_non_superuser WITH LOGIN; SET ROLE stats_non_superuser; SELECT count(*)>=0 FROM citus_stat_tenants; ERROR: permission denied for view citus_stat_tenants SELECT count(*)>=0 FROM citus_stat_tenants_local; ERROR: permission denied for view citus_stat_tenants_local SELECT count(*)>=0 FROM citus_stat_tenants(); ERROR: permission denied for function citus_stat_tenants SELECT count(*)>=0 FROM citus_stat_tenants_local(); ERROR: permission denied for function citus_stat_tenants_local RESET ROLE; GRANT pg_monitor TO stats_non_superuser; SET ROLE stats_non_superuser; SELECT count(*)>=0 FROM citus_stat_tenants; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM citus_stat_tenants_local; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM citus_stat_tenants(); ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM citus_stat_tenants_local(); ?column? --------------------------------------------------------------------- t (1 row) RESET ROLE; DROP ROLE stats_non_superuser; -- test function push down CREATE OR REPLACE FUNCTION select_from_dist_tbl_text(p_keyword text) RETURNS boolean LANGUAGE plpgsql AS $fn$ BEGIN RETURN(SELECT count(*)>=0 FROM citus_stat_tenants.dist_tbl_text WHERE a = $1); END; $fn$; SELECT create_distributed_function( 'select_from_dist_tbl_text(text)', 'p_keyword', colocate_with => 'dist_tbl_text' ); create_distributed_function --------------------------------------------------------------------- (1 row) SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) SELECT select_from_dist_tbl_text('/b*c/de'); select_from_dist_tbl_text --------------------------------------------------------------------- t (1 row) SELECT select_from_dist_tbl_text('/b*c/de'); select_from_dist_tbl_text --------------------------------------------------------------------- t (1 row) SELECT select_from_dist_tbl_text(U&'\0061\0308bc'); select_from_dist_tbl_text --------------------------------------------------------------------- t (1 row) SELECT select_from_dist_tbl_text(U&'\0061\0308bc'); select_from_dist_tbl_text --------------------------------------------------------------------- t (1 row) 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 äbc | 2 (2 rows) CREATE OR REPLACE PROCEDURE select_from_dist_tbl_text_proc( p_keyword text ) LANGUAGE plpgsql AS $$ BEGIN PERFORM select_from_dist_tbl_text(p_keyword); PERFORM count(*)>=0 FROM citus_stat_tenants.dist_tbl_text WHERE b < 0; PERFORM count(*)>=0 FROM citus_stat_tenants.dist_tbl_text; PERFORM count(*)>=0 FROM citus_stat_tenants.dist_tbl_text WHERE a = p_keyword; COMMIT; END;$$; CALL citus_stat_tenants.select_from_dist_tbl_text_proc('/b*c/de'); CALL citus_stat_tenants.select_from_dist_tbl_text_proc('/b*c/de'); CALL citus_stat_tenants.select_from_dist_tbl_text_proc('/b*c/de'); 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 ORDER BY tenant_attribute; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- /b*c/de | 8 äbc | 8 (2 rows) CREATE OR REPLACE VIEW select_from_dist_tbl_text_view AS SELECT * FROM citus_stat_tenants.dist_tbl_text; SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = '/b*c/de'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = '/b*c/de'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = '/b*c/de'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = U&'\0061\0308bc'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = U&'\0061\0308bc'; ?column? --------------------------------------------------------------------- t (1 row) SELECT count(*)>=0 FROM select_from_dist_tbl_text_view WHERE a = U&'\0061\0308bc'; ?column? --------------------------------------------------------------------- t (1 row) 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 äbc | 11 (2 rows) -- single shard distributed table, which is not part of a tenant schema SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) SET citus.shard_replication_factor TO 1; CREATE TABLE dist_tbl_text_single_shard(a text, b int); select create_distributed_table('dist_tbl_text_single_shard', NULL); create_distributed_table --------------------------------------------------------------------- (1 row) INSERT INTO dist_tbl_text_single_shard VALUES ('/b*c/de', 1); SELECT count(*)>=0 FROM dist_tbl_text_single_shard WHERE a = '/b*c/de'; ?column? --------------------------------------------------------------------- t (1 row) DELETE FROM dist_tbl_text_single_shard WHERE a = '/b*c/de'; UPDATE dist_tbl_text_single_shard SET b = 1 WHERE a = '/b*c/de'; SELECT tenant_attribute, query_count_in_this_period FROM citus_stat_tenants; tenant_attribute | query_count_in_this_period --------------------------------------------------------------------- (0 rows) -- schema based tenants SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) SET citus.enable_schema_based_sharding TO ON; CREATE SCHEMA citus_stat_tenants_t1; CREATE TABLE citus_stat_tenants_t1.users(id int); SELECT id FROM citus_stat_tenants_t1.users WHERE id = 2; id --------------------------------------------------------------------- (0 rows) INSERT INTO citus_stat_tenants_t1.users VALUES (1); UPDATE citus_stat_tenants_t1.users SET id = 2 WHERE id = 1; DELETE FROM citus_stat_tenants_t1.users WHERE id = 2; SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- citus_stat_tenants_t1 | 1 | 0 | 4 | 0 (1 row) SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) PREPARE schema_tenant_insert_plan (int) AS insert into citus_stat_tenants_t1.users values ($1); EXECUTE schema_tenant_insert_plan(1); PREPARE schema_tenant_select_plan (int) AS SELECT count(*) > 1 FROM citus_stat_tenants_t1.users where Id = $1; EXECUTE schema_tenant_select_plan(1); ?column? --------------------------------------------------------------------- f (1 row) SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- citus_stat_tenants_t1 | 1 | 0 | 2 | 0 (1 row) SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) -- local execution & prepared statements \c - - - :worker_2_port SET search_path TO citus_stat_tenants; PREPARE schema_tenant_insert_plan (int) AS insert into citus_stat_tenants_t1.users values ($1); EXECUTE schema_tenant_insert_plan(1); EXECUTE schema_tenant_insert_plan(1); EXECUTE schema_tenant_insert_plan(1); EXECUTE schema_tenant_insert_plan(1); EXECUTE schema_tenant_insert_plan(1); PREPARE schema_tenant_select_plan (int) AS SELECT count(*) > 1 FROM citus_stat_tenants_t1.users where Id = $1; EXECUTE schema_tenant_select_plan(1); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE schema_tenant_select_plan(1); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE schema_tenant_select_plan(1); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE schema_tenant_select_plan(1); ?column? --------------------------------------------------------------------- t (1 row) EXECUTE schema_tenant_select_plan(1); ?column? --------------------------------------------------------------------- t (1 row) SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- citus_stat_tenants_t1 | 5 | 0 | 10 | 0 (1 row) \c - - - :master_port SET search_path TO citus_stat_tenants; SET citus.enable_schema_based_sharding TO OFF; SELECT citus_stat_tenants_reset(); citus_stat_tenants_reset --------------------------------------------------------------------- (1 row) -- test sampling -- set rate to 0 to disable sampling SELECT result FROM run_command_on_all_nodes('ALTER SYSTEM set citus.stat_tenants_untracked_sample_rate to 0;'); result --------------------------------------------------------------------- ALTER SYSTEM ALTER SYSTEM ALTER SYSTEM (3 rows) SELECT result FROM run_command_on_all_nodes('SELECT pg_reload_conf()'); result --------------------------------------------------------------------- t t t (3 rows) INSERT INTO dist_tbl VALUES (1, 'abcd'); INSERT INTO dist_tbl VALUES (2, 'abcd'); UPDATE dist_tbl SET b = a + 1 WHERE a = 3; UPDATE dist_tbl SET b = a + 1 WHERE a = 4; DELETE FROM dist_tbl WHERE a = 5; SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period FROM citus_stat_tenants ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period --------------------------------------------------------------------- (0 rows) -- test sampling -- set rate to 1 to track all tenants SELECT result FROM run_command_on_all_nodes('ALTER SYSTEM set citus.stat_tenants_untracked_sample_rate to 1;'); result --------------------------------------------------------------------- ALTER SYSTEM ALTER SYSTEM ALTER SYSTEM (3 rows) SELECT result FROM run_command_on_all_nodes('SELECT pg_reload_conf()'); result --------------------------------------------------------------------- t t t (3 rows) SELECT sleep_until_next_period(); sleep_until_next_period --------------------------------------------------------------------- (1 row) SELECT pg_sleep(0.1); pg_sleep --------------------------------------------------------------------- (1 row) INSERT INTO dist_tbl VALUES (1, 'abcd'); INSERT INTO dist_tbl VALUES (2, 'abcd'); UPDATE dist_tbl SET b = a + 1 WHERE a = 3; UPDATE dist_tbl SET b = a + 1 WHERE a = 4; DELETE FROM dist_tbl WHERE a = 5; SELECT tenant_attribute, read_count_in_this_period, read_count_in_last_period, query_count_in_this_period, query_count_in_last_period, (cpu_usage_in_this_period>0) AS cpu_is_used_in_this_period, (cpu_usage_in_last_period>0) AS cpu_is_used_in_last_period FROM citus_stat_tenants(true) ORDER BY tenant_attribute; tenant_attribute | read_count_in_this_period | read_count_in_last_period | query_count_in_this_period | query_count_in_last_period | cpu_is_used_in_this_period | cpu_is_used_in_last_period --------------------------------------------------------------------- 1 | 0 | 0 | 1 | 0 | t | f 2 | 0 | 0 | 1 | 0 | t | f 3 | 0 | 0 | 1 | 0 | t | f 4 | 0 | 0 | 1 | 0 | t | f 5 | 0 | 0 | 1 | 0 | t | f (5 rows) SET client_min_messages TO ERROR; DROP SCHEMA citus_stat_tenants CASCADE; DROP SCHEMA citus_stat_tenants_t1 CASCADE;