@@ -251,6 +251,81 @@ CREATE TRIGGER part_moved AFTER UPDATE ON shardman.partitions
251
251
-- fire trigger only on worker nodes
252
252
ALTER TABLE shardman .partitions ENABLE REPLICA TRIGGER part_moved;
253
253
254
+
255
+ -- Partition removed: drop old LR channels.
256
+ CREATE FUNCTION part_removed () RETURNS TRIGGER AS $$
257
+ DECLARE
258
+ me int := shardman .my_id ();
259
+ prev_src_lname text ;
260
+ src_next_lname text ;
261
+ new_primary partitions;
262
+ drop_slot_delay int := 2000 ; -- two seconds
263
+ BEGIN
264
+ RAISE DEBUG ' [SHMN] part_removed trigger called for part %, owner %' ,
265
+ OLD .part_name , OLD .owner ;
266
+
267
+ IF OLD .prv IS NOT NULL THEN
268
+ prev_src_lname := shardman .get_data_lname (OLD .part_name , OLD .prv , OLD .owner );
269
+ ELSE
270
+ select * from shardman .partitions where owner= OLD .nxt and part_name= OLD .part_name into new_primary;
271
+ END IF;
272
+ IF OLD .nxt IS NOT NULL THEN
273
+ src_next_lname := shardman .get_data_lname (OLD .part_name , OLD .owner , OLD .nxt );
274
+ END IF;
275
+
276
+
277
+ IF me = OLD .owner THEN -- src node
278
+ -- If primary part was moved, replace on src node its partition with
279
+ -- foreign one
280
+ IF OLD .prv IS NULL THEN
281
+ PERFORM shardman .replace_usual_part_with_foreign (new_primary);
282
+ ELSE
283
+ -- On the other hand, if prev replica existed, drop sub for old
284
+ -- channel prev -> src
285
+ PERFORM shardman .eliminate_sub (prev_src_lname);
286
+ END IF;
287
+ IF OLD .nxt IS NOT NULL THEN
288
+ -- If next replica existed, drop pub for old channel src -> next
289
+ -- Wait sometime to let other node first remove subscription
290
+ PERFORM pg_sleep(drop_slot_delay);
291
+ PERFORM shardman .drop_repslot_and_pub (src_next_lname);
292
+ PERFORM shardman .remove_sync_standby (src_next_lname);
293
+ END IF;
294
+ -- Drop old table anyway
295
+ -- ???? Can we really do it now? We will have FDW pointing to removed table...
296
+ EXECUTE format(' DROP TABLE IF EXISTS %I' , OLD .part_name );
297
+ ELSEIF me = OLD .prv THEN -- node with prev replica
298
+ -- Wait sometime to let other node first remove subscription
299
+ PERFORM pg_sleep(drop_slot_delay);
300
+ -- Drop pub for old channel prev -> src
301
+ PERFORM shardman .drop_repslot_and_pub (prev_src_lname);
302
+ PERFORM shardman .remove_sync_standby (prev_src_lname);
303
+ PERFORM update shardman .partitions set nxt= OLD .nxt where owner= me and part_name= OLD .part_name ;
304
+ ELSEIF me = OLD .nxt THEN -- node with next replica
305
+ -- Drop sub for old channel src -> next
306
+ PERFORM shardman .eliminate_sub (src_next_lname);
307
+ PERFORM update shardman .partitions set prv= OLD .prv where owner= me and part_name= OLD .part_name ;
308
+ END IF;
309
+
310
+ -- If primary was moved
311
+ IF OLD .prv IS NULL THEN
312
+ -- And update fdw almost everywhere
313
+ PERFORM shardman .update_fdw_server (new_primary);
314
+ END IF;
315
+
316
+ RETURN NULL ;
317
+ END
318
+ $$ LANGUAGE plpgsql;
319
+
320
+ CREATE TRIGGER part_removed AFTER REMOVE ON shardman .partitions
321
+ FOR EACH ROW
322
+ EXECUTE PROCEDURE part_removed();
323
+ -- fire trigger only on worker nodes
324
+ ALTER TABLE shardman .partitions ENABLE REPLICA TRIGGER part_removed;
325
+
326
+
327
+
328
+
254
329
-- Executed on newtail node, see cr_rebuild_lr
255
330
CREATE FUNCTION replica_created_drop_cp_sub (
256
331
part_name name, oldtail int , newtail int ) RETURNS void AS $$
0 commit comments