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

Commit 065ecc7

Browse files
committed
Some comments and decorations for 84742fe: one fdw server per node.
We now have one foreign server per node, not per partition as before, because - Current patch for 2PC on postgres_fdw doesn't track several servers pointing to the same node, which means that we try to prepare the same xact several times. - Usefulness of old idea to specify all replicas in fdw server's connection string is arguable -- it helps only with reads, these reads can be stale, and recovery should come soon anyway. Further, one server per node should decrease number of connections (and backends) drastically. Finally, this idea was not implemented anyway.
1 parent 84742fe commit 065ecc7

File tree

1 file changed

+49
-41
lines changed

1 file changed

+49
-41
lines changed

shard.sql

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ BEGIN
240240
END IF;
241241

242242
-- And update fdw almost everywhere
243-
PERFORM shardman.update_fdw_server(NEW);
243+
PERFORM shardman.update_fdw_table_srv(NEW);
244244
RETURN NULL;
245245
END
246246
$$ LANGUAGE plpgsql;
@@ -326,7 +326,7 @@ BEGIN
326326

327327
IF NOT replica_removed AND shardman.me_worker() THEN
328328
-- update fdw almost everywhere
329-
PERFORM shardman.update_fdw_server(new_primary);
329+
PERFORM shardman.update_fdw_table_srv(new_primary);
330330
END IF;
331331

332332
IF shardman.me_lord() THEN
@@ -427,14 +427,14 @@ DECLARE
427427
opt text;
428428
opt_key text;
429429
BEGIN
430-
ASSERT EXISTS (SELECT 1 from pg_foreign_server WHERE srvname=server_name);
430+
ASSERT EXISTS (SELECT 1 FROM pg_foreign_server WHERE srvname = server_name);
431431
EXECUTE format($q$SELECT coalesce(srvoptions, '{}'::text[]) FROM
432432
pg_foreign_server WHERE srvname = %L$q$,
433-
server_name) INTO opts;
434-
FOREACH opt IN ARRAY opts LOOP
435-
opt_key := regexp_replace(substring(opt from '^.*?='), '=$', '');
436-
EXECUTE format('ALTER SERVER %I OPTIONS (DROP %s);', server_name, opt_key);
437-
END LOOP;
433+
server_name) INTO opts;
434+
FOREACH opt IN ARRAY opts LOOP
435+
opt_key := regexp_replace(substring(opt from '^.*?='), '=$', '');
436+
EXECUTE format('ALTER SERVER %I OPTIONS (DROP %s);', server_name, opt_key);
437+
END LOOP;
438438
END $$ LANGUAGE plpgsql STRICT;
439439
-- Same for resetting user mapping opts
440440
CREATE or replace FUNCTION reset_um_opts(srvname name, umuser regrole)
@@ -450,36 +450,40 @@ BEGIN
450450
ums.umuser = umuser$q$, srvname)
451451
INTO opts;
452452
IF opts IS NOT NULL THEN
453-
FOREACH opt IN ARRAY opts LOOP
454-
opt_key := regexp_replace(substring(opt from '^.*?='), '=$', '');
453+
FOREACH opt IN ARRAY opts LOOP
454+
opt_key := regexp_replace(substring(opt from '^.*?='), '=$', '');
455455
EXECUTE format('ALTER USER MAPPING FOR %I SERVER %I OPTIONS (DROP %s);',
456456
umuser::name, srvname, opt_key);
457-
END LOOP;
457+
END LOOP;
458458
END IF;
459459
END $$ LANGUAGE plpgsql STRICT;
460460

461-
CREATE FUNCTION create_foreign_server(node_id integer) RETURNS void AS $$
461+
-- Create foreign server & um pointing to node 'node_id' named "node_'node_id'",
462+
-- or alter existing one to match the connstring.
463+
CREATE FUNCTION ensure_foreign_server(node_id integer) RETURNS void AS $$
462464
DECLARE
463-
connstring text;
465+
connstring text := shardman.get_worker_node_connstr(node_id);
464466
server_opts text;
465467
um_opts text;
466-
server_name text;
468+
server_name text := 'node_' || node_id;
467469
BEGIN
468-
SELECT nodes.connstring FROM shardman.nodes WHERE id = node_id
469-
INTO connstring;
470470
SELECT * FROM shardman.conninfo_to_postgres_fdw_opts(connstring)
471471
INTO server_opts, um_opts;
472-
server_name := 'node_'||node_id;
473-
IF NOT EXISTS (SELECT 1 from pg_foreign_server WHERE srvname=server_name)
472+
IF NOT EXISTS (SELECT 1 from pg_foreign_server WHERE srvname = server_name)
474473
THEN
475-
RAISE DEBUG 'Create foreign server % for with options %', server_name, server_opts;
474+
RAISE DEBUG '[SHMN] Create foreign server % for with options %',
475+
server_name, server_opts;
476476
EXECUTE format('CREATE SERVER %I FOREIGN DATA WRAPPER postgres_fdw %s;',
477-
server_name, server_opts);
478-
-- TODO: support not only CURRENT_USER
479-
EXECUTE format('CREATE USER MAPPING FOR CURRENT_USER SERVER %I %s;',
477+
server_name, server_opts);
478+
-- TODO: support not only CURRENT_USER
479+
EXECUTE format('CREATE USER MAPPING FOR CURRENT_USER SERVER %I %s;',
480480
server_name, um_opts);
481481
ELSE
482-
RAISE DEBUG 'Use existed foreign server % with options %', server_name, server_opts;
482+
-- ALTER SERVER & UM doesn't support dropping all params. We could
483+
-- recreate them, but since these hacks already exist for legacy code,
484+
-- we can use them as well.
485+
RAISE DEBUG 'Using existing foreign server % with options %',
486+
server_name, server_opts;
483487
PERFORM shardman.reset_foreign_server_opts(server_name);
484488
PERFORM shardman.reset_um_opts(server_name, current_user::regrole);
485489

@@ -493,13 +497,12 @@ BEGIN
493497
END IF;
494498
END $$ LANGUAGE plpgsql STRICT;
495499

496-
-- Update foreign server and user mapping params on current node according to
497-
-- partition part, so this is expected to be called on server/um params
498-
-- change. FDW server, user mapping, foreign table and
499-
-- (obviously) parent partition must exist when called if they need to be
500-
-- updated; however, it is ok to call this func on nodes which don't need fdw
501-
-- setup for this part because they hold primary partition.
502-
CREATE FUNCTION update_fdw_server(part partitions) RETURNS void AS $$
500+
-- Make sure foreign table for given part is associated with proper foreign
501+
-- server, so this is expected to be called on server/um params change,
502+
-- e.g. shard move or connstring update. Foreign table must exist when called if
503+
-- they need to be updated; however, it is ok to call this func on nodes which
504+
-- don't need fdw setup for this part because they hold primary partition.
505+
CREATE FUNCTION update_fdw_table_srv(part partitions) RETURNS void AS $$
503506
DECLARE
504507
connstring text;
505508
server_opts text;
@@ -509,24 +512,31 @@ DECLARE
509512
server_oid oid;
510513
foreign_table_oid oid;
511514
BEGIN
512-
RAISE DEBUG '[SHMN] update_fdw_server called for part %, owner %',
515+
RAISE DEBUG '[SHMN] update_fdw_table_srv called for part %, owner %',
513516
part.part_name, part.owner;
514517

515518
SELECT * FROM shardman.partitions WHERE part_name = part.part_name AND
516519
owner = me INTO my_part;
517520
IF my_part.part_name IS NOT NULL THEN -- we are holding the part
518521
IF my_part.prv IS NULL THEN
519-
RAISE DEBUG '[SHMN] we are holding primary for part %, not updating fdw server for it', part.part_name;
522+
RAISE DEBUG '[SHMN] we are holding primary for part %, not updating fdw table for it',
523+
part.part_name;
520524
RETURN;
521525
ELSE
522-
RAISE DEBUG '[SHMN] we are holding replica for part %, updating fdw server for it', part.part_name;
526+
RAISE DEBUG '[SHMN] we are holding replica for part %, updating fdw table for it',
527+
part.part_name;
523528
END IF;
524529
END IF;
525530

526-
PERFORM shardman.create_foreign_server(part.owner);
531+
PERFORM shardman.ensure_foreign_server(part.owner);
527532

528-
SELECT oid FROM pg_foreign_server WHERE srvname='node_'||part.owner into server_oid;
529-
SELECT oid FROM pg_class WHERE relname=part.part_name||'_fdw' into foreign_table_oid;
533+
-- Well, ALTER FOREIGN TABLE doesn't support changing server, but this hack
534+
-- seems to be working.
535+
SELECT oid FROM pg_foreign_server WHERE srvname = 'node_' || part.owner
536+
INTO server_oid;
537+
SELECT oid FROM pg_class WHERE relname = shardman.get_fdw_part_name(part.part_name)
538+
INTO foreign_table_oid;
539+
ASSERT foreign_table_oid IS NOT NULL, 'update_fdw_table_srv: table not found';
530540
UPDATE pg_foreign_table SET ftserver = server_oid WHERE ftrelid = foreign_table_oid;
531541
END $$ LANGUAGE plpgsql STRICT;
532542

@@ -536,13 +546,11 @@ CREATE FUNCTION replace_usual_part_with_foreign(part partitions)
536546
RETURNS void AS $$
537547
DECLARE
538548
connstring text;
539-
fdw_part_name text;
540-
server_name text;
549+
fdw_part_name text := shardman.get_fdw_part_name(part.part_name);
550+
server_name text := 'node_' || part.owner;
541551
BEGIN
542-
server_name := 'node_'||part.owner;
543-
PERFORM shardman.create_foreign_server(part.owner);
552+
PERFORM shardman.ensure_foreign_server(part.owner);
544553

545-
SELECT shardman.get_fdw_part_name(part.part_name) INTO fdw_part_name;
546554
EXECUTE format('DROP FOREIGN TABLE IF EXISTS %I;', fdw_part_name);
547555

548556
-- Generate and execute CREATE FOREIGN TABLE sql statement which will

0 commit comments

Comments
 (0)