/supa_audit

Generic Table Auditing

Primary LanguagePLpgSQLApache License 2.0Apache-2.0

supa_audit

PostgreSQL version Tests


Source Code: https://github.com/supabase/supa_audit


The supa_audit PostgreSQL extension is a generic solution for tracking changes to tables' data over time.

The audit table, audit.record_version, leverages each records primary key values to produce a stable record_id::uuid, enabling efficient (linear time) history queries.

Usage

create extension supa_audit cascade;

create table public.account(
    id int primary key,
    name text not null
);

-- Enable auditing
select audit.enable_tracking('public.account'::regclass);

-- Insert a record
insert into public.account(id, name)
values (1, 'Foo Barsworth');

-- Update a record
update public.account
set name = 'Foo Barsworht III'
where id = 1;

-- Delete a record
delete from public.account
where id = 1;

-- Truncate the table
truncate table public.account;

-- Review the history
select
    *
from
    audit.record_version;

/*
 id |              record_id               |            old_record_id             |    op    |               ts                | table_oid | table_schema | table_name |                 record                 |             old_record
----+--------------------------------------+--------------------------------------+----------+---------------------------------+-----------+--------------+------------+----------------------------------------+------------------------------------
  1 | 57ca384e-f24c-5af5-b361-a057aeac506c |                                      | INSERT   | Thu Feb 10 17:02:25.621095 2022 |     16439 | public       | account    | {"id": 1, "name": "Foo Barsworth"}     |
  2 | 57ca384e-f24c-5af5-b361-a057aeac506c | 57ca384e-f24c-5af5-b361-a057aeac506c | UPDATE   | Thu Feb 10 17:02:25.622151 2022 |     16439 | public       | account    | {"id": 1, "name": "Foo Barsworht III"} | {"id": 1, "name": "Foo Barsworth"}
  3 |                                      | 57ca384e-f24c-5af5-b361-a057aeac506c | DELETE   | Thu Feb 10 17:02:25.622495 2022 |     16439 | public       | account    |                                        | {"id": 1, "name": "Foo Barsworth III"}
  4 |                                      |                                      | TRUNCATE | Thu Feb 10 17:02:25.622779 2022 |     16439 | public       | account    |                                        |
(4 rows)
*/

-- Disable auditing
select audit.disable_tracking('public.account'::regclass);

Test

Run the Tests

nix-shell --run "pg_13_supa_audit make installcheck"

Adding Tests

Tests are located in test/sql/ and the expected output is in test/expected/

The output of the most recent test run is stored in results/.

When the output for a test in results/ is correct, copy it to test/expected/ and the test will pass.

Interactive Prompt

nix-shell --run "pg_13_supa_audit psql"

Performance

Write Throughput

Auditing tables reduces throughput of inserts, updates, and deletes.

It is not reccomended to enable tracking on tables with a peak write throughput over 3k ops/second.

Querying

When querying a table's history, filter on the indexed table_oid rather than the table_name and schema_name columns.

select
    *
from
    audit.record_version
where
    table_oid = 'public.account'::regclass::oid;