Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 62b0e33

Browse files
committed
alter_ftable_set_server in mv_part.
1 parent 4bd380a commit 62b0e33

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

pg_shardman--0.0.2.sql

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -389,12 +389,14 @@ BEGIN
389389
END IF;
390390

391391
-- Is there some replica of this node?
392-
SELECT node_id INTO new_master_id FROM shardman.replicas WHERE part_name=part.part_name ORDER BY random() LIMIT 1;
392+
SELECT node_id INTO new_master_id FROM shardman.replicas
393+
WHERE part_name=part.part_name ORDER BY random() LIMIT 1;
393394
IF new_master_id IS NOT NULL
394395
THEN -- exists some replica for this node: redirect foreign table to
395396
-- this replica and refresh LR channels for this replication group
396397
-- Update partitions table: now replica is promoted to master...
397-
UPDATE shardman.partitions SET node_id=new_master_id WHERE part_name=part.part_name;
398+
UPDATE shardman.partitions SET node_id=new_master_id
399+
WHERE part_name=part.part_name;
398400
-- ... and is not a replica any more
399401
DELETE FROM shardman.replicas WHERE part_name=part.part_name AND node_id=new_master_id;
400402

@@ -415,9 +417,12 @@ BEGIN
415417
PERFORM shardman.broadcast(pubs, super_connstr => true);
416418
-- Broadcast refresh alter subscription commands
417419
PERFORM shardman.broadcast(subs, super_connstr => true);
418-
ELSE -- there is no replica: we have to create new empty partition at random mode and redirect all FDWs to it
419-
SELECT id INTO new_master_id FROM shardman.nodes WHERE id<>rm_node_id ORDER BY random() LIMIT 1;
420-
INSERT INTO shardman.partitions (part_name,node_id,relation) VALUES (part.part.name,new_master_id,part.relation);
420+
ELSE -- there is no replica: we have to create new empty partition at
421+
-- random mode and redirect all FDWs to it
422+
SELECT id INTO new_master_id FROM shardman.nodes
423+
WHERE id<>rm_node_id ORDER BY random() LIMIT 1;
424+
INSERT INTO shardman.partitions (part_name,node_id,relation)
425+
VALUES (part.part.name,new_master_id,part.relation);
421426
END IF;
422427

423428
-- Update pathman partition map at all nodes
@@ -434,7 +439,7 @@ BEGIN
434439
-- At all other nodes adjust foreign server for foreign table to
435440
-- refer to new master node.
436441
prts := format(
437-
'%s%s:SELECT shardman.alter_ftable_set_server(%L, ''node_%s'');',
442+
'%s%s:SELECT shardman.alter_ftable_set_server(%L, ''node_%s'', true);',
438443
prts, node.id, fdw_part_name, new_master_id);
439444
END IF;
440445
END LOOP;
@@ -455,9 +460,10 @@ BEGIN
455460
END
456461
$$ LANGUAGE plpgsql;
457462

458-
-- Since PG doesn't support it, mess with catalogs directly. If no more foreign
459-
-- tables use old server, drop it.
460-
CREATE FUNCTION alter_ftable_set_server(ftable name, new_fserver name) RETURNS void AS $$
463+
-- Since PG doesn't support it, mess with catalogs directly. If asked and no one
464+
-- uses this server, drop it.
465+
CREATE FUNCTION alter_ftable_set_server(ftable name, new_fserver name,
466+
server_not_needed bool DEFAULT false) RETURNS void AS $$
461467
DECLARE
462468
new_fserver_oid oid := oid FROM pg_foreign_server WHERE srvname = new_fserver;
463469
old_fserver name := srvname FROM pg_foreign_server
@@ -467,7 +473,8 @@ BEGIN
467473
UPDATE pg_foreign_table SET ftserver = new_fserver_oid WHERE ftrelid = ftable::regclass;
468474
UPDATE pg_depend SET refobjid = new_fserver_oid
469475
WHERE objid = ftable::regclass AND refobjid = old_fserver_oid;
470-
IF (SELECT count(*) FROM pg_foreign_table WHERE ftserver = old_fserver_oid) = 0
476+
IF server_not_needed AND
477+
((SELECT count(*) FROM pg_foreign_table WHERE ftserver = old_fserver_oid) = 0)
471478
THEN
472479
EXECUTE format('DROP SERVER %s CASCADE', old_fserver);
473480
END IF;
@@ -862,8 +869,8 @@ BEGIN
862869
drop_fdws := format('%s%s:DROP FOREIGN TABLE %I;',
863870
drop_fdws, node.id, fdw_part_name);
864871
ELSE
865-
replace_parts := format('%s%s:UPDATE pg_foreign_table SET ftserver = (SELECT oid FROM pg_foreign_server WHERE srvname = ''node_%s'') WHERE ftrelid = (SELECT oid FROM pg_class WHERE relname=%L);',
866-
replace_parts, node.id, dst_node_id, fdw_part_name);
872+
replace_parts := format('%s%s:SELECT shardman.alter_ftable_set_server(%L, ''node_%s'');',
873+
replace_parts, node.id, fdw_part_name, dst_node_id);
867874
END IF;
868875
END LOOP;
869876

@@ -2032,40 +2039,46 @@ BEGIN
20322039
IF seqno <> max_seqno
20332040
THEN
20342041
RAISE NOTICE 'Advance node % from %', replica.node_id, advanced_node;
2035-
PERFORM shardman.remote_copy(replica.relation, replica.part_name, replica.node_id, advanced_node, seqno);
2042+
PERFORM shardman.remote_copy(replica.relation, pname, replica.node_id,
2043+
advanced_node, seqno);
20362044
END IF;
20372045
END LOOP;
20382046
END;
20392047
$$ LANGUAGE plpgsql;
20402048

2041-
-- Get relation primary key. There can be table with no primary key or with compound primary key.
2042-
-- But logical replication and hash partitioning in any case requires single primary key.
2049+
-- Get relation primary key. There can be table with no primary key or with
2050+
-- compound primary key. But logical replication and hash partitioning in any
2051+
-- case requires single primary key.
20432052
CREATE FUNCTION get_primary_key(rel regclass, out pk_name text, out pk_type text) AS $$
2044-
SELECT a.attname::text,a.atttypid::regtype::text FROM pg_index i
2053+
SELECT a.attname::text, a.atttypid::regtype::text FROM pg_index i
20452054
JOIN pg_attribute a ON a.attrelid = i.indrelid
20462055
AND a.attnum = ANY(i.indkey)
20472056
WHERE i.indrelid = rel
20482057
AND i.indisprimary;
20492058
$$ LANGUAGE sql;
20502059

2051-
-- Copy missing data from one node to another. This function us using change_log table to determine records which need to be copied.
2060+
-- Copy missing data from one node to another. This function uses change_log
2061+
-- table to determine records which need to be copied.
20522062
-- See explanations in synchronize_replicas.
20532063
-- Parameters:
20542064
-- rel_name: name of parent relation
20552065
-- part_name: synchronized partition name
20562066
-- dst_node: lagging node
20572067
-- src_node: advanced node
20582068
-- last_seqno: maximal seqno at lagging node
2059-
CREATE FUNCTION remote_copy(rel_name text, part_name text, dst_node int, src_node int, last_seqno bigint) RETURNS void AS $$
2069+
CREATE FUNCTION remote_copy(rel_name text, part_name text, dst_node int,
2070+
src_node int, last_seqno bigint) RETURNS void AS $$
20602071
DECLARE
20612072
script text;
20622073
conn_string text;
20632074
pk_name text;
20642075
pk_type text;
20652076
BEGIN
2066-
SELECT * FROM shardman.get_primary_key(rel_name) INTO pk_name,pk_type;
2077+
SELECT * FROM shardman.get_primary_key(rel_name) INTO pk_name, pk_type;
2078+
ASSERT pk_name IS NOT NULL, 'Can''t sync replicas without primary key';
20672079
SELECT connection_string INTO conn_string FROM shardman.nodes WHERE id=src_node;
2068-
-- We need to execute all this three statements in one transaction to exclude inconsistencies in case of failure
2080+
-- We need to execute all this three statements in one transaction to
2081+
-- exclude inconsistencies in case of failure
20692082
script := format('{%s:COPY %s_change_log FROM PROGRAM ''psql "%s" -c "COPY (SELECT * FROM %s_change_log WHERE seqno>%s) TO stdout"'';
20702083
DELETE FROM %I USING %s_change_log cl WHERE cl.seqno>%s AND cl.old_pk=%I;
20712084
COPY %I FROM PROGRAM ''psql "%s" -c "COPY (SELECT DISTINCT ON (%I) %I.* FROM %I,%s_change_log cl WHERE cl.seqno>%s AND cl.new_pk=%I ORDER BY %I) TO stdout"''}',

readme.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,10 @@ We don't track replication mode for each table separately, and changing
252252
`shardman.sync_replication` GUC during cluster operation might lead to a mess.
253253
It is better to set it permanently for now.
254254

255-
`pg_shardman` currently doesn't bothers itself with configuring replication
255+
`pg_shardman` currently doesn't bother itself with configuring replication
256256
identities. It is strongly recommended to use primary key as sharding key to
257-
avoid problems with `UPDATE` and `DELETE` operations.
257+
avoid problems with `UPDATE` and `DELETE` operations. Besides, primary key is
258+
necessary to synchronize multiple replicas after failure.
258259

259260
### Balancing the load
260261

0 commit comments

Comments
 (0)