@@ -245,8 +245,10 @@ DECLARE
245
245
pubs text = ' ' ;
246
246
subs text = ' ' ;
247
247
fdws text = ' ' ;
248
+ prts text = ' ' ;
248
249
sync text = ' ' ;
249
250
conf text = ' ' ;
251
+ alts text = ' ' ;
250
252
fdw_part_name text ;
251
253
new_master_id int ;
252
254
sync_standbys text [];
@@ -278,13 +280,20 @@ BEGIN
278
280
LOOP
279
281
-- Drop publication and subscriptions for replicas
280
282
pubs := format(' %s%s:DROP PUBLICATION node_%s;
281
- %s:DROP PUBLICATION node_%s;' ,
283
+ %s:DROP PUBLICATION node_%s;
284
+ %s:SELECT pg_drop_replication_slot(' ' node_%s' ' );
285
+ %s:SELECT pg_drop_replication_slot(' ' node_%s' ' );' ,
282
286
pubs, node .id , rm_node_id,
283
- rm_node_id, node .id );
287
+ rm_node_id, node .id ,
288
+ node .id , rm_node_id,
289
+ rm_node_id, node .id );
290
+ alts := format(' %s{%s:ALTER SUBSCRIPTION sub_%s_%s DISABLE;ALTER SUBSCRIPTION sub_%s_%s SET (slot_name=NONE)}{%s:ALTER SUBSCRIPTION sub_%s_%s DISABLE;ALTER SUBSCRIPTION sub_%s_%s SET (slot_name=NONE)}' ,
291
+ alts, rm_node_id, rm_node_id, node .id , rm_node_id, node .id ,
292
+ node .id , node .id , rm_node_id, node .id , rm_node_id);
284
293
subs := format(' %s%s:DROP SUBSCRIPTION sub_%s_%s;
285
- %s:DROP SUBSCRIPTION sub_%s_%s' ,
294
+ %s:DROP SUBSCRIPTION sub_%s_%s; ' ,
286
295
subs, rm_node_id, rm_node_id, node .id ,
287
- node .id , node .id , rm_node_id);
296
+ node .id , node .id , rm_node_id);
288
297
289
298
-- Construct new synchronous standby list
290
299
sync_standbys :=
@@ -301,27 +310,40 @@ BEGIN
301
310
-- Drop shared tables subscriptions
302
311
FOR master_node_id IN SELECT DISTINCT master_node from shardman .tables WHERE master_node IS NOT NULL
303
312
LOOP
313
+ alts := format(' %s{%s:ALTER SUBSCRIPTION share_%s_%s DISABLE;ALTER SUBSCRIPTION share_%s_%s SET (slot_name=NONE)}' ,
314
+ alts, rm_node_id, rm_node_id, master_node_id, rm_node_id, master_node_id);
304
315
subs := format(' %s%s:DROP SUBSCRIPTION share_%s_%s;' ,
305
316
subs, rm_node_id, rm_node_id, master_node_id);
317
+ pubs := format(' %s%s:SELECT pg_drop_replication_slot(' ' share_%s_%s' ' );' ,
318
+ pubs, master_node_id, rm_node_id, master_node_id);
306
319
END LOOP;
307
320
321
+ -- Broadcast alter subscription commands, ignore errors because removed node may be not available
322
+ PERFORM shardman .broadcast (alts,
323
+ ignore_errors => true,
324
+ super_connstr => true);
308
325
-- Broadcast drop subscription commands, ignore errors because removed node may be not available
309
- PERFORM shardman .broadcast (subs, ignore_errors:= true, sync_commit_on => true,
310
- super_connst => true);
311
- -- Broadcast drop replication commands
312
- PERFORM shardman .broadcast (pubs, ignore_errors:= true, super_connstr => true);
326
+ PERFORM shardman .broadcast (subs,
327
+ ignore_errors => true,
328
+ super_connstr => true);
329
+
330
+ -- Broadcast drop replication commands
331
+ PERFORM shardman .broadcast (pubs, ignore_errors => true, super_connstr => true);
313
332
314
333
-- In case of synchronous replication update synchronous standbys list
315
334
IF shardman .synchronous_replication ()
316
335
THEN
317
336
-- On removed node, reset synchronous standbys list
318
337
sync := format(' %s%s:ALTER SYSTEM SET synchronous_standby_names to ' ' ' ' ;' ,
319
338
sync, rm_node_id, sync_standbys);
320
- PERFORM shardman .broadcast (sync, ignore_errors => true,
321
- sync_commit_on => true, super_connstr => true);
339
+ PERFORM shardman .broadcast (sync,
340
+ ignore_errors => true,
341
+ sync_commit_on => true,
342
+ super_connstr => true);
322
343
PERFORM shardman .broadcast (conf, ignore_errors:= true, super_connstr => true);
323
344
END IF;
324
-
345
+ /* To correctly remove foreign servers we need to update pf_depend table, otherwise
346
+ * our hack with direct update pg_foreign_table leaves deteriorated dependencies
325
347
-- Remove foreign servers at all nodes for the removed node
326
348
FOR node IN SELECT * FROM shardman.nodes WHERE id<>rm_node_id
327
349
LOOP
@@ -330,14 +352,14 @@ BEGIN
330
352
%s:DROP SERVER node_%s;',
331
353
fdws, node.id, rm_node_id,
332
354
rm_node_id, node.id);
355
+ drps := format('%s%s:DROP USER MAPPING FOR CURRENT_USER SERVER node_%s;
356
+ %s:DROP USER MAPPING FOR CURRENT_USER SERVER node_%s;',
357
+ drps, node.id, rm_node_id,
358
+ rm_node_id, node.id);
333
359
END LOOP;
334
-
335
- -- Broadcast drop server commands
336
- PERFORM shardman .broadcast (fdws, ignore_errors:= true);
337
- fdws := ' ' ;
338
-
360
+ */
339
361
-- Exclude partitions of removed node
340
- FOR part in SELECT * from shardman .partitions where node = rm_node_id
362
+ FOR part in SELECT * from shardman .partitions where node_id = rm_node_id
341
363
LOOP
342
364
-- Is there some replica of this node?
343
365
SELECT node_id INTO new_master_id FROM shardman .replicas WHERE part_name= part .part_name ORDER BY random() LIMIT 1 ;
@@ -346,7 +368,7 @@ BEGIN
346
368
-- Update partitions table: now replica is promoted to master...
347
369
UPDATE shardman .partitions SET node_id= new_master_id WHERE part_name= part .part_name ;
348
370
-- ... and is not a replica any more
349
- DELETE FROM sharaman .replicas WHERE part_name= part .part_name AND node_id= new_master_id;
371
+ DELETE FROM shardman .replicas WHERE part_name= part .part_name AND node_id= new_master_id;
350
372
351
373
pubs := ' ' ;
352
374
subs := ' ' ;
@@ -376,19 +398,23 @@ BEGIN
376
398
fdw_part_name := format(' %s_fdw' , part .part_name );
377
399
IF node .id = new_master_id THEN
378
400
-- At new master node replace foreign link with local partition
379
- fdws := format(' %s%d:SELECT replace_hash_partition(%L,%L);' ,
380
- fdws, node .id , fdw_part_name, part .part_name );
401
+ prts := format(' %s%s:SELECT replace_hash_partition(%L,%L);' ,
402
+ prts, node .id , fdw_part_name, part .part_name );
403
+ fdws := format(' %s%s:DROP FOREIGN TABLE %I;' ,
404
+ fdws, node .id , fdw_part_name);
381
405
ELSE
382
406
-- At all other nodes adjust foreign server for foreign table to refer to new master node.
383
407
-- It is not possible to alter foreign server for foreign table so we have to do it in such "hackers" way:
384
- fdws := 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);' ,
385
- fdws , node .id , new_master_id, fdw_part_name);
408
+ prts := 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);' ,
409
+ prts , node .id , new_master_id, fdw_part_name);
386
410
END IF;
387
411
END LOOP;
388
412
END LOOP;
389
413
390
414
-- Broadcast changes of pathman mapping
391
- PERFORM shardman .broadcast (fdws, ignore_errors:= true);
415
+ PERFORM shardman .broadcast (prts, ignore_errors:= true);
416
+ -- Broadcast drop server commands
417
+ PERFORM shardman .broadcast (fdws, ignore_errors:= true);
392
418
393
419
-- Finally delete node from nodes table and all dependent tables
394
420
DELETE from shardman .nodes WHERE id= rm_node_id;
0 commit comments