MP090WARNINGFree
warn-trigger-on-hot-table
What It Detects
CREATE TRIGGER ... FOR EACH ROW locks out writes to add code that then runs on every row written.
Why It's Dangerous
Creating the trigger takes a SHARE ROW EXCLUSIVE lock, so reads continue but writes queue. The cost that lasts is the body: a row-level trigger runs once per affected row inside the transaction doing the writing, so from this migration onward the function sits on the critical path of every INSERT, UPDATE and DELETE on the table. A function that takes a millisecond is invisible on single-row writes and adds ten seconds to a 10,000-row UPDATE — ten seconds of extra lock-holding, not just extra runtime.
Bad Example
CREATE TRIGGER audit_users AFTER INSERT OR UPDATE OR DELETE ON users FOR EACH ROW EXECUTE FUNCTION write_audit_log(); -- Now part of every write to users, forever
Good Example
-- A statement-level trigger with transition tables does the same work -- once per statement instead of once per row. CREATE TRIGGER audit_users AFTER UPDATE ON users REFERENCING NEW TABLE AS changed FOR EACH STATEMENT EXECUTE FUNCTION write_audit_log();
Configuration
Disable this rule:
# .migrationpilotrc.yml rules: MP090: false
Or change its severity:
# .migrationpilotrc.yml
rules:
MP090:
severity: warning