Skip to content

Commit

Permalink
The rollback functions now automatically disable the application trig…
Browse files Browse the repository at this point in the history
…gers, unless they are set in a list of triggers that must not be disabled during the operation. A new emaj_keep_enabled_trigger() function records the triggers that must not be automatically disabled during rollback operations. This decreases the risk that the E-Maj administrator forgets to disable some application triggers at rollback time, thus compromising the tables groups integrity. The triggers that are not automatically disabled are stored into a new emaj_enabled_trigger technical table whose content is managed by the emaj_keep_enabled_trigger() function. In the rollback processing, 2 new elementary steps are created, DIS_APP_TRG and ENA_APP_TRG, to respectively disable and enable an application trigger.
  • Loading branch information
beaud76 committed Apr 28, 2019
1 parent ce2fc8b commit 9c2392c
Show file tree
Hide file tree
Showing 97 changed files with 9,804 additions and 6,725 deletions.
12 changes: 9 additions & 3 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ E-Maj - Change log
<devel>
------
###Enhancements:###
* The rollback functions now automatically disable the application triggers,
unless they are set in a list of triggers that should not be automatically
disabled during the operation. A new emaj_keep_enabled_trigger() function
records the triggers that are not automatically disabled during rollback
operations. This may impact existing user rollback procedures.
* All log objects (tables, sequences, functions) are now located in a schema
named 'emaj_<application-schema>'. And there is now way to change it
anymore. This replaces the use of the now dropped grpdef_log_schema_suffix
Expand Down Expand Up @@ -562,7 +567,7 @@ E-Maj - Change log
old related marks and log tables rows cannot be used for any rollback
operation any more. Nevertheless, log rows remain visible, old marks can
be deleted, renamed or commented, and log statistics can be requested.
* Now that logs may survive to a group start, a mark is automaticaly set
* Now that logs may survive to a group start, a mark is automatically set
at group stop time so that this operation is clearly visible in the marks
list; This mark is named STOP_xxx where this suffix represents the time
of the day.
Expand Down Expand Up @@ -782,7 +787,8 @@ E-Maj - Change log
referencing a table that has no row to rollback.
* in emaj_start_group() and emaj_set_mark_group() functions, avoid empty or
NULL mark names. If the supplied mark name is NULL or empty, a name is
automaticaly generated as "MARK_" followed by digits from the current time.
automatically generated as "MARK_" followed by digits from the current
time.
* fix an invalid column name referenced in emaj_delete_mark_group() function.
* in emaj_delete_mark_group() function, fix an erroneous information
inserted into the emaj_hist table.
Expand Down Expand Up @@ -944,7 +950,7 @@ E-Maj - Change log
rollback operations on multi-processor servers. A PHP command is created
for this purpose: emajParallelRollback.php.
* the emaj_reset_group function is not necessary any more before starting
a group; the log purge is automaticaly done at emaj_start_group function;
a group; the log purge is automatically done at emaj_start_group function.
But the emaj_reset_function remains so user can purge log tables sooner.
* issue a warning at emaj_create_group, emaj_start_group and
emaj_rollback_group if either a table of the group has a foreign key that
Expand Down
2 changes: 1 addition & 1 deletion docs/en/alterGroups.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ or ::

If the parameter representing the mark is not specified, or is empty or *NULL*, a name is automatically generated: “ALTER_%”, where the '%' character represents the current transaction start time with a “hh.mn.ss.mmm” pattern.

An E-Maj rollback operation targeting a mark set before such groups changes does **NOT** automaticaly cancel these changes.
An E-Maj rollback operation targeting a mark set before such groups changes does **NOT** automatically cancel these changes.

However, the administrator can apply the same procedure to reset a tables group to a prior state.

Expand Down
2 changes: 1 addition & 1 deletion docs/en/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ A **log table** has the same structure as its corresponding application table. H

To let E-Maj work, some **other technical objects** are also created at extension installation time:

* 15 tables,
* 16 tables,
* 8 composite and 3 enum types,
* 1 view,
* 2 triggers,
Expand Down
2 changes: 1 addition & 1 deletion docs/en/extractionFunctions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ The used technology may result to doubled backslashes in the output file. These

As the function can generate a large or even very large file (depending on the log volume), it is the user's responsibility to provide a sufficient disk space.

It is also the user's responsibility to deactivate triggers, if any exist, before executing the generated script.
It is also the user's responsibility to deactivate application triggers, if any exist, before executing the generated script.

Using the *emaj_gen_sql_groups()* function, it is possible to generate a sql script related to several groups::

Expand Down
5 changes: 5 additions & 0 deletions docs/en/functionsList.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ E-Maj functions that are available to users are listed in alphabetic order below
| :ref:`emaj_get_previous_mark_group | | group TEXT, | mark TEXT |
| <emaj_get_previous_mark_group>` (V) | | mark TEXT | |
+--------------------------------------------------+-------------------------------+---------------------------------------+
| :ref:`emaj_keep_enabled_trigger | | action TEXT, | #.triggers INT |
| <emaj_keep_enabled_trigger>` | | schema TEXT, | |
| | | table TEXT, | |
| | | triggers.array TEXT[] | |
+--------------------------------------------------+-------------------------------+---------------------------------------+
| :ref:`emaj_log_stat_group | | group TEXT, | SETOF emaj_log_stat_type |
| <emaj_log_stat_group>` (V) | | start.mark TEXT, | |
| | | end.mark TEXT | |
Expand Down
6 changes: 3 additions & 3 deletions docs/en/mainFunctions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ The function also creates the log schemas, if needed.

On the contrary, if specific tablespaces are referenced for any log table or log index, these tablespaces must exist before the function's execution.

The *emaj_create_group()* function also checks the existence of application triggers on any tables of the group. If a trigger exists on a table of the group, a message is returned, suggesting the user to verify that this trigger does not update any tables that would not belong to the group.
The *emaj_create_group()* function also checks the existence of application triggers on any tables of the group. If a trigger exists on a table of the group, a message is returned, suggesting the user to check the impact of this trigger on E-Maj rollbacks.

If a sequence of the group is associated either to a *SERIAL* or *BIGSERIAL* column or to a column created with a *GENERATED AS IDENTITY* clause, and the table that owns this column does not belong to the same tables group, the function also issues a *WARNING* message.

Expand Down Expand Up @@ -199,7 +199,7 @@ The function returns a set of rows with a severity level set to either “*Notic

To be sure that no concurrent transaction updates any table of the group during the rollback operation, the *emaj_rollback_group()* function explicitly sets an *EXCLUSIVE* lock on each table of the group. If transactions updating these tables are running, this can lead to deadlock. If the deadlock processing impacts the execution of the E-Maj function, the error is trapped and the lock operation is repeated, with a maximum of 5 attempts. But tables of the group remain accessible for read only transactions during the operation.

If tables belonging to the group to rollback have triggers, it may be necessary to de-activate them before the rollback and re-activate them after (more details :ref:`here <application_triggers>`).
If tables belonging to the group to rollback have triggers, these triggers are by default temporarily disabled during the operation. Using the :ref:`emaj_keep_enabled_trigger()<emaj_keep_enabled_trigger>` function, it is possible to record triggers as ‘not to be automatically disabled at rollback’ (more details :ref:`here <application_triggers>`).

If a table impacted by the rollback owns a foreign key or is referenced by a foreign key from another table, then this foreign key is taken into account by the rollback operation. If the check of the keys created or modified by the rollback cannot be deferred at the end of the operation (constraint not declared as *DEFERRABLE*), then this foreign key is dropped at the beginning of the rollback and recreated at the end.

Expand Down Expand Up @@ -258,7 +258,7 @@ The function returns a set of rows with a severity level set to either “*Notic

To be sure that no concurrent transaction updates any table of the group during the rollback operation, the *emaj_rollback_group()* function explicitly sets an *EXCLUSIVE* lock on each table of the group. If transactions updating these tables are running, this can lead to deadlock. If the deadlock processing impacts the execution of the E-Maj function, the error is trapped and the lock operation is repeated, with a maximum of 5 attempts. But tables of the group remain accessible for read only transactions during the operation.

If tables belonging to the group to rollback have triggers, it may be necessary to de-activate them before the rollback and re-activate them after (more details :ref:`here <application_triggers>`).
If tables belonging to the group to rollback have triggers, these triggers are by default temporarily disabled during the operation. Using the :ref:`emaj_keep_enabled_trigger()<emaj_keep_enabled_trigger>` function, it is possible to record triggers as ‘not to be automatically disabled at rollback’ (more details :ref:`here <application_triggers>`).

If a table impacted the rollback owns a foreign key or is referenced by a foreign key from another table, then this foreign key is taken into account by the rollback operation. If the check of the keys created or modified by the rollback cannot be deferred at the end of the operation (constraint not declared as *DEFERRABLE*), then this foreign key is dropped at the beginning of the rollback and recreated at the end.

Expand Down
2 changes: 1 addition & 1 deletion docs/en/marksFunctions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Once a mark is protected, any *logged* or *unlogged rollback* attempt is refused

A mark of an "*audit-only*" or an *IDLE* tables group cannot be protected.

When a mark is set, it is not protected. Protected marks of a tables group automaticaly loose their protection when the group is stopped. Warning: deleting a protected mark also deletes its protection. This protection is not moved on an adjacent mark.
When a mark is set, it is not protected. Protected marks of a tables group automatically loose their protection when the group is stopped. Warning: deleting a protected mark also deletes its protection. This protection is not moved on an adjacent mark.

The emaj_unprotect_mark_group() function remove an existing protection on a tables group mark. ::

Expand Down
21 changes: 20 additions & 1 deletion docs/en/otherFunctions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ For each E-Maj schema (*emaj* and each log schema) the function verifies that:
* all tables, functions, sequences and types contained in the schema are either objects of the extension, or linked to created tables groups,
* they don't contain any view, foreign table, domain, conversion, operator or operator class.

Then, for each created tables group, the function performs the same checks as those performed when a group is started, a mark is set, or a rollback is executed (more details :ref:`here <internal_checks>`).
Then, for each created tables group, the function performs the same checks as those performed when a group is started, a mark is set, or a rollback is executed (:ref:`more details <internal_checks>`).

The function returns a set of rows describing the detected discrepancies. If no error is detected, the function returns a single row containing the following messages::

Expand All @@ -26,6 +26,25 @@ The *emaj_verify_all()* function can be executed by any role belonging to *emaj_

If errors are detected, for instance after an application table referenced in a tables group has been dropped, appropriate measures must be taken. Typically, the potential orphan log tables or functions must be manually dropped.

.. _emaj_keep_enabled_trigger:

Not disabling application triggers at E-Maj rollback time
---------------------------------------------------------

Application triggers are automatically disabled during E-Maj rollback operations. Under some circumstances, it may be desirable to keep them enabled (more details :ref:`here <application_triggers>`). The *emaj_keep_enabled_trigger()* function achieves this. It allows to add or remove triggers into/from a list of triggers that do not need to be disabled during rollback operations. ::

SELECT emaj.emaj_keep_enabled_trigger(<action>, <schema.name>, <table.name>, <trigger.name>);

The *<action>* parameter accepts 2 values: ‘ADD’ to add a trigger to the list or ‘REMOVE’ to delete a trigger from the list.

The trigger is identified by the 3 components: schema name, table name and trigger name.

The trigger name may contain ‘%’ and ‘_’ wildcard characters. These characters have the same meaning as in the *LIKE* clause of the SQL language. Thus several triggers of a single table can be processed by a unique function call.

The function returns the number of triggers effectively added or removed.

The function does not process E-Maj triggers (log triggers or triggers protecting against *TRUNCATE*).

.. _emaj_rollback_activity:

Monitoring rollback operations
Expand Down
2 changes: 1 addition & 1 deletion docs/en/otherGroupsFunctions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ The function returns the number of tables and sequences contained by the group.

The *emaj_force_stop_group()* function performs the same actions as the :ref:`emaj_stop_group() <emaj_stop_group>` function, except that:

* it supports the lack of table or trigger to deactivate, generating a “warning” message in such a case,
* it supports the lack of table or E-Maj trigger to deactivate, generating a “warning” message in such a case,
* it does NOT set a stop mark.

Once the function is completed, the tables group is in *IDLE* state. It may then be altered or dropped, using the :ref:`emaj_alter_group() <emaj_alter_group>` or :ref:`emaj_drop_group() <emaj_drop_group>` functions.
Expand Down
10 changes: 6 additions & 4 deletions docs/en/responsibility.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ The :ref:`emaj_start_group() <emaj_start_group>`, :ref:`emaj_stop_group() <emaj_
Management of application triggers
----------------------------------

Triggers may have been created on application tables. It is not rare that these triggers perform one or more updates on other tables. In such a case, it is the E-Maj administrator's responsibility to understand the impact of rollback operations on tables concerned by triggers, and if needed, to take the appropriate measures.
Triggers may have been created on application tables. It is not rare that these triggers perform one or more updates on other tables. In such a case, it is the E-Maj administrator's responsibility to understand the impact of E-Maj rollback operations on tables concerned by triggers, and if needed, to take the appropriate measures.

If the trigger simply adjusts the content of the row to insert or update, the logged data will contain the final value of columns. So the rollback would reset the old values without any problem. But may be it would be necessary to deactivate such a trigger during a rollback operation.
If the trigger simply adjusts the content of the row to insert or update, the logged data will contain the final columns value. So in case of rollback, the log table contains the right data to process. And as the trigger is by default automatically disabled at rollback time, the trigger cannot disturb the rollback processing.

If the trigger updates another table, two cases must be considered:

* if the updated table belong to the same tables group, it would be necessary to deactivate the trigger during a rollback operation, so that E-Maj and only E-Maj performs the updates required by the rollback operation,
* if the updated table does not belong to the same tables group, it is essential to analyse the consequences of a rollback operation, in order to avoid a de-synchronisation between both tables. In such a case, merely deactivating the trigger may not be sufficient.
* if the updated table belongs to the same tables group, the automatic trigger disabling and the rollback of both tables will let them in the expected state,
* if the updated table does not belong to the same tables group, it is essential to analyse the consequences of a rollback operation, in order to avoid a de-synchronisation between both tables. If needed, the :ref:`emaj_keep_enabled_trigger()<emaj_keep_enabled_trigger>` function can be used to not disable the trigger at rollback time. But merely deactivating the trigger may not be sufficient and some other actions may be required.

For more complex triggers, it is essential to perfectly understand their impacts on E-Maj rollbacks and take any appropriate mesure at rollback time.

Internal E-Maj table or sequence change
---------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions docs/en/upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ The operation is very quick et does not alter tables groups. They may remain in

Version specific details:

* The procedure that upgrades a version 2.0.1 into 2.1.0, may modify the :ref:`emaj_group_def <emaj_group_def>` table in order to reflect the fact that the *tspemaj* tablespace is not automaticaly considered as a default tablespace anymore. If *tspemaj* was effectively used as default tablespace for created tables groups, the related *grpdef_log_dat_tsp* and *grpdef_log_idx_tsp* columns content of the *emaj_group_def* table is automatically adjusted so that a future drop and recreate operation would store the log tables and indexes in the same tablespace. The administrator may review these changes to be sure they correspond to his expectations.
* The procedure that upgrades a version 2.0.1 into 2.1.0, may modify the :ref:`emaj_group_def <emaj_group_def>` table in order to reflect the fact that the *tspemaj* tablespace is not automatically considered as a default tablespace anymore. If *tspemaj* was effectively used as default tablespace for created tables groups, the related *grpdef_log_dat_tsp* and *grpdef_log_idx_tsp* columns content of the *emaj_group_def* table is automatically adjusted so that a future drop and recreate operation would store the log tables and indexes in the same tablespace. The administrator may review these changes to be sure they correspond to his expectations.

* The procedure that upgrades a version 2.2.2 into 2.2.3 checks the recorded log sequences values. In some cases, it may ask for a preliminary reset of some tables groups.

* The procedure that upgrades a version 2.3.1 into 3.0.0 changes the structure of log tables: both *emaj_client_ip* and *emaj_client_port* columns are not created anymore. Existing log tables are not modified. Only the new log tables are impacted. But the administrator can :ref:`add these columns<addLogColumns>`, by using the *'alter_log_tables'* parameter.

* The procedure that upgrades a version 3.0.0 into <devel> renames existing log objects. This leads to locking the application tables, which may generate conflicts with the parallel use of these tables.
* The procedure that upgrades a version 3.0.0 into <devel> renames existing log objects. This leads to locking the application tables, which may generate conflicts with the parallel use of these tables. This procedure also issues a warning message indicating that the changes in E-Maj rollback functions regarding the application triggers processing may require changes in user’s procedures.
2 changes: 1 addition & 1 deletion docs/fr/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Une **table de log** a la même structure que la table applicative correspondant

Pour le bon fonctionnement d'E-Maj, un certain nombre d'**objets techniques** sont également créés à l'installation de cette extension :

* 15 tables,
* 16 tables,
* 8 types composites et 3 énumérations,
* 1 vue,
* 2 triggers,
Expand Down
2 changes: 1 addition & 1 deletion docs/fr/extractionFunctions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ La technique mise en œuvre aboutit à avoir des caractères antislash doublés

Comme la fonction peut générer un gros voire très gros fichier (en fonction du volume des logs), il est de la responsabilité de l'utilisateur de prévoir un espace disque suffisant.

Il est aussi de la responsabilité de l'utilisateur de désactiver d'éventuels triggers avant d'exécuter le script généré.
Il est aussi de la responsabilité de l'utilisateur de désactiver d'éventuels triggers applicatifs avant d'exécuter le script généré.

La fonction *emaj_gen_sql_groups()* permet de générer des scripts SQL portant sur plusieurs groupes de tables ::

Expand Down

0 comments on commit 9c2392c

Please sign in to comment.