diff --git a/src/backend/distributed/metadata/node_metadata.c b/src/backend/distributed/metadata/node_metadata.c index 58073775b..15377f427 100644 --- a/src/backend/distributed/metadata/node_metadata.c +++ b/src/backend/distributed/metadata/node_metadata.c @@ -7,6 +7,7 @@ #include "postgres.h" #include "miscadmin.h" #include "funcapi.h" +#include "utils/plancache.h" #include "access/genam.h" @@ -749,6 +750,12 @@ master_update_node(PG_FUNCTION_ARGS) LockShardsInPlacementListMetadata(placementList, AccessExclusiveLock); } + /* + * if we have planned statements such as prepared statements, we should clear the cache so that + * the planned cache doesn't return the old nodename/nodepost. + */ + ResetPlanCache(); + UpdateNodeLocation(nodeId, newNodeNameString, newNodePort); /* we should be able to find the new node from the metadata */ diff --git a/src/test/regress/expected/multi_mx_node_metadata.out b/src/test/regress/expected/multi_mx_node_metadata.out index c28eba404..c602678e6 100644 --- a/src/test/regress/expected/multi_mx_node_metadata.out +++ b/src/test/regress/expected/multi_mx_node_metadata.out @@ -311,6 +311,92 @@ SELECT verify_metadata('localhost', :worker_1_port), t | t (1 row) +--------------------------------------------------------------------- +-- Test that master_update_node invalidates the plan cache +--------------------------------------------------------------------- +PREPARE foo AS SELECT COUNT(*) FROM dist_table_1 WHERE a = 1; +SET citus.log_remote_commands = ON; +-- trigger caching for prepared statements +EXECUTE foo; +NOTICE: issuing SELECT count(*) AS count FROM public.dist_table_1_102010 dist_table_1 WHERE (a OPERATOR(pg_catalog.=) 1) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE foo; +NOTICE: issuing SELECT count(*) AS count FROM public.dist_table_1_102010 dist_table_1 WHERE (a OPERATOR(pg_catalog.=) 1) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE foo; +NOTICE: issuing SELECT count(*) AS count FROM public.dist_table_1_102010 dist_table_1 WHERE (a OPERATOR(pg_catalog.=) 1) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE foo; +NOTICE: issuing SELECT count(*) AS count FROM public.dist_table_1_102010 dist_table_1 WHERE (a OPERATOR(pg_catalog.=) 1) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE foo; +NOTICE: issuing SELECT count(*) AS count FROM public.dist_table_1_102010 dist_table_1 WHERE (a OPERATOR(pg_catalog.=) 1) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE foo; +NOTICE: issuing SELECT count(*) AS count FROM public.dist_table_1_102010 dist_table_1 WHERE (a OPERATOR(pg_catalog.=) 1) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE foo; +NOTICE: issuing SELECT count(*) AS count FROM public.dist_table_1_102010 dist_table_1 WHERE (a OPERATOR(pg_catalog.=) 1) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + +SELECT master_update_node(:nodeid_1, '127.0.0.1', :worker_1_port); + master_update_node +--------------------------------------------------------------------- + +(1 row) + +SELECT wait_until_metadata_sync(30000); +NOTICE: issuing LISTEN metadata_sync +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + wait_until_metadata_sync +--------------------------------------------------------------------- + +(1 row) + +-- make sure the nodename changed. +EXECUTE foo; +NOTICE: issuing SELECT count(*) AS count FROM public.dist_table_1_102010 dist_table_1 WHERE (a OPERATOR(pg_catalog.=) 1) +DETAIL: on server postgres@127.0.0.1:57637 connectionId: xxxxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + +SET citus.log_remote_commands TO OFF; --------------------------------------------------------------------- -- Test that master_update_node can appear in a prepared transaction. --------------------------------------------------------------------- diff --git a/src/test/regress/sql/multi_mx_node_metadata.sql b/src/test/regress/sql/multi_mx_node_metadata.sql index 727ba05c6..4dee21780 100644 --- a/src/test/regress/sql/multi_mx_node_metadata.sql +++ b/src/test/regress/sql/multi_mx_node_metadata.sql @@ -139,6 +139,30 @@ ROLLBACK; SELECT verify_metadata('localhost', :worker_1_port), verify_metadata('localhost', :worker_2_port); +-------------------------------------------------------------------------- +-- Test that master_update_node invalidates the plan cache +-------------------------------------------------------------------------- + +PREPARE foo AS SELECT COUNT(*) FROM dist_table_1 WHERE a = 1; + +SET citus.log_remote_commands = ON; +-- trigger caching for prepared statements +EXECUTE foo; +EXECUTE foo; +EXECUTE foo; +EXECUTE foo; +EXECUTE foo; +EXECUTE foo; +EXECUTE foo; + +SELECT master_update_node(:nodeid_1, '127.0.0.1', :worker_1_port); +SELECT wait_until_metadata_sync(30000); + +-- make sure the nodename changed. +EXECUTE foo; + +SET citus.log_remote_commands TO OFF; + -------------------------------------------------------------------------- -- Test that master_update_node can appear in a prepared transaction. --------------------------------------------------------------------------