Files
buzz/schema/functions/events_created_at_floor_guard.sql

30 lines
1.5 KiB
PL/PgSQL

-- Replica-fence floor guard (keep in sync with migrations/0021). A deferred
-- constraint trigger re-checks, inside COMMIT processing, that channel-bearing
-- event rows are no older than `buzz.created_at_floor` seconds before commit
-- time (clock_timestamp(), NOT the transaction-frozen now()). This turns the
-- relay's ingest-time created_at envelope into a commit-time storage
-- invariant, which is what lets keyset-cursor pages below the replica fence
-- be served by a read replica without holes. Enforcement is armed per session
-- via the GUC (set by the relay's writer pool on connect); sessions without
-- the GUC (pg_restore, manual backfills) bypass it and must hold the replica
-- fence closed for their duration. The only structural exemption is
-- channel_id IS NULL: those rows never appear in keyset-paged windows.
CREATE FUNCTION events_created_at_floor_guard() RETURNS trigger
LANGUAGE plpgsql AS $$
DECLARE
floor_secs numeric := nullif(current_setting('buzz.created_at_floor', true), '')::numeric;
BEGIN
IF floor_secs IS NOT NULL
AND floor_secs > 0
AND NEW.channel_id IS NOT NULL
AND NEW.created_at < clock_timestamp() - make_interval(secs => floor_secs)
THEN
RAISE EXCEPTION
'events.created_at % is more than % s before commit time %; below the replica-fence floor',
NEW.created_at, floor_secs, clock_timestamp()
USING ERRCODE = 'check_violation';
END IF;
RETURN NULL;
END
$$;