SlideShare a Scribd company logo
1
Hooks in PostgreSQL
Hooks in PostgreSQL
2
Who's Guillaume Lelarge?
● French translator of the PostgreSQL manual
● Member of pgAdmin's team
● Vice-treasurer of PostgreSQL Europe
● CTO of Dalibo
● Mail: guillaume@lelarge.info
● Twitter: g_lelarge
● Blog: http://blog.guillaume.lelarge.info
3
PostgreSQL
● Well known for its extensibility
● For example, a user can add
– Types
– Functions
– Operators
– Languages
– Etc
● Extensions in 9.1
● Less known is the hook system
4
Hooks
● Interrupt, and modify behaviour
● Not known because
– Not explained in the documentation
– Usually quite recent
● Four kinds of hooks
– Planner hooks
– Executor hooks
– Security/permissions hooks
– PL/pgsql hooks
5
Planner hooks
Hook Used in Initial release
explain_get_index_name_hook 8.3
ExplainOneQuery_hook IndexAdvisor 8.3
get_attavgwidth_hook 8.4
get_index_stats_hook 8.4
get_relation_info_hook plantuner 8.3
get_relation_stats_hook 8.4
join_search_hook saio 8.3
planner_hook planinstr 8.3
6
Executor hooks
Hook Used in Initial release
ExecutorStart_hook pg_stat_statements 8.4
ExecutorRun_hook pg_stat_statements 8.4
ExecutorFinish_hook pg_stat_statements 8.4
ExecutorEnd_hook pg_stat_statements 8.4
ProcessUtility_hook pgextwlist, pg_stat_statements 9.0
7
Security/permissions hooks
Hook Used in Initial release
check_password_hook passwordcheck 9.0
ClientAuthentication_hook auth_delay, sepgsql, etc 9.1
ExecutorCheckPerms_hook sepgsql 9.1
fmgr_hook sepgsql 9.1
needs_fmgr_hook sepgsql 9.1
object_access_hook sepgsql 9.1
8
PL/pgsql hooks
Hook Initial release
func_setup 8.2
func_beg 8.2
func_end 8.2
stmt_beg 8.2
stmt_end 8.2
Used by
●pldebugger,
●plprofiler,
●log_functions.
9
And yet another one
Hook Used in Initial release
shmem_startup_hook pg_stat_statements 8.4
10
How do they work inside PG
● Hooks consist of global function pointers
● Initially set to NULL
● When PostgreSQL wants to use a hook
– It checks the global function pointer
– And executes it if it is set
11
How do we set the function pointer?
● A hook function is available in a shared library
● At load time, PostgreSQL calls the _PG_init()
function of the shared library
● This function needs to set the pointer
– And usually saves the previous one!
12
How do we unset the function pointer?
● At unload time, PostgreSQL calls the _PG_fini()
function of the shared library
● This function needs to unset the pointer
– And usually restores the previous one!
13
Example with
ClientAuthentication_hook
● Declaration of the function type
– extract from src/include/libpq/auth.h, line 27
/* Hook for plugins to get control in ClientAuthentication() */
typedef void (*ClientAuthentication_hook_type) (Port *, int);
14
Example with
ClientAuthentication_hook
● Declare, and set the global function pointer
– extract from src/backend/libpq/auth.c, line 215
/*
* This hook allows plugins to get control following client authentication,
* but before the user has been informed about the results. It could be used
* to record login events, insert a delay after failed authentication, etc.
*/
ClientAuthentication_hook_type ClientAuthentication_hook = NULL;
15
Example with
ClientAuthentication_hook
● Check, and execute
– extract from src/backend/libpq/auth.c, line 580
if (ClientAuthentication_hook)
(*ClientAuthentication_hook) (port, status);
16
Writing hooks
● Details on some hooks
– ClientAuthentication
– Executor_End
– check_password
– func_beg
● And various examples
17
ClientAuthentication_hook details
● Get control
– After client authentication
– But before informing the user
● Usefull to
– Record login events
– Insert a delay after failed authentication
18
ClientAuthentication_hook use
● Modules using this hook
– auth_delay
– sepgsql
– connection_limits
(https://github.com/tvondra/connection_limits)
19
ClientAuthentication_hook function
● Two parameters
– f (Port *port, int status)
● Port is a complete structure described in
include/libpq/libpq-be.h
– remote_host, remote_hostname, remote_port,
database_name, user_name, guc_options, etc.
● Status is a status code
– STATUS_ERROR, STATUS_OK
20
Writing a ClientAuthentication_hook
● Example: forbid connection if a file is present
● Needs two functions
– One to install the hook
– Another one to check availability of the file, and
allow or deny connection
21
Writing a ClientAuthentication_hook
● First, initialize the hook
static ClientAuthentication_hook_type prev_client_auth_hook = NULL;
/* Module entry point */
void
_PG_init(void)
{
prev_client_auth_hook = ClientAuthentication_hook;
ClientAuthentication_hook = my_client_auth;
}
22
Writing a ClientAuthentication_hook
● Check availability of the file, and allow or deny
connection
static void my_client_auth(Port *port, int status)
{
struct stat buf;
if (prev_client_auth_hook)
(*prev_client_auth_hook) (port, status);
if (status != STATUS_OK)
return;
if(!stat("/tmp/connection.stopped", &buf))
ereport(FATAL, (errcode(ERRCODE_INTERNAL_ERROR),
errmsg("Connection not authorized!!")));
}
23
Executor hooks details
● Start
– beginning of execution of a query plan
● Run
– Accepts direction, and count
– May be called more than once
● Finish
– After the final ExecutorRun call
● End
– End of execution of a query plan
24
Executor hooks use
● Usefull to get informations on executed queries
● Already used by
– pg_stat_statements
– auto_explain
– pg_log_userqueries
http://pgxn.org/dist/pg_log_userqueries/
– query_histogram
http://pgxn.org/dist/query_histogram/
– query_recorder http://pgxn.org/dist/query_recorder/
25
ExecutorEnd_hook function
● One parameter
– f(QueryDesc *queryDesc)
● QueryDesc is a structure described in
include/executor/execdesc.h
– CmdType, sourceTexte, Instrumentation, etc
26
Writing an ExecutorEnd_hook
● Example: log queries executed by superuser only
● Needs three functions
– One to install the hook
– One to uninstall the hook
– And a last one to do the job :-)
27
Writing an ExecutorEnd_hook
● First, install the hook
/* Saved hook values in case of unload */
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
void _PG_init(void)
{
prev_ExecutorEnd = ExecutorEnd_hook;
ExecutorEnd_hook = my_ExecutorEnd;
}
28
Writing an ExecutorEnd_hook
● The hook itself:
– check if the user has the superuser attribute
– log (or not) the query
– fire the next hook or the default one
static void
my_ExecutorEnd(QueryDesc *queryDesc)
{
Assert(query != NULL);
if (superuser())
elog(LOG, "superuser %s fired this query %s",
GetUserNameFromId(GetUserId()),
query);
if (prev_ExecutorEnd)
prev_ExecutorEnd(queryDesc);
else
standard_ExecutorEnd(queryDesc);
}
29
Writing an ExecutorEnd_hook
● Finally, uninstall the hook
void _PG_fini(void)
{
ExecutorEnd_hook = prev_ExecutorEnd;
}
30
check_password hook details
● Get control
– When CREATE/ALTER USER is executed
– But before commiting
● Usefull to
– Check the password according to some enterprise
rules
– Log change of passwords
– Disallow plain text passwords
● Major issue
– Less effective with encrypted passwords :-/
31
check_password hook use
● Usefull to check password strength
● Already used by
– passwordcheck
32
check_password_hook function
● Five parameters
– const char *username, const char *password, int
password_type, Datum validuntil_time, bool
validuntil_null
● password_type
– PASSWORD_TYPE_PLAINTEXT
– PASSWORD_TYPE_MD5
33
Writing a check_password_hook
● Example: disallow plain text passwords
● Needs two functions
– One to install the hook
– One to check the password type
34
Writing a check_password_hook
● First, install the hook
void _PG_init(void)
{
check_password_hook = my_check_password;
}
35
Writing a check_password_hook
● The hook itself:
– check if the password is encrypted
static void
my_check_password(const char *username,
const char *password, int password_type,
Datum validuntil_time, bool validuntil_null)
{
if (password_type == PASSWORD_TYPE_PLAINTEXT)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("password is not encrypted")));
}
}
36
func_beg details
● Get control
– Before BEGIN block of a PL/pgsql function
● Usefull to
– Log start of each function
– Profile functions
– Debug functions
37
func_beg use
● Modules using this hook
– pldebugger
– plprofiler
– log_functions
(https://github.com/gleu/log_functions)
38
func_beg function
● Two parameters
– f (PLpgSQL_execstate *estate, PLpgSQL_function
*func)
● estate is a complete structure described in
src/pl/plpgsql/plpgsql.h
● func is a complete structure described in
src/pl/plpgsql/plpgsql.h
– Name, OID, return type, ...
39
Writing a func_beg
● Example: log each function executed
● Needs two functions
– One to install the hook
– Another one to log the function name
40
Writing a func_beg
● First, initialize the hook
static PLpgSQL_plugin plugin_funcs = { my_func_beg };
void _PG_init(void)
{
PLpgSQL_plugin ** var_ptr = (PLpgSQL_plugin **)
find_rendezvous_variable("PLpgSQL_plugin");
*var_ptr = &plugin_funcs;
}
void load_plugin(PLpgSQL_plugin *hooks)
{
hooks->func_beg = my_func_beg;
}
41
Writing a func_beg
● Log function name
static void my_func_beg(PLpgSQL_execstate *estate,
PLpgSQL_function *func)
{
elog(LOG, "Execute function %s", func->fn_name);
}
42
Compiling hooks
● Usual Makefile
MODULE_big = your_hook
OBJS = your_hook.o
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/your_hook
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
43
Compiling hooks – example
● Make is your friend (and so is pg_config)
$ make USE_PGXS=1
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-
statement -Wendif-labels -Wformat-security -fno-strict-aliasing -fwrapv -
fexcess-precision=standard -fpic -I. -I. -I/opt/postgresql-
9.1/include/server -I/opt/postgresql-9.1/include/internal -D_GNU_SOURCE -
c -o your_hook.o your_hook.c
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-
statement -Wendif-labels -Wformat-security -fno-strict-aliasing -fwrapv -
fexcess-precision=standard -fpic -shared -o your_hook.so
only_encrypted_passwords.o -L/opt/postgresql-9.1/lib -Wl,--as-needed -Wl,-
rpath,'/opt/postgresql-9.1/lib',--enable-new-dtags
● Can't use PGXS with PL/pgsql plugins
– But will be possible in 9.2 (thanks to Heikki for
working on the patch)
44
Installing hooks – from source
● Make is still your friend
$ make USE_PGXS=1 install
/bin/mkdir -p '/opt/postgresql-9.1/lib'
/bin/sh /opt/postgresql-9.1/lib/pgxs/src/makefiles/../../config/install-sh -c
-m 755 your_hook.so '/opt/postgresql-9.1/lib/your_hook.so'
45
PGXS
● It's better to rely only on PGXS (if possible)
● Makefile looks like this:
MODULE_big = your_hook
OBJS = your_hook.o
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
● So much simpler...
46
Using hooks with
shared_preload_libraries
● Install the shared library
● In postgresql.conf
– shared_preload_libraries
– And possibly other shared library GUCs
● Restart PG
47
Using hooks – example
● Install the hook...
● In postgresql.conf
shared_preload_libraries = 'only_encrypted_passwords'
● Restart PostgreSQL
$ pg_ctl start
server starting
2012-01-28 16:01:32 CET LOG: loaded library "only_encrypted_passwords"
48
Using hooks – example
● Use the hook...
postgres=# CREATE USER u1 PASSWORD 'supersecret';
ERROR: password is not encrypted
postgres=# CREATE USER u1 PASSWORD 'md5f96c038c1bf28d837c32cc62fa97910a';
CREATE ROLE
postgres=# ALTER USER u1 PASSWORD 'f96c038c1bf28d837c32cc62fa97910a';
ERROR: password is not encrypted
postgres=# ALTER USER u1 PASSWORD 'md5f96c038c1bf28d837c32cc62fa97910a';
ALTER ROLE
49
Using hooks with LOAD statement
● Install the shared library
● LOAD the library
● ... and use it
50
Using hooks – example
● Install the hook...
● Create the function, and use it:
postgres=# CREATE FUNCTION f1() RETURNS boolean LANGUAGE plpgsql AS $$
postgres$# BEGIN
postgres$# PERFORM pg_sleep(5);
postgres$# RETURN true;
postgres$# END
postgres$# $$;
CREATE FUNCTION
hooks=# SET client_min_messages TO log;
LOG: duration: 0.132 ms statement: SET client_min_messages TO log;
SET
hooks=# SELECT f1();
LOG: duration: 5003.180 ms statement: SELECT f1();
f1
----
t
(1 row)
51
Using hooks – example
● LOAD the shared library, and use it...
hooks=# LOAD 'logplpgsql';
LOG: duration: 0.373 ms statement: LOAD 'logplpgsql';
LOAD
hooks=# SELECT f1();
LOG: Execute function f1
LOG: duration: 5001.466 ms statement: SELECT f1();
[...]
hooks=# SELECT f1() FROM generate_series(1, 5);
LOG: Execute function f1
LOG: Execute function f1
LOG: Execute function f1
LOG: Execute function f1
LOG: Execute function f1
LOG: duration: 25006.701 ms statement: SELECT f1() FROM generate_series(1,
5);
[...]
52
9.2 hooks
● One old hook with enhanced capability
● PGXS support for PL/pgsql hooks
● Two new hooks
– A logging hook
– And another planer hook
53
9.2 – Enhanced object_access_hook
● DROP statement support for object_access_hook
● Used by sepgsql
54
9.2 hooks – the logging hook
● Logging hook, by Martin Pihlak
– emit_log_hook
– Intercept messages before they are sent to the server
log
– Custom log filtering
– Used by pg_journal
(http://www.pgxn.org/dist/pg_journal/0.1.0/)
55
9.2 hooks – the planner hook
● Planner hook, by Peter Geoghegan
– post_parse_analyze_hook
– Get control at end of parse analysis
– Query normalisation within pg_stat_statements
56
Conclusion
● Hooks are an interesting system to extend the
capabilities of PostgreSQL
● Be cautious to avoid adding many of them
● We need more of them :-)
● Examples and slides available on:
– https://github.com/gleu/Hooks-in-PostgreSQL

More Related Content

Similar to Hooks in postgresql by Guillaume Lelarge

Quality of life through Unit Testing
Quality of life through Unit TestingQuality of life through Unit Testing
Quality of life through Unit Testing
Sian Lerk Lau
 
Shall we play a game?
Shall we play a game?Shall we play a game?
Shall we play a game?
IngridRivera36
 
0507 057 01 98 * Adana Klima Servisleri
0507 057 01 98 * Adana Klima Servisleri0507 057 01 98 * Adana Klima Servisleri
Shall we play a game
Shall we play a gameShall we play a game
Shall we play a game
jackpot201
 
We shall play a game....
We shall play a game....We shall play a game....
We shall play a game....
Sadia Textile
 
StormCrawler at Bristech
StormCrawler at BristechStormCrawler at Bristech
StormCrawler at Bristech
Julien Nioche
 
Rest application
Rest applicationRest application
Rest application
Illia Seleznov
 
Load testing in Zonky with Gatling
Load testing in Zonky with GatlingLoad testing in Zonky with Gatling
Load testing in Zonky with Gatling
Petr Vlček
 
2. writing MySql plugins general
2. writing MySql plugins   general2. writing MySql plugins   general
2. writing MySql plugins general
Roland Bouman
 
Docker Monitoring Webinar
Docker Monitoring  WebinarDocker Monitoring  Webinar
Docker Monitoring Webinar
Sematext Group, Inc.
 
There and back again: A story of a s
There and back again: A story of a sThere and back again: A story of a s
There and back again: A story of a s
Colin Harrington
 
Why you should be using structured logs
Why you should be using structured logsWhy you should be using structured logs
Why you should be using structured logs
Stefan Krawczyk
 
PG Day'14 Russia, PostgreSQL System Architecture, Heikki Linnakangas
PG Day'14 Russia, PostgreSQL System Architecture, Heikki LinnakangasPG Day'14 Russia, PostgreSQL System Architecture, Heikki Linnakangas
PG Day'14 Russia, PostgreSQL System Architecture, Heikki Linnakangas
pgdayrussia
 
nginx: writing your first module
nginx: writing your first modulenginx: writing your first module
nginx: writing your first module
redivy
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
KAI CHU CHUNG
 
Log4j2
Log4j2Log4j2
Bug Bounty Hunter Methodology - Nullcon 2016
Bug Bounty Hunter Methodology - Nullcon 2016Bug Bounty Hunter Methodology - Nullcon 2016
Bug Bounty Hunter Methodology - Nullcon 2016
bugcrowd
 
Introduction to trader bots with Python
Introduction to trader bots with PythonIntroduction to trader bots with Python
Introduction to trader bots with Python
roskakori
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
Sri Prasanna
 
Tracing and profiling my sql (percona live europe 2019) draft_1
Tracing and profiling my sql (percona live europe 2019) draft_1Tracing and profiling my sql (percona live europe 2019) draft_1
Tracing and profiling my sql (percona live europe 2019) draft_1
Valerii Kravchuk
 

Similar to Hooks in postgresql by Guillaume Lelarge (20)

Quality of life through Unit Testing
Quality of life through Unit TestingQuality of life through Unit Testing
Quality of life through Unit Testing
 
Shall we play a game?
Shall we play a game?Shall we play a game?
Shall we play a game?
 
0507 057 01 98 * Adana Klima Servisleri
0507 057 01 98 * Adana Klima Servisleri0507 057 01 98 * Adana Klima Servisleri
0507 057 01 98 * Adana Klima Servisleri
 
Shall we play a game
Shall we play a gameShall we play a game
Shall we play a game
 
We shall play a game....
We shall play a game....We shall play a game....
We shall play a game....
 
StormCrawler at Bristech
StormCrawler at BristechStormCrawler at Bristech
StormCrawler at Bristech
 
Rest application
Rest applicationRest application
Rest application
 
Load testing in Zonky with Gatling
Load testing in Zonky with GatlingLoad testing in Zonky with Gatling
Load testing in Zonky with Gatling
 
2. writing MySql plugins general
2. writing MySql plugins   general2. writing MySql plugins   general
2. writing MySql plugins general
 
Docker Monitoring Webinar
Docker Monitoring  WebinarDocker Monitoring  Webinar
Docker Monitoring Webinar
 
There and back again: A story of a s
There and back again: A story of a sThere and back again: A story of a s
There and back again: A story of a s
 
Why you should be using structured logs
Why you should be using structured logsWhy you should be using structured logs
Why you should be using structured logs
 
PG Day'14 Russia, PostgreSQL System Architecture, Heikki Linnakangas
PG Day'14 Russia, PostgreSQL System Architecture, Heikki LinnakangasPG Day'14 Russia, PostgreSQL System Architecture, Heikki Linnakangas
PG Day'14 Russia, PostgreSQL System Architecture, Heikki Linnakangas
 
nginx: writing your first module
nginx: writing your first modulenginx: writing your first module
nginx: writing your first module
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 
Log4j2
Log4j2Log4j2
Log4j2
 
Bug Bounty Hunter Methodology - Nullcon 2016
Bug Bounty Hunter Methodology - Nullcon 2016Bug Bounty Hunter Methodology - Nullcon 2016
Bug Bounty Hunter Methodology - Nullcon 2016
 
Introduction to trader bots with Python
Introduction to trader bots with PythonIntroduction to trader bots with Python
Introduction to trader bots with Python
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
 
Tracing and profiling my sql (percona live europe 2019) draft_1
Tracing and profiling my sql (percona live europe 2019) draft_1Tracing and profiling my sql (percona live europe 2019) draft_1
Tracing and profiling my sql (percona live europe 2019) draft_1
 

More from Kyle Hailey

Performance insights twitch
Performance insights twitchPerformance insights twitch
Performance insights twitch
Kyle Hailey
 
History of database monitoring
History of database monitoringHistory of database monitoring
History of database monitoring
Kyle Hailey
 
Ash masters : advanced ash analytics on Oracle
Ash masters : advanced ash analytics on Oracle Ash masters : advanced ash analytics on Oracle
Ash masters : advanced ash analytics on Oracle
Kyle Hailey
 
Successfully convince people with data visualization
Successfully convince people with data visualizationSuccessfully convince people with data visualization
Successfully convince people with data visualization
Kyle Hailey
 
Virtual Data : Eliminating the data constraint in Application Development
Virtual Data :  Eliminating the data constraint in Application DevelopmentVirtual Data :  Eliminating the data constraint in Application Development
Virtual Data : Eliminating the data constraint in Application Development
Kyle Hailey
 
DBTA Data Summit : Eliminating the data constraint in Application Development
DBTA Data Summit : Eliminating the data constraint in Application DevelopmentDBTA Data Summit : Eliminating the data constraint in Application Development
DBTA Data Summit : Eliminating the data constraint in Application Development
Kyle Hailey
 
Accelerate Develoment with VIrtual Data
Accelerate Develoment with VIrtual DataAccelerate Develoment with VIrtual Data
Accelerate Develoment with VIrtual Data
Kyle Hailey
 
Delphix and Pure Storage partner
Delphix and Pure Storage partnerDelphix and Pure Storage partner
Delphix and Pure Storage partner
Kyle Hailey
 
Mark Farnam : Minimizing the Concurrency Footprint of Transactions
Mark Farnam  : Minimizing the Concurrency Footprint of TransactionsMark Farnam  : Minimizing the Concurrency Footprint of Transactions
Mark Farnam : Minimizing the Concurrency Footprint of Transactions
Kyle Hailey
 
Dan Norris: Exadata security
Dan Norris: Exadata securityDan Norris: Exadata security
Dan Norris: Exadata security
Kyle Hailey
 
Martin Klier : Volkswagen for Oracle Guys
Martin Klier : Volkswagen for Oracle GuysMartin Klier : Volkswagen for Oracle Guys
Martin Klier : Volkswagen for Oracle Guys
Kyle Hailey
 
What is DevOps
What is DevOpsWhat is DevOps
What is DevOps
Kyle Hailey
 
Data as a Service
Data as a Service Data as a Service
Data as a Service
Kyle Hailey
 
Data Virtualization: Revolutionizing data cloning
Data Virtualization: Revolutionizing data cloningData Virtualization: Revolutionizing data cloning
Data Virtualization: Revolutionizing data cloning
Kyle Hailey
 
BGOUG "Agile Data: revolutionizing database cloning'
BGOUG  "Agile Data: revolutionizing database cloning'BGOUG  "Agile Data: revolutionizing database cloning'
BGOUG "Agile Data: revolutionizing database cloning'
Kyle Hailey
 
Denver devops : enabling DevOps with data virtualization
Denver devops : enabling DevOps with data virtualizationDenver devops : enabling DevOps with data virtualization
Denver devops : enabling DevOps with data virtualization
Kyle Hailey
 
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Kyle Hailey
 
Jonathan Lewis explains Delphix
Jonathan Lewis explains Delphix Jonathan Lewis explains Delphix
Jonathan Lewis explains Delphix
Kyle Hailey
 
Oaktable World 2014 Toon Koppelaars: database constraints polite excuse
Oaktable World 2014 Toon Koppelaars: database constraints polite excuseOaktable World 2014 Toon Koppelaars: database constraints polite excuse
Oaktable World 2014 Toon Koppelaars: database constraints polite excuse
Kyle Hailey
 
Profiling the logwriter and database writer
Profiling the logwriter and database writerProfiling the logwriter and database writer
Profiling the logwriter and database writer
Kyle Hailey
 

More from Kyle Hailey (20)

Performance insights twitch
Performance insights twitchPerformance insights twitch
Performance insights twitch
 
History of database monitoring
History of database monitoringHistory of database monitoring
History of database monitoring
 
Ash masters : advanced ash analytics on Oracle
Ash masters : advanced ash analytics on Oracle Ash masters : advanced ash analytics on Oracle
Ash masters : advanced ash analytics on Oracle
 
Successfully convince people with data visualization
Successfully convince people with data visualizationSuccessfully convince people with data visualization
Successfully convince people with data visualization
 
Virtual Data : Eliminating the data constraint in Application Development
Virtual Data :  Eliminating the data constraint in Application DevelopmentVirtual Data :  Eliminating the data constraint in Application Development
Virtual Data : Eliminating the data constraint in Application Development
 
DBTA Data Summit : Eliminating the data constraint in Application Development
DBTA Data Summit : Eliminating the data constraint in Application DevelopmentDBTA Data Summit : Eliminating the data constraint in Application Development
DBTA Data Summit : Eliminating the data constraint in Application Development
 
Accelerate Develoment with VIrtual Data
Accelerate Develoment with VIrtual DataAccelerate Develoment with VIrtual Data
Accelerate Develoment with VIrtual Data
 
Delphix and Pure Storage partner
Delphix and Pure Storage partnerDelphix and Pure Storage partner
Delphix and Pure Storage partner
 
Mark Farnam : Minimizing the Concurrency Footprint of Transactions
Mark Farnam  : Minimizing the Concurrency Footprint of TransactionsMark Farnam  : Minimizing the Concurrency Footprint of Transactions
Mark Farnam : Minimizing the Concurrency Footprint of Transactions
 
Dan Norris: Exadata security
Dan Norris: Exadata securityDan Norris: Exadata security
Dan Norris: Exadata security
 
Martin Klier : Volkswagen for Oracle Guys
Martin Klier : Volkswagen for Oracle GuysMartin Klier : Volkswagen for Oracle Guys
Martin Klier : Volkswagen for Oracle Guys
 
What is DevOps
What is DevOpsWhat is DevOps
What is DevOps
 
Data as a Service
Data as a Service Data as a Service
Data as a Service
 
Data Virtualization: Revolutionizing data cloning
Data Virtualization: Revolutionizing data cloningData Virtualization: Revolutionizing data cloning
Data Virtualization: Revolutionizing data cloning
 
BGOUG "Agile Data: revolutionizing database cloning'
BGOUG  "Agile Data: revolutionizing database cloning'BGOUG  "Agile Data: revolutionizing database cloning'
BGOUG "Agile Data: revolutionizing database cloning'
 
Denver devops : enabling DevOps with data virtualization
Denver devops : enabling DevOps with data virtualizationDenver devops : enabling DevOps with data virtualization
Denver devops : enabling DevOps with data virtualization
 
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
Oracle Open World 2014: Lies, Damned Lies, and I/O Statistics [ CON3671]
 
Jonathan Lewis explains Delphix
Jonathan Lewis explains Delphix Jonathan Lewis explains Delphix
Jonathan Lewis explains Delphix
 
Oaktable World 2014 Toon Koppelaars: database constraints polite excuse
Oaktable World 2014 Toon Koppelaars: database constraints polite excuseOaktable World 2014 Toon Koppelaars: database constraints polite excuse
Oaktable World 2014 Toon Koppelaars: database constraints polite excuse
 
Profiling the logwriter and database writer
Profiling the logwriter and database writerProfiling the logwriter and database writer
Profiling the logwriter and database writer
 

Recently uploaded

Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
Remote DBA Services
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
Marcin Chrost
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Envertis Software Solutions
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
ssuserad3af4
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
dakas1
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
Bert Jan Schrijver
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
mz5nrf0n
 
SQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure MalaysiaSQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure Malaysia
GohKiangHock
 
Top 9 Trends in Cybersecurity for 2024.pptx
Top 9 Trends in Cybersecurity for 2024.pptxTop 9 Trends in Cybersecurity for 2024.pptx
Top 9 Trends in Cybersecurity for 2024.pptx
devvsandy
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
Yara Milbes
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
Rakesh Kumar R
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 

Recently uploaded (20)

Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
316895207-SAP-Oil-and-Gas-Downstream-Training.pptx
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
 
SQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure MalaysiaSQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure Malaysia
 
Top 9 Trends in Cybersecurity for 2024.pptx
Top 9 Trends in Cybersecurity for 2024.pptxTop 9 Trends in Cybersecurity for 2024.pptx
Top 9 Trends in Cybersecurity for 2024.pptx
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 

Hooks in postgresql by Guillaume Lelarge

  • 2. 2 Who's Guillaume Lelarge? ● French translator of the PostgreSQL manual ● Member of pgAdmin's team ● Vice-treasurer of PostgreSQL Europe ● CTO of Dalibo ● Mail: guillaume@lelarge.info ● Twitter: g_lelarge ● Blog: http://blog.guillaume.lelarge.info
  • 3. 3 PostgreSQL ● Well known for its extensibility ● For example, a user can add – Types – Functions – Operators – Languages – Etc ● Extensions in 9.1 ● Less known is the hook system
  • 4. 4 Hooks ● Interrupt, and modify behaviour ● Not known because – Not explained in the documentation – Usually quite recent ● Four kinds of hooks – Planner hooks – Executor hooks – Security/permissions hooks – PL/pgsql hooks
  • 5. 5 Planner hooks Hook Used in Initial release explain_get_index_name_hook 8.3 ExplainOneQuery_hook IndexAdvisor 8.3 get_attavgwidth_hook 8.4 get_index_stats_hook 8.4 get_relation_info_hook plantuner 8.3 get_relation_stats_hook 8.4 join_search_hook saio 8.3 planner_hook planinstr 8.3
  • 6. 6 Executor hooks Hook Used in Initial release ExecutorStart_hook pg_stat_statements 8.4 ExecutorRun_hook pg_stat_statements 8.4 ExecutorFinish_hook pg_stat_statements 8.4 ExecutorEnd_hook pg_stat_statements 8.4 ProcessUtility_hook pgextwlist, pg_stat_statements 9.0
  • 7. 7 Security/permissions hooks Hook Used in Initial release check_password_hook passwordcheck 9.0 ClientAuthentication_hook auth_delay, sepgsql, etc 9.1 ExecutorCheckPerms_hook sepgsql 9.1 fmgr_hook sepgsql 9.1 needs_fmgr_hook sepgsql 9.1 object_access_hook sepgsql 9.1
  • 8. 8 PL/pgsql hooks Hook Initial release func_setup 8.2 func_beg 8.2 func_end 8.2 stmt_beg 8.2 stmt_end 8.2 Used by ●pldebugger, ●plprofiler, ●log_functions.
  • 9. 9 And yet another one Hook Used in Initial release shmem_startup_hook pg_stat_statements 8.4
  • 10. 10 How do they work inside PG ● Hooks consist of global function pointers ● Initially set to NULL ● When PostgreSQL wants to use a hook – It checks the global function pointer – And executes it if it is set
  • 11. 11 How do we set the function pointer? ● A hook function is available in a shared library ● At load time, PostgreSQL calls the _PG_init() function of the shared library ● This function needs to set the pointer – And usually saves the previous one!
  • 12. 12 How do we unset the function pointer? ● At unload time, PostgreSQL calls the _PG_fini() function of the shared library ● This function needs to unset the pointer – And usually restores the previous one!
  • 13. 13 Example with ClientAuthentication_hook ● Declaration of the function type – extract from src/include/libpq/auth.h, line 27 /* Hook for plugins to get control in ClientAuthentication() */ typedef void (*ClientAuthentication_hook_type) (Port *, int);
  • 14. 14 Example with ClientAuthentication_hook ● Declare, and set the global function pointer – extract from src/backend/libpq/auth.c, line 215 /* * This hook allows plugins to get control following client authentication, * but before the user has been informed about the results. It could be used * to record login events, insert a delay after failed authentication, etc. */ ClientAuthentication_hook_type ClientAuthentication_hook = NULL;
  • 15. 15 Example with ClientAuthentication_hook ● Check, and execute – extract from src/backend/libpq/auth.c, line 580 if (ClientAuthentication_hook) (*ClientAuthentication_hook) (port, status);
  • 16. 16 Writing hooks ● Details on some hooks – ClientAuthentication – Executor_End – check_password – func_beg ● And various examples
  • 17. 17 ClientAuthentication_hook details ● Get control – After client authentication – But before informing the user ● Usefull to – Record login events – Insert a delay after failed authentication
  • 18. 18 ClientAuthentication_hook use ● Modules using this hook – auth_delay – sepgsql – connection_limits (https://github.com/tvondra/connection_limits)
  • 19. 19 ClientAuthentication_hook function ● Two parameters – f (Port *port, int status) ● Port is a complete structure described in include/libpq/libpq-be.h – remote_host, remote_hostname, remote_port, database_name, user_name, guc_options, etc. ● Status is a status code – STATUS_ERROR, STATUS_OK
  • 20. 20 Writing a ClientAuthentication_hook ● Example: forbid connection if a file is present ● Needs two functions – One to install the hook – Another one to check availability of the file, and allow or deny connection
  • 21. 21 Writing a ClientAuthentication_hook ● First, initialize the hook static ClientAuthentication_hook_type prev_client_auth_hook = NULL; /* Module entry point */ void _PG_init(void) { prev_client_auth_hook = ClientAuthentication_hook; ClientAuthentication_hook = my_client_auth; }
  • 22. 22 Writing a ClientAuthentication_hook ● Check availability of the file, and allow or deny connection static void my_client_auth(Port *port, int status) { struct stat buf; if (prev_client_auth_hook) (*prev_client_auth_hook) (port, status); if (status != STATUS_OK) return; if(!stat("/tmp/connection.stopped", &buf)) ereport(FATAL, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("Connection not authorized!!"))); }
  • 23. 23 Executor hooks details ● Start – beginning of execution of a query plan ● Run – Accepts direction, and count – May be called more than once ● Finish – After the final ExecutorRun call ● End – End of execution of a query plan
  • 24. 24 Executor hooks use ● Usefull to get informations on executed queries ● Already used by – pg_stat_statements – auto_explain – pg_log_userqueries http://pgxn.org/dist/pg_log_userqueries/ – query_histogram http://pgxn.org/dist/query_histogram/ – query_recorder http://pgxn.org/dist/query_recorder/
  • 25. 25 ExecutorEnd_hook function ● One parameter – f(QueryDesc *queryDesc) ● QueryDesc is a structure described in include/executor/execdesc.h – CmdType, sourceTexte, Instrumentation, etc
  • 26. 26 Writing an ExecutorEnd_hook ● Example: log queries executed by superuser only ● Needs three functions – One to install the hook – One to uninstall the hook – And a last one to do the job :-)
  • 27. 27 Writing an ExecutorEnd_hook ● First, install the hook /* Saved hook values in case of unload */ static ExecutorEnd_hook_type prev_ExecutorEnd = NULL; void _PG_init(void) { prev_ExecutorEnd = ExecutorEnd_hook; ExecutorEnd_hook = my_ExecutorEnd; }
  • 28. 28 Writing an ExecutorEnd_hook ● The hook itself: – check if the user has the superuser attribute – log (or not) the query – fire the next hook or the default one static void my_ExecutorEnd(QueryDesc *queryDesc) { Assert(query != NULL); if (superuser()) elog(LOG, "superuser %s fired this query %s", GetUserNameFromId(GetUserId()), query); if (prev_ExecutorEnd) prev_ExecutorEnd(queryDesc); else standard_ExecutorEnd(queryDesc); }
  • 29. 29 Writing an ExecutorEnd_hook ● Finally, uninstall the hook void _PG_fini(void) { ExecutorEnd_hook = prev_ExecutorEnd; }
  • 30. 30 check_password hook details ● Get control – When CREATE/ALTER USER is executed – But before commiting ● Usefull to – Check the password according to some enterprise rules – Log change of passwords – Disallow plain text passwords ● Major issue – Less effective with encrypted passwords :-/
  • 31. 31 check_password hook use ● Usefull to check password strength ● Already used by – passwordcheck
  • 32. 32 check_password_hook function ● Five parameters – const char *username, const char *password, int password_type, Datum validuntil_time, bool validuntil_null ● password_type – PASSWORD_TYPE_PLAINTEXT – PASSWORD_TYPE_MD5
  • 33. 33 Writing a check_password_hook ● Example: disallow plain text passwords ● Needs two functions – One to install the hook – One to check the password type
  • 34. 34 Writing a check_password_hook ● First, install the hook void _PG_init(void) { check_password_hook = my_check_password; }
  • 35. 35 Writing a check_password_hook ● The hook itself: – check if the password is encrypted static void my_check_password(const char *username, const char *password, int password_type, Datum validuntil_time, bool validuntil_null) { if (password_type == PASSWORD_TYPE_PLAINTEXT) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("password is not encrypted"))); } }
  • 36. 36 func_beg details ● Get control – Before BEGIN block of a PL/pgsql function ● Usefull to – Log start of each function – Profile functions – Debug functions
  • 37. 37 func_beg use ● Modules using this hook – pldebugger – plprofiler – log_functions (https://github.com/gleu/log_functions)
  • 38. 38 func_beg function ● Two parameters – f (PLpgSQL_execstate *estate, PLpgSQL_function *func) ● estate is a complete structure described in src/pl/plpgsql/plpgsql.h ● func is a complete structure described in src/pl/plpgsql/plpgsql.h – Name, OID, return type, ...
  • 39. 39 Writing a func_beg ● Example: log each function executed ● Needs two functions – One to install the hook – Another one to log the function name
  • 40. 40 Writing a func_beg ● First, initialize the hook static PLpgSQL_plugin plugin_funcs = { my_func_beg }; void _PG_init(void) { PLpgSQL_plugin ** var_ptr = (PLpgSQL_plugin **) find_rendezvous_variable("PLpgSQL_plugin"); *var_ptr = &plugin_funcs; } void load_plugin(PLpgSQL_plugin *hooks) { hooks->func_beg = my_func_beg; }
  • 41. 41 Writing a func_beg ● Log function name static void my_func_beg(PLpgSQL_execstate *estate, PLpgSQL_function *func) { elog(LOG, "Execute function %s", func->fn_name); }
  • 42. 42 Compiling hooks ● Usual Makefile MODULE_big = your_hook OBJS = your_hook.o ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) else subdir = contrib/your_hook top_builddir = ../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif
  • 43. 43 Compiling hooks – example ● Make is your friend (and so is pg_config) $ make USE_PGXS=1 gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after- statement -Wendif-labels -Wformat-security -fno-strict-aliasing -fwrapv - fexcess-precision=standard -fpic -I. -I. -I/opt/postgresql- 9.1/include/server -I/opt/postgresql-9.1/include/internal -D_GNU_SOURCE - c -o your_hook.o your_hook.c gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after- statement -Wendif-labels -Wformat-security -fno-strict-aliasing -fwrapv - fexcess-precision=standard -fpic -shared -o your_hook.so only_encrypted_passwords.o -L/opt/postgresql-9.1/lib -Wl,--as-needed -Wl,- rpath,'/opt/postgresql-9.1/lib',--enable-new-dtags ● Can't use PGXS with PL/pgsql plugins – But will be possible in 9.2 (thanks to Heikki for working on the patch)
  • 44. 44 Installing hooks – from source ● Make is still your friend $ make USE_PGXS=1 install /bin/mkdir -p '/opt/postgresql-9.1/lib' /bin/sh /opt/postgresql-9.1/lib/pgxs/src/makefiles/../../config/install-sh -c -m 755 your_hook.so '/opt/postgresql-9.1/lib/your_hook.so'
  • 45. 45 PGXS ● It's better to rely only on PGXS (if possible) ● Makefile looks like this: MODULE_big = your_hook OBJS = your_hook.o PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) ● So much simpler...
  • 46. 46 Using hooks with shared_preload_libraries ● Install the shared library ● In postgresql.conf – shared_preload_libraries – And possibly other shared library GUCs ● Restart PG
  • 47. 47 Using hooks – example ● Install the hook... ● In postgresql.conf shared_preload_libraries = 'only_encrypted_passwords' ● Restart PostgreSQL $ pg_ctl start server starting 2012-01-28 16:01:32 CET LOG: loaded library "only_encrypted_passwords"
  • 48. 48 Using hooks – example ● Use the hook... postgres=# CREATE USER u1 PASSWORD 'supersecret'; ERROR: password is not encrypted postgres=# CREATE USER u1 PASSWORD 'md5f96c038c1bf28d837c32cc62fa97910a'; CREATE ROLE postgres=# ALTER USER u1 PASSWORD 'f96c038c1bf28d837c32cc62fa97910a'; ERROR: password is not encrypted postgres=# ALTER USER u1 PASSWORD 'md5f96c038c1bf28d837c32cc62fa97910a'; ALTER ROLE
  • 49. 49 Using hooks with LOAD statement ● Install the shared library ● LOAD the library ● ... and use it
  • 50. 50 Using hooks – example ● Install the hook... ● Create the function, and use it: postgres=# CREATE FUNCTION f1() RETURNS boolean LANGUAGE plpgsql AS $$ postgres$# BEGIN postgres$# PERFORM pg_sleep(5); postgres$# RETURN true; postgres$# END postgres$# $$; CREATE FUNCTION hooks=# SET client_min_messages TO log; LOG: duration: 0.132 ms statement: SET client_min_messages TO log; SET hooks=# SELECT f1(); LOG: duration: 5003.180 ms statement: SELECT f1(); f1 ---- t (1 row)
  • 51. 51 Using hooks – example ● LOAD the shared library, and use it... hooks=# LOAD 'logplpgsql'; LOG: duration: 0.373 ms statement: LOAD 'logplpgsql'; LOAD hooks=# SELECT f1(); LOG: Execute function f1 LOG: duration: 5001.466 ms statement: SELECT f1(); [...] hooks=# SELECT f1() FROM generate_series(1, 5); LOG: Execute function f1 LOG: Execute function f1 LOG: Execute function f1 LOG: Execute function f1 LOG: Execute function f1 LOG: duration: 25006.701 ms statement: SELECT f1() FROM generate_series(1, 5); [...]
  • 52. 52 9.2 hooks ● One old hook with enhanced capability ● PGXS support for PL/pgsql hooks ● Two new hooks – A logging hook – And another planer hook
  • 53. 53 9.2 – Enhanced object_access_hook ● DROP statement support for object_access_hook ● Used by sepgsql
  • 54. 54 9.2 hooks – the logging hook ● Logging hook, by Martin Pihlak – emit_log_hook – Intercept messages before they are sent to the server log – Custom log filtering – Used by pg_journal (http://www.pgxn.org/dist/pg_journal/0.1.0/)
  • 55. 55 9.2 hooks – the planner hook ● Planner hook, by Peter Geoghegan – post_parse_analyze_hook – Get control at end of parse analysis – Query normalisation within pg_stat_statements
  • 56. 56 Conclusion ● Hooks are an interesting system to extend the capabilities of PostgreSQL ● Be cautious to avoid adding many of them ● We need more of them :-) ● Examples and slides available on: – https://github.com/gleu/Hooks-in-PostgreSQL