Architecture ============ To enable rollback operations without requiring a physical backup of the PostgreSQL instance files, E-Maj records all changes applied to application tables so they can be reversed later. Logged SQL Statements ********************* E-Maj records the following SQL operations: * **Row insertions**: - ``INSERT`` (elementary: ``INSERT ... VALUES`` or set-oriented: ``INSERT ... SELECT``) - ``COPY ... FROM`` * **Row updates**: - ``UPDATE`` * **Row deletions**: - ``DELETE`` * **Table truncations**: - ``TRUNCATE`` For statements affecting multiple rows (e.g., ``DELETE FROM ``), **each individual row change is recorded separately**. For example, deleting 1 million rows results in 1 million deletion events being logged. For ``TRUNCATE`` operations, the **entire table content is recorded** before the table is truncated. ---- Created Objects *************** For each application table, E-Maj creates the following objects: * A **dedicated log table** containing data corresponding to updates applied to the application table. * A **trigger** and a **specific function** that, for each row change (*INSERT*, *COPY*, *UPDATE*, or *DELETE*), record all data needed to potentially reverse the action later. * An **additional trigger** to handle **TRUNCATE** statements. * A **sequence** used to quickly count the number of changes recorded in log tables between two marks. .. image:: images/created_objects.png :align: center A **log table** has the **same structure** as its corresponding application table but includes :ref:`additional technical columns`. To support E-Maj functionality, the following **technical objects** are also created during extension installation: * 19 tables, * 1 sequence named *emaj_global_seq*, which assigns a unique, time-increasing identifier to every change recorded in any log table of the database, * 8 composite types and 3 enum types, * 1 view, * Over 180 functions, with more than 80 directly :doc:`callable by users`), * 1 trigger, * 1 dedicated schema named *emaj*, containing all these relational objects, * 2 roles (NOLOGIN): - ``emaj_adm`` to manages E-Maj components. - ``emaj_viewer`` for read-only access to E-Maj components. * 3 event triggers. The *emaj_adm* role owns all log schemas, tables, sequences, and functions. ---- Schemas ******* Almost all technical objects created during E-Maj installation are stored in the ``emaj`` schema. The only exception is the *emaj_protection_trg* event trigger, which resides in the *public* schema. All objects linked to application tables are stored in schemas named ``emaj_``, where ** is the schema name of the application tables. .. note:: Log schemas are **exclusively managed** by E-Maj functions. They **must not** contain any objects other than those created by the extension. ---- Naming Conventions for E-Maj Objects ************************************ For an application table, log objects are named using the table name as a prefix: * **Log table**: ``_log`` * **Log function**: ``_log_fnct`` * **Log sequence**: ``_log_seq`` For application tables with **long names** (over 50 characters), the prefix is generated to comply with PostgreSQL naming rules and avoid conflicts. A log table name may include a suffix like *_1*, *_2*, etc. In such cases, it refers to an **old log table** renamed by an table group alter operation. E-Maj **function names** follow a naming convention: * Functions prefixed with ``emaj_`` are **user-callable**. * Functions prefixed with ``_`` are **internal** and should not be called directly. **Triggers** created on application tables share the same names: * ``emaj_log_trg``: Logs row-level operations (*INSERT*, *UPDATE*, *DELETE*). * ``emaj_trunc_trg``: Handles *TRUNCATE* operations. **Event trigger** names start with ``emaj_`` and end with ``_trg``. ---- Tablespaces *********** By default, E-Maj technical tables are stored in the **default tablespace** set at the instance, database, or session level. The same rule applies to **log tables and their indexes**. However, using :ref:`table group parameters`, you can specify **custom tablespaces** for log tables and/or their indexes.