From 286a27eded58df24aa61f211206cc9a692e8cac3 Mon Sep 17 00:00:00 2001 From: Zhenghua Lyu Date: Wed, 28 Feb 2018 15:04:04 +0800 Subject: [PATCH] Clear queueid of queueentry stat after sending out. Different queries in the same session may be in different resource queues. The resource queue field of stat cache in local hash should be cleaned after the stat message has been sent out. This commit fix the Github issue #4582 . --- src/backend/postmaster/pgstat.c | 3 +- .../regress/expected/resource_queue_stat.out | 137 ++++++++++++++++++ src/test/regress/greenplum_schedule | 1 + src/test/regress/sql/resource_queue_stat.sql | 70 +++++++++ 4 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 src/test/regress/expected/resource_queue_stat.out create mode 100644 src/test/regress/sql/resource_queue_stat.sql diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 2972c4b65f..2b74e8c29b 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -4202,7 +4202,7 @@ pgstat_getportalentry(uint32 portalid, Oid queueid) Assert(portalentry != NULL); /* Initialize if this we have not seen this portal before! */ - if (!found) + if (!found || portalentry->queueentry.queueid == InvalidOid) { portalentry->portalid = portalid; portalentry->queueentry.queueid = queueid; @@ -4254,6 +4254,7 @@ pgstat_report_queuestat() msg.m_elapsed_wait = pentry->queueentry.elapsed_wait; /* Reset the counters for this entry. */ + pentry->queueentry.queueid = InvalidOid; pentry->queueentry.n_queries_exec = 0; pentry->queueentry.n_queries_wait = 0; pentry->queueentry.elapsed_exec = 0; diff --git a/src/test/regress/expected/resource_queue_stat.out b/src/test/regress/expected/resource_queue_stat.out new file mode 100644 index 0000000000..ba2984215d --- /dev/null +++ b/src/test/regress/expected/resource_queue_stat.out @@ -0,0 +1,137 @@ +set stats_queue_level=on; +-- start_ignore +drop role resqueuetest; +ERROR: role "resqueuetest" does not exist +drop resource queue q; +ERROR: resource queue "q" does not exist +-- end_ignore +create resource queue q with (active_statements = 10); +create user resqueuetest with resource queue q; +set role resqueuetest; +select 1; + ?column? +---------- + 1 +(1 row) + +select 1; + ?column? +---------- + 1 +(1 row) + +select 1; + ?column? +---------- + 1 +(1 row) + +select pg_sleep(1); + pg_sleep +---------- + +(1 row) + +-- will display q.n_queries_exec=4, and after the query it becomes 5 +select queuename, n_queries_exec from pg_stat_resqueues where queuename = 'q'; + queuename | n_queries_exec +-----------+---------------- + q | 4 +(1 row) + +-- drop the queue +reset role; +drop role resqueuetest; +drop resource queue q; +set stats_queue_level=on; +-- create the queue and test +create resource queue q with (active_statements = 10); +create user resqueuetest with resource queue q; +set role resqueuetest; +select 1; + ?column? +---------- + 1 +(1 row) + +select 1; + ?column? +---------- + 1 +(1 row) + +select 1; + ?column? +---------- + 1 +(1 row) + +select pg_sleep(1); + pg_sleep +---------- + +(1 row) + +-- will display q.n_queries_exec=4, and after the query it becomes 5 +select queuename, n_queries_exec from pg_stat_resqueues where queuename = 'q'; + queuename | n_queries_exec +-----------+---------------- + q | 4 +(1 row) + +-- create another queue, do switch test +reset role; +set stats_queue_level=on; +-- start_ignore +drop role resqueuetest1; +ERROR: role "resqueuetest1" does not exist +drop resource queue q1; +ERROR: resource queue "q1" does not exist +-- end_ignore +create resource queue q1 with (active_statements = 10); +create user resqueuetest1 with resource queue q1; +-- now change the role +set role resqueuetest1; +select 1; + ?column? +---------- + 1 +(1 row) + +select 1; + ?column? +---------- + 1 +(1 row) + +select 1; + ?column? +---------- + 1 +(1 row) + +select pg_sleep(1); + pg_sleep +---------- + +(1 row) + +-- will display q.n_queries_exec=5, q1.n_queries_exec=4 +select queuename, n_queries_exec from pg_stat_resqueues where queuename = 'q1'; + queuename | n_queries_exec +-----------+---------------- + q1 | 4 +(1 row) + +select queuename, n_queries_exec from pg_stat_resqueues where queuename = 'q'; + queuename | n_queries_exec +-----------+---------------- + q | 5 +(1 row) + +-- clean +reset role; +drop role resqueuetest; +drop resource queue q; +drop role resqueuetest1; +drop resource queue q1; diff --git a/src/test/regress/greenplum_schedule b/src/test/regress/greenplum_schedule index 89ba8f57ac..0814c693c1 100755 --- a/src/test/regress/greenplum_schedule +++ b/src/test/regress/greenplum_schedule @@ -90,6 +90,7 @@ ignore: icudp_full test: resource_queue test: resource_queue_function +test: resource_queue_stat test: resource_group test: wrkloadadmin diff --git a/src/test/regress/sql/resource_queue_stat.sql b/src/test/regress/sql/resource_queue_stat.sql new file mode 100644 index 0000000000..00b98c09de --- /dev/null +++ b/src/test/regress/sql/resource_queue_stat.sql @@ -0,0 +1,70 @@ +set stats_queue_level=on; + +-- start_ignore +drop role resqueuetest; +drop resource queue q; +-- end_ignore + +create resource queue q with (active_statements = 10); +create user resqueuetest with resource queue q; + +set role resqueuetest; + +select 1; +select 1; +select 1; + +select pg_sleep(1); +-- will display q.n_queries_exec=4, and after the query it becomes 5 +select queuename, n_queries_exec from pg_stat_resqueues where queuename = 'q'; + +-- drop the queue +reset role; +drop role resqueuetest; +drop resource queue q; + +set stats_queue_level=on; + +-- create the queue and test +create resource queue q with (active_statements = 10); +create user resqueuetest with resource queue q; + +set role resqueuetest; + +select 1; +select 1; +select 1; + +select pg_sleep(1); +-- will display q.n_queries_exec=4, and after the query it becomes 5 +select queuename, n_queries_exec from pg_stat_resqueues where queuename = 'q'; + +-- create another queue, do switch test +reset role; +set stats_queue_level=on; + +-- start_ignore +drop role resqueuetest1; +drop resource queue q1; +-- end_ignore + +create resource queue q1 with (active_statements = 10); +create user resqueuetest1 with resource queue q1; + +-- now change the role +set role resqueuetest1; +select 1; +select 1; +select 1; + +select pg_sleep(1); +-- will display q.n_queries_exec=5, q1.n_queries_exec=4 +select queuename, n_queries_exec from pg_stat_resqueues where queuename = 'q1'; +select queuename, n_queries_exec from pg_stat_resqueues where queuename = 'q'; + +-- clean +reset role; +drop role resqueuetest; +drop resource queue q; +drop role resqueuetest1; +drop resource queue q1; -- GitLab