-- -- failure_offline_move_shard_placement -- -- The tests cover moving shard placements without using logical replication. CREATE SCHEMA IF NOT EXISTS move_shard_offline; SET SEARCH_PATH = move_shard_offline; SET citus.shard_count TO 4; SET citus.next_shard_id TO 200; SET citus.shard_replication_factor TO 1; SELECT pg_backend_pid() as pid \gset SELECT citus.mitmproxy('conn.allow()'); mitmproxy --------------------------------------------------------------------- (1 row) CREATE TABLE t(id int PRIMARY KEY, int_data int); SELECT create_distributed_table('t', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE VIEW shards_in_workers AS SELECT shardid, (CASE WHEN nodeport = :worker_1_port THEN 'worker1' ELSE 'worker2' END) AS worker FROM pg_dist_placement NATURAL JOIN pg_dist_node WHERE shardstate != 4 ORDER BY 1,2 ASC; CREATE VIEW indices_on_shard_201 AS SELECT * FROM run_command_on_workers( $cmd$ SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END FROM pg_index WHERE indrelid = 'move_shard_offline.t_201'::regclass $cmd$); CREATE VIEW find_index_for_shard_201_in_workers AS SELECT CASE nodeport WHEN :worker_1_port THEN 'worker1' ELSE 'worker2' END FROM indices_on_shard_201 WHERE result = 't'; -- Insert some data INSERT INTO t SELECT x, x+1 FROM generate_series(1,100) AS f(x); -- Initial shard placements SELECT * FROM shards_in_workers; shardid | worker --------------------------------------------------------------------- 200 | worker2 201 | worker1 202 | worker2 203 | worker1 (4 rows) SELECT * FROM find_index_for_shard_201_in_workers; case --------------------------------------------------------------------- worker1 (1 row) -- failure on sanity checks SELECT citus.mitmproxy('conn.onQuery(query="DROP TABLE IF EXISTS move_shard_offline.t CASCADE").kill()'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); ERROR: connection not open CONTEXT: while executing command on localhost:xxxxx -- cancellation on sanity checks SELECT citus.mitmproxy('conn.onQuery(query="DROP TABLE IF EXISTS move_shard_offline.t CASCADE").cancel(' || :pid || ')'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); ERROR: canceling statement due to user request -- failure on move_shard table creation SELECT citus.mitmproxy('conn.onQuery(query="CREATE TABLE move_shard_offline.t").kill()'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); ERROR: connection not open CONTEXT: while executing command on localhost:xxxxx -- cancellation on move_shard table creation SELECT citus.mitmproxy('conn.onQuery(query="CREATE TABLE move_shard_offline.t").cancel(' || :pid || ')'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); ERROR: canceling statement due to user request -- failure on blocking COPY operation on target node SELECT citus.mitmproxy('conn.onQuery(query="COPY").kill()'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); ERROR: connection not open CONTEXT: while executing command on localhost:xxxxx while executing command on localhost:xxxxx -- cancellation on blocking COPY operation on target node SELECT citus.mitmproxy('conn.onQuery(query="COPY").cancel(' || :pid || ')'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); ERROR: canceling statement due to user request -- failure on adding constraints on target node SELECT citus.mitmproxy('conn.onQuery(query="ADD CONSTRAINT").kill()'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); ERROR: connection not open CONTEXT: while executing command on localhost:xxxxx -- cancellation on adding constraints on target node SELECT citus.mitmproxy('conn.onQuery(query="ADD CONSTRAINT").cancel(' || :pid || ')'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); ERROR: canceling statement due to user request SELECT public.wait_for_resource_cleanup(); wait_for_resource_cleanup --------------------------------------------------------------------- (1 row) -- Verify that the shard is not moved and the number of rows are still 100k SELECT citus.mitmproxy('conn.allow()'); mitmproxy --------------------------------------------------------------------- (1 row) SELECT * FROM shards_in_workers; shardid | worker --------------------------------------------------------------------- 200 | worker2 201 | worker1 202 | worker2 203 | worker1 (4 rows) SELECT count(*) FROM t; count --------------------------------------------------------------------- 100 (1 row) SELECT * FROM find_index_for_shard_201_in_workers; case --------------------------------------------------------------------- worker1 (1 row) -- Verify that shard can be moved after a temporary failure SELECT master_move_shard_placement(201, 'localhost', :worker_1_port, 'localhost', :worker_2_proxy_port, 'block_writes'); master_move_shard_placement --------------------------------------------------------------------- (1 row) SELECT public.wait_for_resource_cleanup(); wait_for_resource_cleanup --------------------------------------------------------------------- (1 row) SELECT * FROM shards_in_workers; shardid | worker --------------------------------------------------------------------- 200 | worker2 201 | worker2 202 | worker2 203 | worker1 (4 rows) SELECT count(*) FROM t; count --------------------------------------------------------------------- 100 (1 row) SELECT * FROM find_index_for_shard_201_in_workers; case --------------------------------------------------------------------- worker2 (1 row) DROP SCHEMA move_shard_offline CASCADE; NOTICE: drop cascades to 4 other objects DETAIL: drop cascades to table t drop cascades to view shards_in_workers drop cascades to view indices_on_shard_201 drop cascades to view find_index_for_shard_201_in_workers