3434$$;
3535
3636-- --------------------------------------------------------------------------------------------------------------------
37- -- colocate_multirelation colocates one multirelation with another
37+ -- colocate_shards physically moves table2's shards so each one lands on the
38+ -- same node as table1's shard sharing the same tile_key range (shardminvalue).
39+ -- Citus' own colocate_with option doesn't support range-distributed tables,
40+ -- so this does the move explicitly with citus_move_shard_placement() instead
41+ -- of relying on Citus' colocation groups.
3842-- --------------------------------------------------------------------------------------------------------------------
39- CREATE OR REPLACE FUNCTION colocate_multirelation (table1 text , table2 text )
43+ DROP FUNCTION IF EXISTS colocate_multirelation;
44+ CREATE OR REPLACE FUNCTION colocate_shards (table1 text , table2 text )
4045 RETURNS boolean
4146LANGUAGE plpgsql
4247AS $$
4348DECLARE
44- i integer ;
45- shard_info record;
46- node_info record;
47- node text ;
48- shardid_test bigint ;
49+ tile_pair record;
4950BEGIN
50- -- Move one of them to a new place because one node contains 10 and the other contains 11
51- -- It is an enterpise feature
52- -- SELECT master_move_shard_placement(102660,'pgxl4', 5432,'pgxl2', 5432);
53- -- For every node, update shards information
54- FOR node_info in SELECT * FROM master_get_active_worker_nodes()
51+ FOR tile_pair IN
52+ SELECT s2 .shardid AS moving_shard,
53+ n1 .nodename AS target_node, n1 .nodeport AS target_port,
54+ n2 .nodename AS source_node, n2 .nodeport AS source_port
55+ FROM pg_dist_shard s1
56+ JOIN pg_dist_placement p1 ON p1 .shardid = s1 .shardid
57+ JOIN pg_dist_node n1 ON n1 .groupid = p1 .groupid AND n1 .noderole = ' primary'
58+ JOIN pg_dist_shard s2 ON s2 .shardminvalue = s1 .shardminvalue
59+ JOIN pg_dist_placement p2 ON p2 .shardid = s2 .shardid
60+ JOIN pg_dist_node n2 ON n2 .groupid = p2 .groupid AND n2 .noderole = ' primary'
61+ WHERE s1 .logicalrelid = table1::regclass
62+ AND s2 .logicalrelid = table2::regclass
63+ AND (n1 .nodename , n1 .nodeport ) IS DISTINCT FROM (n2 .nodename , n2 .nodeport )
5564 LOOP
56- i = 0 ;
57- -- Get the shards of every table in every node
58- FOR shard_info in SELECT shard .shardid , shard .shardminvalue , shard .shardmaxvalue
59- FROM pg_dist_placement AS placement, pg_dist_node AS node, pg_dist_shard As shard
60- WHERE placement .groupid = node .groupid
61- AND shard .logicalrelid = table1::regclass
62- AND placement .shardid = shard .shardid
63- AND node .noderole = ' primary'
64- AND nodename= node_info .node_name
65- LOOP
66- SELECT shard .shardid
67- FROM pg_dist_placement AS placement, pg_dist_node AS node, pg_dist_shard As shard
68- WHERE placement .groupid = node .groupid
69- AND shard .logicalrelid = table2::regclass
70- AND placement .shardid = shard .shardid
71- AND node .noderole = ' primary'
72- AND nodename= node_info .node_name offset i limit 1 INTO shardid_test;
73- -- RAISE NOTICE 'Update:%',shardid_test;
74- UPDATE pg_dist_shard SET shardminvalue = shard_info .shardminvalue , shardmaxvalue= shard_info .shardmaxvalue
75- WHERE shardid = shardid_test;
76- i := i + 1 ;
77- END LOOP;
65+ PERFORM citus_move_shard_placement(tile_pair .moving_shard ,
66+ tile_pair .source_node , tile_pair .source_port ,
67+ tile_pair .target_node , tile_pair .target_port ,
68+ ' block_writes' );
7869 END LOOP;
7970 RETURN TRUE;
8071END;
@@ -101,11 +92,15 @@ i integer;
10192 results json;
10293BEGIN
10394 PERFORM create_range_shards(shards, reshuffled_table);
104- -- Modify the ranges
105- UPDATE pg_catalog .pg_dist_partition
106- SET colocationid= 2
107- WHERE logicalrelid= reshuffled_table::regclass;
108- PERFORM colocate_multirelation(tableName, reshuffled_table);
95+ /* create_range_shards() above already assigns reshuffled_table's shards
96+ * the correct tile_key-aligned ranges (1..shards), matching tableName's
97+ * own tile numbering by convention -- both tables tile the same way.
98+ * Citus' shard placement for the newly-created shards is otherwise
99+ * independent of tableName's placement, so without this, a tile-key
100+ * join between the two tables is a cross-node repartition even though
101+ * both sides cover the same tile_key range. colocate_shards() moves
102+ * each of reshuffled_table's shards onto tableName's matching-tile node. */
103+ PERFORM colocate_shards(tableName, reshuffled_table);
109104RETURN true;
110105END;
111106$$;
0 commit comments