mirror of https://github.com/citusdata/citus.git
invalidate plan cache in master_update_node
If a plan is cached by postgres but a user uses master_update_node, then when the plan cache is used for the updated node, they will get the old nodename/nodepost in the plan. This is because the plan cache doesn't know about the master_update_node. This could be a problem in prepared statements or anything that goes into plancache. As a solution the plan cache is invalidated inside master_update_node.copy/fix/clearPrepareCache
parent
2d50f63841
commit
8d8bc974ef
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
---------------------------------------------------------------------
|
||||
|
|
|
@ -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.
|
||||
--------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue