SlideShare ist ein Scribd-Unternehmen logo
1 von 43
Downloaden Sie, um offline zu lesen
Introduction to
Triggers
Who am I?
• Jim Mlodgenski
– jimm@openscg.com
– @jim_mlodgenski
• Director
– United States PostgreSQL (www.postgresql.us)
• Co-organizer of
– Philly PUG (www.phlpug.org)
– NYC PUG (www.nycpug.org)
• CTO, OpenSCG
– www.openscg.com
Triggers
• Code that gets executed when an
event happens in the database
– INSERT, UPDATE, DELETE
• Event Triggers fire on DDL
– CREATE, DROP, ALTER
– Still not mature yet
●
(limited functionaity)
Use Cases
• Table Partitioning
• Automatically generate derived column
values
• Enforce complex constraints
• Enforce referential integrity across nodes in a
distributed database
• Provide transparent event logging
• Provide auditing
• Invalidate cache entries
Structure
● Trigger
● Trigger Function
CREATE TRIGGER foo_trg
BEFORE UPDATE ON foo
FOR EACH ROW
EXECUTE PROCEDURE
foo_update();
Trigger Events
● Insert
● Update
● Delete
● Truncate
Trigger Timing
● Before
– The trigger is fired before the change is made
to the table
● After
– The trigger is fired after the change is made to
the table
Trigger Frequency
● For Each Row
– The trigger is fired once each time a row is
affected
● For Each Statement
– The trigger is fired once each time a statement
is executed
Trigger Overhead
CREATE UNLOGGED TABLE trigger_test (
key serial primary key,
value varchar,
insert_ts timestamp,
update_ts timestamp
);
INSERT INTO trigger_test (value) VALUES
(‘hello’);
set keys :scale
setrandom key 1 :keys
UPDATE trigger_test SET value = 'HELLO' WHERE
key = :key;
Trigger Overhead
pgbench -n -t 100000
-f INSERTS.pgbench postgres
pgbench -n -s 100000 -t 10000
-f UPDATES.pgbench postgres
Inserts: 4510 tps
Updates: 4349 tps
Trigger Overhead
CREATE FUNCTION empty_trigger()
RETURNS trigger AS $$
BEGIN
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER empty_trigger BEFORE
INSERT OR UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE
empty_trigger();
Trigger Overhead
pgbench -n -t 100000
-f INSERTS.pgbench postgres
pgbench -n -s 100000 -t 10000
-f UPDATES.pgbench postgres
Inserts: 4296 tps (4.8% overhead)
Updates: 3988 tps (8.3% overhead)
Trigger Arguments
● NEW
– Variable holding the new row for
INSERT/UPDATE operations in row-level triggers
● OLD
– Variable holding the old row for UPDATE/DELETE
operations in row-level triggers
NEW vs OLD
CREATE TABLE audit (
event_time timestamp NOT NULL,
user_name varchar NOT NULL,
old_row json,
new_row json
);
NEW vs OLD (cont.)
CREATE OR REPLACE FUNCTION audit_trigger()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit
VALUES (CURRENT_TIMESTAMP,
CURRENT_USER,
row_to_json(OLD),
row_to_json(NEW));
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
NEW vs OLD (cont.)
CREATE TRIGGER audit_trigger
AFTER UPDATE ON pgbench_branches
FOR EACH ROW
EXECUTE PROCEDURE audit_trigger();
Trigger Arguments (cont.)
● TG_OP
– A string of INSERT, UPDATE, DELETE, or TRUNCATE
telling for which operation the trigger was fired
● TG_NAME
– Variable that contains the name of the trigger actually
fired
● TG_WHEN
– A string of BEFORE, AFTER, or INSTEAD OF, depending
on the trigger's definition
● TG_LEVEL
– A string of either ROW or STATEMENT depending on the
trigger's definition
TG_OP
CREATE TABLE audit (
event_time timestamp NOT NULL,
user_name varchar NOT NULL,
operation varchar NOT NULL,
old_row json,
new_row json
);
TG_OP (cont.)
CREATE OR REPLACE FUNCTION audit_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO audit
VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP,
row_to_json(OLD), null);
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO audit
VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP,
row_to_json(OLD), row_to_json(NEW));
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO audit
VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP,
null, row_to_json(NEW));
RETURN NEW;
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
TG_OP (cont.)
CREATE TRIGGER audit_trigger
AFTER UPDATE OR INSERT OR DELETE
ON pgbench_branches
FOR EACH ROW
EXECUTE PROCEDURE audit_trigger();
Trigger Arguments (cont.)
● TG_TABLE_NAME
– The name of the table that caused the trigger
invocation.
● TG_RELNAME
– The name of the table that caused the trigger
invocation
● TG_RELID
– The object ID of the table that caused the trigger
invocation
● TG_TABLE_SCHEMA
– The name of the schema of the table that caused the
trigger invocation
TG_TABLE_NAME
CREATE TABLE audit (
event_time timestamp NOT NULL,
user_name varchar NOT NULL,
operation varchar NOT NULL,
table_name varchar NOT NULL,
old_row json,
new_row json
);
TG_TABLE_NAME (cont.)
CREATE OR REPLACE FUNCTION audit_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO audit
VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP,
TG_TABLE_NAME, row_to_json(OLD), null);
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO audit
VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP,
TG_TABLE_NAME, row_to_json(OLD), row_to_json(NEW));
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO audit
VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP,
TG_TABLE_NAME, null, row_to_json(NEW));
RETURN NEW;
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
TG_TABLE_NAME (cont.)
CREATE TRIGGER audit_trigger
AFTER UPDATE OR INSERT OR DELETE
ON pgbench_branches
FOR EACH ROW
EXECUTE PROCEDURE audit_trigger();
CREATE TRIGGER audit_trigger
AFTER UPDATE OR INSERT OR DELETE
ON pgbench_tellers
FOR EACH ROW
EXECUTE PROCEDURE audit_trigger();
Trigger Arguments (cont.)
● TG_NARGS
– The number of arguments given to the trigger
procedure in the CREATE TRIGGER statement
● TG_ARGV[]
– The arguments from the CREATE TRIGGER
statement
Trigger Use Cases
● Table Partitioning
– Splitting what is logically one large table into
smaller physical pieces
– Used to:
● Increase performance
● Archive data
● Storage tiering
Table Partitioning
CREATE TABLE audit_2014 (
CHECK ( event_time >= DATE '2014-01-01'
AND event_time < DATE '2015-01-01')
) INHERITS (audit);
CREATE TABLE audit_2015 (
CHECK ( event_time >= DATE '2015-01-01'
AND event_time < DATE '2016-01-01')
) INHERITS (audit);
Table Partitioning (cont.)
CREATE OR REPLACE FUNCTION partition_audit_trigger()
RETURNS TRIGGER AS $$
BEGIN
EXECUTE 'INSERT INTO audit_' ||
to_char(NEW.event_time, 'YYYY') ||
' VALUES ($1, $2, $3, $4, $5, $6)'
USING NEW.event_time, NEW.user_name, NEW.operation,
NEW.table_name, NEW.old_row, NEW.new_row;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Table Partitioning (cont.)
CREATE TRIGGER partition_audit_trigger
BEFORE INSERT ON audit
FOR EACH ROW
EXECUTE PROCEDURE
partition_audit_trigger();
Partitioning Performance
CREATE OR REPLACE FUNCTION partition_audit_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.event_time >= DATE '2015-01-01' AND
NEW.event_time < DATE '2016-01-01' ) THEN
INSERT INTO audit_2015 VALUES (NEW.*);
ELSIF ( NEW.event_time >= DATE '2014-01-01' AND
NEW.event_time < DATE '2015-01-01' ) THEN
INSERT INTO audit_2014 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Date out of range. Fix
partition_audit_trigger() function!';
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Moving Partitions
CREATE TRIGGER move_partition_audit_trigger
BEFORE UPDATE
ON audit_2014
FOR EACH ROW EXECUTE PROCEDURE
move_partition_audit_trigger('2014-01-01', '2015-01-01');
CREATE TRIGGER move_partition_audit_trigger
BEFORE UPDATE
ON audit_2015
FOR EACH ROW EXECUTE PROCEDURE
move_partition_audit_trigger('2015-01-01', '2016-01-01');
Moving Partitions (cont.)
CREATE OR REPLACE FUNCTION move_partition_audit_trigger()
RETURNS TRIGGER AS $$
DECLARE
start_date DATE;
end_date DATE;
BEGIN
start_date := TG_ARGV[0];
end_date := TG_ARGV[1];
IF ( NEW.event_time IS DISTINCT FROM OLD.event_time ) THEN
IF (NEW.event_time < start_date OR NEW.event_time >= end_date) THEN
EXECUTE 'DELETE FROM ' || TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME ||
' WHERE ctid = $1'
USING OLD.ctid;
INSERT INTO audit VALUES (NEW.*);
RETURN null;
END IF;
END IF;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
Moving Partitions (cont.)
CREATE TRIGGER move_partition_audit_trigger
BEFORE UPDATE
ON audit_2014
FOR EACH ROW
WHEN (NEW.event_time IS DISTINCT FROM OLD.event_time)
EXECUTE PROCEDURE
move_partition_audit_trigger('2014-01-01', '2015-01-01');
CREATE TRIGGER move_partition_audit_trigger
BEFORE UPDATE
ON audit_2015
FOR EACH ROW
WHEN (NEW.event_time IS DISTINCT FROM OLD.event_time)
EXECUTE PROCEDURE
move_partition_audit_trigger('2015-01-01', '2016-01-01');
Trigger Use Cases
● Calculate columns
– Calculate complex values
– Extract values from complex structures
– Used to:
● Increase performance
● Simplify queries
Extract JSON
$ head -n 5 zips.json
{ "_id" : "01001", "city" : "AGAWAM",
"loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" }
{ "_id" : "01002", "city" : "CUSHMAN",
"loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }
{ "_id" : "01005", "city" : "BARRE",
"loc" : [ -72.10835400000001, 42.409698 ], "pop" : 4546, "state" : "MA" }
{ "_id" : "01007", "city" : "BELCHERTOWN",
"loc" : [ -72.41095300000001, 42.275103 ], "pop" : 10579, "state" : "MA" }
{ "_id" : "01008", "city" : "BLANDFORD",
"loc" : [ -72.936114, 42.182949 ], "pop" : 1240, "state" : "MA" }
CREATE TABLE zips (
zip_code varchar PRIMARY KEY,
state varchar,
data json
);
Extract JSON
CREATE OR REPLACE FUNCTION extract_data_trigger()
RETURNS TRIGGER AS $$
BEGIN
NEW.zip_code := NEW.data->>'_id';
NEW.state := NEW.data->>'state';
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER extract_data_trigger
BEFORE UPDATE OR INSERT
ON zips
FOR EACH ROW EXECUTE PROCEDURE extract_data_trigger();
Trigger Use Cases
● Cache invalidation
– Remove stale entries from a cache
– The database tracks all data so is the single
source of truth
– Used to:
● Simplify cache management
● Remove application complexity
Note: Foreign Data Wrappers simplify this
process significantly
Cache Invalidation
CREATE TABLE users (
id serial PRIMARY KEY,
first_name varchar,
last_name varchar,
email_address varchar NOT NULL,
password_md5 varchar NOT NULL
);
CREATE OR REPLACE FUNCTION remove_cache_trigger()
RETURNS TRIGGER AS $$
BEGIN
DELETE from myredis_cache
WHERE key = OLD.id::varchar;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER remove_cache_trigger
AFTER UPDATE OR DELETE
ON users
FOR EACH ROW EXECUTE PROCEDURE remove_cache_trigger();
Cache Invalidation - Async
CREATE OR REPLACE FUNCTION remove_cache_trigger()
RETURNS TRIGGER AS $$
BEGIN
PERFORM pg_notify(TG_TABLE_NAME, OLD.id::varchar);
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
Things to Remember
● Triggers are part of the parent
transaction
– The trigger fails, the main transaction fails
– If the trigger takes a long time, the whole
transaction timing is affected
● Triggers can be difficult to debug
– Especially cascaded triggers
Trigger Function Language
Questions?

Weitere ähnliche Inhalte

Was ist angesagt?

Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...Altinity Ltd
 
Introduction to Elasticsearch with basics of Lucene
Introduction to Elasticsearch with basics of LuceneIntroduction to Elasticsearch with basics of Lucene
Introduction to Elasticsearch with basics of LuceneRahul Jain
 
ClickHouse tips and tricks. Webinar slides. By Robert Hodges, Altinity CEO
ClickHouse tips and tricks. Webinar slides. By Robert Hodges, Altinity CEOClickHouse tips and tricks. Webinar slides. By Robert Hodges, Altinity CEO
ClickHouse tips and tricks. Webinar slides. By Robert Hodges, Altinity CEOAltinity Ltd
 
Introduction to PostgreSQL
Introduction to PostgreSQLIntroduction to PostgreSQL
Introduction to PostgreSQLJim Mlodgenski
 
Your first ClickHouse data warehouse
Your first ClickHouse data warehouseYour first ClickHouse data warehouse
Your first ClickHouse data warehouseAltinity Ltd
 
cstore_fdw: Columnar Storage for PostgreSQL
cstore_fdw: Columnar Storage for PostgreSQLcstore_fdw: Columnar Storage for PostgreSQL
cstore_fdw: Columnar Storage for PostgreSQLCitus Data
 
Patroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyPatroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyAlexander Kukushkin
 
PostgreSQL_ Up and Running_ A Practical Guide to the Advanced Open Source Dat...
PostgreSQL_ Up and Running_ A Practical Guide to the Advanced Open Source Dat...PostgreSQL_ Up and Running_ A Practical Guide to the Advanced Open Source Dat...
PostgreSQL_ Up and Running_ A Practical Guide to the Advanced Open Source Dat...MinhLeNguyenAnh2
 
Indexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuningIndexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuningOSSCube
 
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdfDeep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdfAltinity Ltd
 
Oracle Advanced SQL and Analytic Functions
Oracle Advanced SQL and Analytic FunctionsOracle Advanced SQL and Analytic Functions
Oracle Advanced SQL and Analytic FunctionsZohar Elkayam
 
PostgreSQL HA
PostgreSQL   HAPostgreSQL   HA
PostgreSQL HAharoonm
 

Was ist angesagt? (20)

Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
Webinar slides: MORE secrets of ClickHouse Query Performance. By Robert Hodge...
 
Introduction to Elasticsearch with basics of Lucene
Introduction to Elasticsearch with basics of LuceneIntroduction to Elasticsearch with basics of Lucene
Introduction to Elasticsearch with basics of Lucene
 
ClickHouse tips and tricks. Webinar slides. By Robert Hodges, Altinity CEO
ClickHouse tips and tricks. Webinar slides. By Robert Hodges, Altinity CEOClickHouse tips and tricks. Webinar slides. By Robert Hodges, Altinity CEO
ClickHouse tips and tricks. Webinar slides. By Robert Hodges, Altinity CEO
 
Introduction to PostgreSQL
Introduction to PostgreSQLIntroduction to PostgreSQL
Introduction to PostgreSQL
 
Your first ClickHouse data warehouse
Your first ClickHouse data warehouseYour first ClickHouse data warehouse
Your first ClickHouse data warehouse
 
cstore_fdw: Columnar Storage for PostgreSQL
cstore_fdw: Columnar Storage for PostgreSQLcstore_fdw: Columnar Storage for PostgreSQL
cstore_fdw: Columnar Storage for PostgreSQL
 
Patroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyPatroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easy
 
PostgreSQL_ Up and Running_ A Practical Guide to the Advanced Open Source Dat...
PostgreSQL_ Up and Running_ A Practical Guide to the Advanced Open Source Dat...PostgreSQL_ Up and Running_ A Practical Guide to the Advanced Open Source Dat...
PostgreSQL_ Up and Running_ A Practical Guide to the Advanced Open Source Dat...
 
SQL JOINS
SQL JOINSSQL JOINS
SQL JOINS
 
Dictionary
DictionaryDictionary
Dictionary
 
SQL Join Basic
SQL Join BasicSQL Join Basic
SQL Join Basic
 
Trigger
TriggerTrigger
Trigger
 
Indexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuningIndexing the MySQL Index: Key to performance tuning
Indexing the MySQL Index: Key to performance tuning
 
PostgreSQL: Advanced indexing
PostgreSQL: Advanced indexingPostgreSQL: Advanced indexing
PostgreSQL: Advanced indexing
 
Postgresql
PostgresqlPostgresql
Postgresql
 
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdfDeep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
 
PostgreSQL
PostgreSQLPostgreSQL
PostgreSQL
 
Oracle Advanced SQL and Analytic Functions
Oracle Advanced SQL and Analytic FunctionsOracle Advanced SQL and Analytic Functions
Oracle Advanced SQL and Analytic Functions
 
Introduction to SQL
Introduction to SQLIntroduction to SQL
Introduction to SQL
 
PostgreSQL HA
PostgreSQL   HAPostgreSQL   HA
PostgreSQL HA
 

Ähnlich wie An Introduction To PostgreSQL Triggers

Advanced Postgres Monitoring
Advanced Postgres MonitoringAdvanced Postgres Monitoring
Advanced Postgres MonitoringDenish Patel
 
Oracle - Program with PL/SQL - Lession 17
Oracle - Program with PL/SQL - Lession 17Oracle - Program with PL/SQL - Lession 17
Oracle - Program with PL/SQL - Lession 17Thuan Nguyen
 
Keith Fiske - When PostgreSQL Can't, You Can @ Postgres Open
Keith Fiske - When PostgreSQL Can't, You Can @ Postgres OpenKeith Fiske - When PostgreSQL Can't, You Can @ Postgres Open
Keith Fiske - When PostgreSQL Can't, You Can @ Postgres OpenPostgresOpen
 
Major features postgres 11
Major features postgres 11Major features postgres 11
Major features postgres 11EDB
 
Procedures and triggers in SQL
Procedures and triggers in SQLProcedures and triggers in SQL
Procedures and triggers in SQLVikash Sharma
 
prohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracle
prohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracleprohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracle
prohuddle-utPLSQL v3 - Ultimate unit testing framework for OracleJacek Gebal
 
PostgreSQL 9.5 Features
PostgreSQL 9.5 FeaturesPostgreSQL 9.5 Features
PostgreSQL 9.5 FeaturesSaiful
 
Oracle trigger
Oracle triggerOracle trigger
Oracle triggernasrul28
 
Function Procedure Trigger Partition.pdf
Function Procedure Trigger Partition.pdfFunction Procedure Trigger Partition.pdf
Function Procedure Trigger Partition.pdfSanam Maharjan
 
Tony jambu (obscure) tools of the trade for tuning oracle sq ls
Tony jambu   (obscure) tools of the trade for tuning oracle sq lsTony jambu   (obscure) tools of the trade for tuning oracle sq ls
Tony jambu (obscure) tools of the trade for tuning oracle sq lsInSync Conference
 
Database Automation with MySQL Triggers and Event Schedulers
Database Automation with MySQL Triggers and Event SchedulersDatabase Automation with MySQL Triggers and Event Schedulers
Database Automation with MySQL Triggers and Event SchedulersAbdul Rahman Sherzad
 
Changing your huge table's data types in production
Changing your huge table's data types in productionChanging your huge table's data types in production
Changing your huge table's data types in productionJimmy Angelakos
 
Oracle_Audit_APEX IOUG Collaborate 14
Oracle_Audit_APEX IOUG Collaborate 14Oracle_Audit_APEX IOUG Collaborate 14
Oracle_Audit_APEX IOUG Collaborate 14Leon Rzhemovskiy
 
Below is the question I need help with. It need to be done in Java. .pdf
Below is the question I need help with. It need to be done in Java. .pdfBelow is the question I need help with. It need to be done in Java. .pdf
Below is the question I need help with. It need to be done in Java. .pdfaroraenterprisesmbd
 
T sql denali code Day of .Net
T sql denali code Day of .NetT sql denali code Day of .Net
T sql denali code Day of .NetKathiK58
 
Basic Query Tuning Primer - Pg West 2009
Basic Query Tuning Primer - Pg West 2009Basic Query Tuning Primer - Pg West 2009
Basic Query Tuning Primer - Pg West 2009mattsmiley
 

Ähnlich wie An Introduction To PostgreSQL Triggers (20)

Advanced Postgres Monitoring
Advanced Postgres MonitoringAdvanced Postgres Monitoring
Advanced Postgres Monitoring
 
Unit 4
Unit 4Unit 4
Unit 4
 
Oracle - Program with PL/SQL - Lession 17
Oracle - Program with PL/SQL - Lession 17Oracle - Program with PL/SQL - Lession 17
Oracle - Program with PL/SQL - Lession 17
 
Keith Fiske - When PostgreSQL Can't, You Can @ Postgres Open
Keith Fiske - When PostgreSQL Can't, You Can @ Postgres OpenKeith Fiske - When PostgreSQL Can't, You Can @ Postgres Open
Keith Fiske - When PostgreSQL Can't, You Can @ Postgres Open
 
Major features postgres 11
Major features postgres 11Major features postgres 11
Major features postgres 11
 
Procedures and triggers in SQL
Procedures and triggers in SQLProcedures and triggers in SQL
Procedures and triggers in SQL
 
prohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracle
prohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracleprohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracle
prohuddle-utPLSQL v3 - Ultimate unit testing framework for Oracle
 
PostgreSQL 9.5 Features
PostgreSQL 9.5 FeaturesPostgreSQL 9.5 Features
PostgreSQL 9.5 Features
 
Oracle trigger
Oracle triggerOracle trigger
Oracle trigger
 
Function Procedure Trigger Partition.pdf
Function Procedure Trigger Partition.pdfFunction Procedure Trigger Partition.pdf
Function Procedure Trigger Partition.pdf
 
Tony jambu (obscure) tools of the trade for tuning oracle sq ls
Tony jambu   (obscure) tools of the trade for tuning oracle sq lsTony jambu   (obscure) tools of the trade for tuning oracle sq ls
Tony jambu (obscure) tools of the trade for tuning oracle sq ls
 
Database Automation with MySQL Triggers and Event Schedulers
Database Automation with MySQL Triggers and Event SchedulersDatabase Automation with MySQL Triggers and Event Schedulers
Database Automation with MySQL Triggers and Event Schedulers
 
Changing your huge table's data types in production
Changing your huge table's data types in productionChanging your huge table's data types in production
Changing your huge table's data types in production
 
Oracle_Audit_APEX IOUG Collaborate 14
Oracle_Audit_APEX IOUG Collaborate 14Oracle_Audit_APEX IOUG Collaborate 14
Oracle_Audit_APEX IOUG Collaborate 14
 
Triggers
TriggersTriggers
Triggers
 
Below is the question I need help with. It need to be done in Java. .pdf
Below is the question I need help with. It need to be done in Java. .pdfBelow is the question I need help with. It need to be done in Java. .pdf
Below is the question I need help with. It need to be done in Java. .pdf
 
T sql denali code Day of .Net
T sql denali code Day of .NetT sql denali code Day of .Net
T sql denali code Day of .Net
 
Basic Query Tuning Primer
Basic Query Tuning PrimerBasic Query Tuning Primer
Basic Query Tuning Primer
 
Basic Query Tuning Primer - Pg West 2009
Basic Query Tuning Primer - Pg West 2009Basic Query Tuning Primer - Pg West 2009
Basic Query Tuning Primer - Pg West 2009
 
Good Tests Bad Tests
Good Tests Bad TestsGood Tests Bad Tests
Good Tests Bad Tests
 

Mehr von Jim Mlodgenski

Top 10 Mistakes When Migrating From Oracle to PostgreSQL
Top 10 Mistakes When Migrating From Oracle to PostgreSQLTop 10 Mistakes When Migrating From Oracle to PostgreSQL
Top 10 Mistakes When Migrating From Oracle to PostgreSQLJim Mlodgenski
 
Oracle postgre sql-mirgration-top-10-mistakes
Oracle postgre sql-mirgration-top-10-mistakesOracle postgre sql-mirgration-top-10-mistakes
Oracle postgre sql-mirgration-top-10-mistakesJim Mlodgenski
 
Debugging Your PL/pgSQL Code
Debugging Your PL/pgSQL CodeDebugging Your PL/pgSQL Code
Debugging Your PL/pgSQL CodeJim Mlodgenski
 
PostgreSQL Procedural Languages: Tips, Tricks and Gotchas
PostgreSQL Procedural Languages: Tips, Tricks and GotchasPostgreSQL Procedural Languages: Tips, Tricks and Gotchas
PostgreSQL Procedural Languages: Tips, Tricks and GotchasJim Mlodgenski
 
Leveraging Hadoop in your PostgreSQL Environment
Leveraging Hadoop in your PostgreSQL EnvironmentLeveraging Hadoop in your PostgreSQL Environment
Leveraging Hadoop in your PostgreSQL EnvironmentJim Mlodgenski
 
Scaling PostreSQL with Stado
Scaling PostreSQL with StadoScaling PostreSQL with Stado
Scaling PostreSQL with StadoJim Mlodgenski
 
Multi-Master Replication with Slony
Multi-Master Replication with SlonyMulti-Master Replication with Slony
Multi-Master Replication with SlonyJim Mlodgenski
 
Scaling PostgreSQL With GridSQL
Scaling PostgreSQL With GridSQLScaling PostgreSQL With GridSQL
Scaling PostgreSQL With GridSQLJim Mlodgenski
 

Mehr von Jim Mlodgenski (11)

Strategic autovacuum
Strategic autovacuumStrategic autovacuum
Strategic autovacuum
 
Top 10 Mistakes When Migrating From Oracle to PostgreSQL
Top 10 Mistakes When Migrating From Oracle to PostgreSQLTop 10 Mistakes When Migrating From Oracle to PostgreSQL
Top 10 Mistakes When Migrating From Oracle to PostgreSQL
 
Oracle postgre sql-mirgration-top-10-mistakes
Oracle postgre sql-mirgration-top-10-mistakesOracle postgre sql-mirgration-top-10-mistakes
Oracle postgre sql-mirgration-top-10-mistakes
 
Profiling PL/pgSQL
Profiling PL/pgSQLProfiling PL/pgSQL
Profiling PL/pgSQL
 
Debugging Your PL/pgSQL Code
Debugging Your PL/pgSQL CodeDebugging Your PL/pgSQL Code
Debugging Your PL/pgSQL Code
 
PostgreSQL Procedural Languages: Tips, Tricks and Gotchas
PostgreSQL Procedural Languages: Tips, Tricks and GotchasPostgreSQL Procedural Languages: Tips, Tricks and Gotchas
PostgreSQL Procedural Languages: Tips, Tricks and Gotchas
 
Postgresql Federation
Postgresql FederationPostgresql Federation
Postgresql Federation
 
Leveraging Hadoop in your PostgreSQL Environment
Leveraging Hadoop in your PostgreSQL EnvironmentLeveraging Hadoop in your PostgreSQL Environment
Leveraging Hadoop in your PostgreSQL Environment
 
Scaling PostreSQL with Stado
Scaling PostreSQL with StadoScaling PostreSQL with Stado
Scaling PostreSQL with Stado
 
Multi-Master Replication with Slony
Multi-Master Replication with SlonyMulti-Master Replication with Slony
Multi-Master Replication with Slony
 
Scaling PostgreSQL With GridSQL
Scaling PostgreSQL With GridSQLScaling PostgreSQL With GridSQL
Scaling PostgreSQL With GridSQL
 

Kürzlich hochgeladen

08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 

Kürzlich hochgeladen (20)

08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

An Introduction To PostgreSQL Triggers

  • 2. Who am I? • Jim Mlodgenski – jimm@openscg.com – @jim_mlodgenski • Director – United States PostgreSQL (www.postgresql.us) • Co-organizer of – Philly PUG (www.phlpug.org) – NYC PUG (www.nycpug.org) • CTO, OpenSCG – www.openscg.com
  • 3.
  • 4. Triggers • Code that gets executed when an event happens in the database – INSERT, UPDATE, DELETE • Event Triggers fire on DDL – CREATE, DROP, ALTER – Still not mature yet ● (limited functionaity)
  • 5. Use Cases • Table Partitioning • Automatically generate derived column values • Enforce complex constraints • Enforce referential integrity across nodes in a distributed database • Provide transparent event logging • Provide auditing • Invalidate cache entries
  • 6. Structure ● Trigger ● Trigger Function CREATE TRIGGER foo_trg BEFORE UPDATE ON foo FOR EACH ROW EXECUTE PROCEDURE foo_update();
  • 7. Trigger Events ● Insert ● Update ● Delete ● Truncate
  • 8. Trigger Timing ● Before – The trigger is fired before the change is made to the table ● After – The trigger is fired after the change is made to the table
  • 9. Trigger Frequency ● For Each Row – The trigger is fired once each time a row is affected ● For Each Statement – The trigger is fired once each time a statement is executed
  • 10. Trigger Overhead CREATE UNLOGGED TABLE trigger_test ( key serial primary key, value varchar, insert_ts timestamp, update_ts timestamp ); INSERT INTO trigger_test (value) VALUES (‘hello’); set keys :scale setrandom key 1 :keys UPDATE trigger_test SET value = 'HELLO' WHERE key = :key;
  • 11. Trigger Overhead pgbench -n -t 100000 -f INSERTS.pgbench postgres pgbench -n -s 100000 -t 10000 -f UPDATES.pgbench postgres Inserts: 4510 tps Updates: 4349 tps
  • 12. Trigger Overhead CREATE FUNCTION empty_trigger() RETURNS trigger AS $$ BEGIN RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER empty_trigger BEFORE INSERT OR UPDATE ON trigger_test FOR EACH ROW EXECUTE PROCEDURE empty_trigger();
  • 13. Trigger Overhead pgbench -n -t 100000 -f INSERTS.pgbench postgres pgbench -n -s 100000 -t 10000 -f UPDATES.pgbench postgres Inserts: 4296 tps (4.8% overhead) Updates: 3988 tps (8.3% overhead)
  • 14. Trigger Arguments ● NEW – Variable holding the new row for INSERT/UPDATE operations in row-level triggers ● OLD – Variable holding the old row for UPDATE/DELETE operations in row-level triggers
  • 15. NEW vs OLD CREATE TABLE audit ( event_time timestamp NOT NULL, user_name varchar NOT NULL, old_row json, new_row json );
  • 16. NEW vs OLD (cont.) CREATE OR REPLACE FUNCTION audit_trigger() RETURNS TRIGGER AS $$ BEGIN INSERT INTO audit VALUES (CURRENT_TIMESTAMP, CURRENT_USER, row_to_json(OLD), row_to_json(NEW)); RETURN NEW; END; $$ LANGUAGE plpgsql;
  • 17. NEW vs OLD (cont.) CREATE TRIGGER audit_trigger AFTER UPDATE ON pgbench_branches FOR EACH ROW EXECUTE PROCEDURE audit_trigger();
  • 18. Trigger Arguments (cont.) ● TG_OP – A string of INSERT, UPDATE, DELETE, or TRUNCATE telling for which operation the trigger was fired ● TG_NAME – Variable that contains the name of the trigger actually fired ● TG_WHEN – A string of BEFORE, AFTER, or INSTEAD OF, depending on the trigger's definition ● TG_LEVEL – A string of either ROW or STATEMENT depending on the trigger's definition
  • 19. TG_OP CREATE TABLE audit ( event_time timestamp NOT NULL, user_name varchar NOT NULL, operation varchar NOT NULL, old_row json, new_row json );
  • 20. TG_OP (cont.) CREATE OR REPLACE FUNCTION audit_trigger() RETURNS TRIGGER AS $$ BEGIN IF (TG_OP = 'DELETE') THEN INSERT INTO audit VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP, row_to_json(OLD), null); RETURN OLD; ELSIF (TG_OP = 'UPDATE') THEN INSERT INTO audit VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP, row_to_json(OLD), row_to_json(NEW)); RETURN NEW; ELSIF (TG_OP = 'INSERT') THEN INSERT INTO audit VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP, null, row_to_json(NEW)); RETURN NEW; END IF; RETURN NULL; END; $$ LANGUAGE plpgsql;
  • 21. TG_OP (cont.) CREATE TRIGGER audit_trigger AFTER UPDATE OR INSERT OR DELETE ON pgbench_branches FOR EACH ROW EXECUTE PROCEDURE audit_trigger();
  • 22. Trigger Arguments (cont.) ● TG_TABLE_NAME – The name of the table that caused the trigger invocation. ● TG_RELNAME – The name of the table that caused the trigger invocation ● TG_RELID – The object ID of the table that caused the trigger invocation ● TG_TABLE_SCHEMA – The name of the schema of the table that caused the trigger invocation
  • 23. TG_TABLE_NAME CREATE TABLE audit ( event_time timestamp NOT NULL, user_name varchar NOT NULL, operation varchar NOT NULL, table_name varchar NOT NULL, old_row json, new_row json );
  • 24. TG_TABLE_NAME (cont.) CREATE OR REPLACE FUNCTION audit_trigger() RETURNS TRIGGER AS $$ BEGIN IF (TG_OP = 'DELETE') THEN INSERT INTO audit VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP, TG_TABLE_NAME, row_to_json(OLD), null); RETURN OLD; ELSIF (TG_OP = 'UPDATE') THEN INSERT INTO audit VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP, TG_TABLE_NAME, row_to_json(OLD), row_to_json(NEW)); RETURN NEW; ELSIF (TG_OP = 'INSERT') THEN INSERT INTO audit VALUES (CURRENT_TIMESTAMP, CURRENT_USER,TG_OP, TG_TABLE_NAME, null, row_to_json(NEW)); RETURN NEW; END IF; RETURN NULL; END; $$ LANGUAGE plpgsql;
  • 25. TG_TABLE_NAME (cont.) CREATE TRIGGER audit_trigger AFTER UPDATE OR INSERT OR DELETE ON pgbench_branches FOR EACH ROW EXECUTE PROCEDURE audit_trigger(); CREATE TRIGGER audit_trigger AFTER UPDATE OR INSERT OR DELETE ON pgbench_tellers FOR EACH ROW EXECUTE PROCEDURE audit_trigger();
  • 26. Trigger Arguments (cont.) ● TG_NARGS – The number of arguments given to the trigger procedure in the CREATE TRIGGER statement ● TG_ARGV[] – The arguments from the CREATE TRIGGER statement
  • 27. Trigger Use Cases ● Table Partitioning – Splitting what is logically one large table into smaller physical pieces – Used to: ● Increase performance ● Archive data ● Storage tiering
  • 28. Table Partitioning CREATE TABLE audit_2014 ( CHECK ( event_time >= DATE '2014-01-01' AND event_time < DATE '2015-01-01') ) INHERITS (audit); CREATE TABLE audit_2015 ( CHECK ( event_time >= DATE '2015-01-01' AND event_time < DATE '2016-01-01') ) INHERITS (audit);
  • 29. Table Partitioning (cont.) CREATE OR REPLACE FUNCTION partition_audit_trigger() RETURNS TRIGGER AS $$ BEGIN EXECUTE 'INSERT INTO audit_' || to_char(NEW.event_time, 'YYYY') || ' VALUES ($1, $2, $3, $4, $5, $6)' USING NEW.event_time, NEW.user_name, NEW.operation, NEW.table_name, NEW.old_row, NEW.new_row; RETURN NULL; END; $$ LANGUAGE plpgsql;
  • 30. Table Partitioning (cont.) CREATE TRIGGER partition_audit_trigger BEFORE INSERT ON audit FOR EACH ROW EXECUTE PROCEDURE partition_audit_trigger();
  • 31. Partitioning Performance CREATE OR REPLACE FUNCTION partition_audit_trigger() RETURNS TRIGGER AS $$ BEGIN IF ( NEW.event_time >= DATE '2015-01-01' AND NEW.event_time < DATE '2016-01-01' ) THEN INSERT INTO audit_2015 VALUES (NEW.*); ELSIF ( NEW.event_time >= DATE '2014-01-01' AND NEW.event_time < DATE '2015-01-01' ) THEN INSERT INTO audit_2014 VALUES (NEW.*); ELSE RAISE EXCEPTION 'Date out of range. Fix partition_audit_trigger() function!'; END IF; RETURN NULL; END; $$ LANGUAGE plpgsql;
  • 32. Moving Partitions CREATE TRIGGER move_partition_audit_trigger BEFORE UPDATE ON audit_2014 FOR EACH ROW EXECUTE PROCEDURE move_partition_audit_trigger('2014-01-01', '2015-01-01'); CREATE TRIGGER move_partition_audit_trigger BEFORE UPDATE ON audit_2015 FOR EACH ROW EXECUTE PROCEDURE move_partition_audit_trigger('2015-01-01', '2016-01-01');
  • 33. Moving Partitions (cont.) CREATE OR REPLACE FUNCTION move_partition_audit_trigger() RETURNS TRIGGER AS $$ DECLARE start_date DATE; end_date DATE; BEGIN start_date := TG_ARGV[0]; end_date := TG_ARGV[1]; IF ( NEW.event_time IS DISTINCT FROM OLD.event_time ) THEN IF (NEW.event_time < start_date OR NEW.event_time >= end_date) THEN EXECUTE 'DELETE FROM ' || TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME || ' WHERE ctid = $1' USING OLD.ctid; INSERT INTO audit VALUES (NEW.*); RETURN null; END IF; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;
  • 34. Moving Partitions (cont.) CREATE TRIGGER move_partition_audit_trigger BEFORE UPDATE ON audit_2014 FOR EACH ROW WHEN (NEW.event_time IS DISTINCT FROM OLD.event_time) EXECUTE PROCEDURE move_partition_audit_trigger('2014-01-01', '2015-01-01'); CREATE TRIGGER move_partition_audit_trigger BEFORE UPDATE ON audit_2015 FOR EACH ROW WHEN (NEW.event_time IS DISTINCT FROM OLD.event_time) EXECUTE PROCEDURE move_partition_audit_trigger('2015-01-01', '2016-01-01');
  • 35. Trigger Use Cases ● Calculate columns – Calculate complex values – Extract values from complex structures – Used to: ● Increase performance ● Simplify queries
  • 36. Extract JSON $ head -n 5 zips.json { "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" } { "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" } { "_id" : "01005", "city" : "BARRE", "loc" : [ -72.10835400000001, 42.409698 ], "pop" : 4546, "state" : "MA" } { "_id" : "01007", "city" : "BELCHERTOWN", "loc" : [ -72.41095300000001, 42.275103 ], "pop" : 10579, "state" : "MA" } { "_id" : "01008", "city" : "BLANDFORD", "loc" : [ -72.936114, 42.182949 ], "pop" : 1240, "state" : "MA" } CREATE TABLE zips ( zip_code varchar PRIMARY KEY, state varchar, data json );
  • 37. Extract JSON CREATE OR REPLACE FUNCTION extract_data_trigger() RETURNS TRIGGER AS $$ BEGIN NEW.zip_code := NEW.data->>'_id'; NEW.state := NEW.data->>'state'; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER extract_data_trigger BEFORE UPDATE OR INSERT ON zips FOR EACH ROW EXECUTE PROCEDURE extract_data_trigger();
  • 38. Trigger Use Cases ● Cache invalidation – Remove stale entries from a cache – The database tracks all data so is the single source of truth – Used to: ● Simplify cache management ● Remove application complexity Note: Foreign Data Wrappers simplify this process significantly
  • 39. Cache Invalidation CREATE TABLE users ( id serial PRIMARY KEY, first_name varchar, last_name varchar, email_address varchar NOT NULL, password_md5 varchar NOT NULL ); CREATE OR REPLACE FUNCTION remove_cache_trigger() RETURNS TRIGGER AS $$ BEGIN DELETE from myredis_cache WHERE key = OLD.id::varchar; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER remove_cache_trigger AFTER UPDATE OR DELETE ON users FOR EACH ROW EXECUTE PROCEDURE remove_cache_trigger();
  • 40. Cache Invalidation - Async CREATE OR REPLACE FUNCTION remove_cache_trigger() RETURNS TRIGGER AS $$ BEGIN PERFORM pg_notify(TG_TABLE_NAME, OLD.id::varchar); RETURN NEW; END; $$ LANGUAGE plpgsql;
  • 41. Things to Remember ● Triggers are part of the parent transaction – The trigger fails, the main transaction fails – If the trigger takes a long time, the whole transaction timing is affected ● Triggers can be difficult to debug – Especially cascaded triggers