Reputation: 802
There is a refresh materialized concurrently that takes several hours to run. One of the users regularly has to truncate one of the tables that the materialized view uses. This table is also used in multiple projects so other users run selects on it
Problem is that this truncate stays locked until the refresh finishes, and anyone selecting the table then gets completely stuck and then the database gets jammed. I've instructed the user to only do this truncate at a specific time but he did not listen
How to create a trigger that prevents the user from doing this truncate? Something along the lines
create trigger before truncate on table for each row execute function stoptruncate()
CREATE OR REPLACE FUNCTION stoptruncate()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
if truncate = true and if 'the refresh query is running'
then raise exception 'cannot run truncate while background refresh is running';
end if;
RETURN NEW;
END;
$function$
;
Upvotes: 0
Views: 280
Reputation: 247235
A trigger comes too late to do anything about that. The trigger function is called after the table lock has been granted.
You could keep the user from waiting forever by setting a low default value for lock_timeout
for that user:
ALTER ROLE trunc_user SET lock_timeout = '200ms';
Upvotes: 1