Change trigger type to AFTER trigger.

During repacking table, if a transaction executes INSERT CONFLICT
ON UPDATE/DO NOTHING, because we define BEFORE trigger on target
table, the contents of operation log table becomes inconsistent
easliy. As a result, pg_reapck fails with a high probability.

To resolve this issue, this changes the trigger type from BEFORE
to AFTER. We define AFTER trigger that is the first of the AFTER
trigger to fire on the table.
This commit is contained in:
Masahiko Sawada
2017-01-19 13:47:18 +09:00
parent e1056c003c
commit d83ee3d6a0
7 changed files with 43 additions and 43 deletions

View File

@ -68,8 +68,8 @@ LANGUAGE sql STABLE STRICT;
CREATE FUNCTION repack.get_create_trigger(relid oid, pkid oid)
RETURNS text AS
$$
SELECT 'CREATE TRIGGER z_repack_trigger' ||
' BEFORE INSERT OR DELETE OR UPDATE ON ' || repack.oid2text($1) ||
SELECT 'CREATE TRIGGER a_repack_trigger' ||
' AFTER INSERT OR DELETE OR UPDATE ON ' || repack.oid2text($1) ||
' FOR EACH ROW EXECUTE PROCEDURE repack.repack_trigger(' ||
'''INSERT INTO repack.log_' || $1 || '(pk, row) VALUES(' ||
' CASE WHEN $1 IS NULL THEN NULL ELSE (ROW($1.' ||
@ -82,7 +82,7 @@ CREATE FUNCTION repack.get_enable_trigger(relid oid)
RETURNS text AS
$$
SELECT 'ALTER TABLE ' || repack.oid2text($1) ||
' ENABLE ALWAYS TRIGGER z_repack_trigger';
' ENABLE ALWAYS TRIGGER a_repack_trigger';
$$
LANGUAGE sql STABLE STRICT;
@ -223,8 +223,8 @@ LANGUAGE C VOLATILE STRICT SECURITY DEFINER;
CREATE FUNCTION repack.conflicted_triggers(oid) RETURNS SETOF name AS
$$
SELECT tgname FROM pg_trigger
WHERE tgrelid = $1 AND tgname >= 'z_repack_trigger'
AND (tgtype & 2) = 2 -- BEFORE trigger
WHERE tgrelid = $1 AND tgname <= 'a_repack_trigger'
AND (tgtype & 2) = 0 -- AFTER trigger
ORDER BY tgname;
$$
LANGUAGE sql STABLE STRICT;