emaj

Enables fine-grained write logging and time travel on subsets of the database.

Overview

PackageVersionCategoryLicenseLanguage
emaj4.7.1TIMEGPL-3.0SQL
IDExtensionBinLibLoadCreateTrustRelocSchema
1050emajNoYesNoYesNoNoemaj
Relateddblink btree_gist timescaledb_toolkit timescaledb periods temporal_tables table_version pg_cron pg_partman timeseries

max_prepared_transactions

Version

TypeRepoVersionPG VerPackageDeps
EXTMIXED4.7.11817161514emajdblink, btree_gist
RPMPGDG4.7.11817161514e-maj_$v-
DEBPIGSTY4.7.11817161514postgresql-$v-emaj-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
d12.aarch64
d13.x86_64
d13.aarch64
u22.x86_64
u22.aarch64
u24.x86_64
u24.aarch64

Build

You can build the DEB packages for emaj using pig build:

pig build pkg emaj         # build DEB packages

Install

You can install emaj directly. First, make sure the PGDG and PIGSTY repositories are added and enabled:

pig repo add pgsql -u          # Add repo and update cache

Install the extension using pig or apt/yum/dnf:

pig install emaj;          # Install for current active PG version
pig ext install -y emaj -v 18  # PG 18
pig ext install -y emaj -v 17  # PG 17
pig ext install -y emaj -v 16  # PG 16
pig ext install -y emaj -v 15  # PG 15
pig ext install -y emaj -v 14  # PG 14
dnf install -y e-maj_18       # PG 18
dnf install -y e-maj_17       # PG 17
dnf install -y e-maj_16       # PG 16
dnf install -y e-maj_15       # PG 15
dnf install -y e-maj_14       # PG 14
apt install -y postgresql-18-emaj   # PG 18
apt install -y postgresql-17-emaj   # PG 17
apt install -y postgresql-16-emaj   # PG 16
apt install -y postgresql-15-emaj   # PG 15
apt install -y postgresql-14-emaj   # PG 14

Create Extension:

CREATE EXTENSION emaj CASCADE;  -- requires: dblink, btree_gist

Usage

E-Maj: logs and rollbacks table content changes

Documentation | Emaj_web GUI

E-Maj logs table changes (Inserts, Updates, Deletes, Truncates) performed on one or several sets of tables, and can efficiently cancel these changes if needed, resetting a tables set to a predefined stable state.

In development environments, it helps testing applications by providing an easy way to rollback all updates generated by program execution, and replay processing as many times as needed.

In production environments, it provides:

  • History of changes performed on tables for examination
  • Inter-batch savepoints on groups of tables
  • Easy “restore” of table groups to a stable state without stopping the cluster
  • Multiple savepoints during batch windows, each usable as a restore point

Concepts

Tables Group

A tables group is a set of application tables that live at the same rhythm — their content can be restored as a whole if needed. A group can include tables and sequences across different schemas. Each group operates in one of two states: LOGGING or IDLE, and can be designated as:

  • ROLLBACKABLE (standard) — supports both logging and rollback
  • AUDIT_ONLY — allows change recording without rollback capability, even for tables without primary keys or UNLOGGED tables

Mark

A mark represents a snapshot moment in a tables group’s lifecycle, capturing a stable state across all group members. Marks have unique names within a group.

Rollback

Rollback operations restore tables and sequences to their state when a specific mark was established:

  • Unlogged rollback — cancelled updates leave no trace
  • Logged rollback — cancellations are recorded, allowing subsequent reversal

Note: E-Maj rollback differs fundamentally from PostgreSQL’s native transaction rollback.

Main Functions

Start a Tables Group

SELECT emaj.emaj_start_group('my_group', 'mark_1');

Activates update recording. The group must be in IDLE state. Automatically creates an initial mark.

Set an Intermediate Mark

SELECT emaj.emaj_set_mark_group('my_group', 'mark_2');

Records a point-in-time snapshot of the application state. The group must be in LOGGING state.

Rollback a Tables Group

Unlogged rollback (restores tables, no trace of cancellation):

SELECT * FROM emaj.emaj_rollback_group('my_group', 'mark_1');

Logged rollback (permits reverting the rollback itself):

SELECT * FROM emaj.emaj_logged_rollback_group('my_group', 'mark_1');

Both support the '_EMAJ_LAST_MARK_' keyword for targeting the most recent mark.

Stop a Tables Group

SELECT emaj.emaj_stop_group('my_group');

Deactivates logging, changing the group state from LOGGING to IDLE.

Multi-Group Operations

Functions support batch operations on multiple groups simultaneously:

SELECT emaj.emaj_start_groups('{"group1","group2"}', 'multi_mark');
SELECT emaj.emaj_set_mark_groups('{"group1","group2"}', 'common_mark');
SELECT * FROM emaj.emaj_rollback_groups('{"group1","group2"}', 'common_mark');
SELECT emaj.emaj_stop_groups('{"group1","group2"}');

Examining Changes

E-Maj provides functions to count and examine data content changes between marks, and to generate SQL scripts that replay logged changes. This is useful for auditing and debugging.

Emaj_web

Emaj_web is a PHP-based web GUI tool for user-friendly E-Maj administration. It is available on GitHub and described in the documentation.


Last Modified 2026-03-12: add pg extension catalog (95749bf)