| 6 | | <sect1 id="triggers"><title>&slony1; Trigger Handling</title> |
|---|
| 7 | | |
|---|
| 8 | | <indexterm><primary>trigger handling</primary></indexterm> |
|---|
| 9 | | |
|---|
| 10 | | <para> &slony1; has had two <quote>flavours</quote> of trigger |
|---|
| 11 | | handling: |
|---|
| 12 | | <itemizedlist> |
|---|
| 13 | | |
|---|
| 14 | | <listitem><para> In versions up to 1.2, &postgres; had no awareness of |
|---|
| 15 | | replication, with the result that &slony1; needed to |
|---|
| 16 | | <quote>hack</quote> on the system catalog in order to deactivate, on |
|---|
| 17 | | subscribers, triggers that ought not to run.</para> |
|---|
| 18 | | |
|---|
| 19 | | <para> This has had a number of somewhat painful side-effects including:</para> |
|---|
| 20 | | <itemizedlist> |
|---|
| 21 | | |
|---|
| 22 | | <listitem><para> Corruption of the system catalog on subscribers, as |
|---|
| 23 | | existing triggers, that generally need to be hidden, are |
|---|
| 24 | | <quote>hacked</quote>, via <envar>pg_catalog.pg_trigger</envar>, to |
|---|
| 25 | | point to the index being used by &slony1; as its <quote>primary |
|---|
| 26 | | key</quote>.</para> |
|---|
| 27 | | |
|---|
| 28 | | <para> The very same thing was true for rules. </para> |
|---|
| 29 | | |
|---|
| 30 | | <para> This had the side-effect that |
|---|
| 31 | | <application>pg_dump</application> could not be used to pull proper |
|---|
| 32 | | schemas from subscriber nodes.</para></listitem> |
|---|
| 33 | | |
|---|
| 34 | | <listitem><para> It introduced the need to take out exclusive locks on |
|---|
| 35 | | <emphasis>all replicated tables</emphasis> when processing |
|---|
| 36 | | &rddlchanges; as triggers on each replicated table would need to be |
|---|
| 37 | | dropped and re-added during the course of |
|---|
| 38 | | processing.</para></listitem> |
|---|
| | 6 | <sect1 id="triggers"><title>Gestion des triggers &slony1;</title> |
|---|
| | 7 | |
|---|
| | 8 | <indexterm><primary>gestion des triggers</primary></indexterm> |
|---|
| | 9 | |
|---|
| | 10 | <para> &slony1; a connu deux <quote>types</quote> des gestion de triggers |
|---|
| | 11 | |
|---|
| | 12 | <itemizedlist> |
|---|
| | 13 | |
|---|
| | 14 | <listitem><para> Jusqu'Ã la version 1.2, &postgres; n'avait pas conscience |
|---|
| | 15 | de la réplication, ce qui impliquait que &slony1; avait besoin que l'on |
|---|
| | 16 | <quote>modifie directement</quote> le catalogue systÚme afin de |
|---|
| | 17 | désactiver, sur les noeuds abonnés, les triggers qui ne devaient pas être |
|---|
| | 18 | exécutés.</para> |
|---|
| | 19 | |
|---|
| | 20 | <para> Ceci provoquait un nombre d'effets secondaires pénibles, tels que :</para> |
|---|
| | 21 | <itemizedlist> |
|---|
| | 22 | |
|---|
| | 23 | <listitem><para> La corruption du catalogue systÚme sur les noeuds abonnés, car |
|---|
| | 24 | les triggers existants, qui sont généralement cachés, sont <quote>modifiés |
|---|
| | 25 | directement </quote>, en modifiant <envar>pg_catalog.pg_trigger</envar>, pour qu'elle |
|---|
| | 26 | désigne les index utilisés par &slony1;, comme <quote>clé primaire</quote>.</para> |
|---|
| | 27 | |
|---|
| | 28 | <para> Ceci est également vrai pour les rÚgles ("rules"). </para> |
|---|
| | 29 | |
|---|
| | 30 | <para> L'effet secondaire était que |
|---|
| | 31 | <application>pg_dump</application> ne pouvait pas être utilisé pour |
|---|
| | 32 | récupérer proprement les schémas des noeuds abonnés.</para></listitem> |
|---|
| | 33 | |
|---|
| | 34 | <listitem><para>Cela introduit la nécessité de poser des verrous exclusifs |
|---|
| | 35 | sur <emphasis>toutes les tables répliquées</emphasis> lors de la commande |
|---|
| | 36 | &rddlchanges; puisque les triggers de chaque table répliquée devaient être |
|---|
| | 37 | supprimés et ajoutés à nouveau par cette opération.</para></listitem> |
|---|
| 87 | | <listitem><para> Before replication is set up, |
|---|
| 88 | | <emphasis>every</emphasis> database starts out in |
|---|
| 89 | | <quote>origin</quote> status, and, by default, all triggers are of the |
|---|
| 90 | | <command>ENABLE TRIGGER</command> form, so they all run, as is normal |
|---|
| 91 | | in a system uninvolved in replication. </para> </listitem> |
|---|
| 92 | | |
|---|
| 93 | | <listitem><para> When a &slony1; subscription is set up, on the origin |
|---|
| 94 | | node, both the <function>logtrigger</function> and |
|---|
| 95 | | <function>denyaccess</function> triggers are added, the former being |
|---|
| 96 | | enabled, and running, the latter being disabled, so it does not |
|---|
| 97 | | run. </para> |
|---|
| 98 | | |
|---|
| 99 | | <para> From a locking perspective, each <xref |
|---|
| 100 | | linkend="stmtsetaddtable"/> request will need to briefly take out an |
|---|
| 101 | | exclusive lock on each table as it attaches these triggers, which is |
|---|
| 102 | | much the same as has always been the case with &slony1;. </para> |
|---|
| 103 | | </listitem> |
|---|
| 104 | | |
|---|
| 105 | | <listitem><para> On the subscriber, the subscription process will add |
|---|
| 106 | | the same triggers, but with the polarities <quote>reversed</quote>, to |
|---|
| 107 | | protect data from accidental corruption on subscribers. </para> |
|---|
| 108 | | |
|---|
| 109 | | <para> From a locking perspective, again, there is not much difference |
|---|
| 110 | | from earlier &slony1; behaviour, as the subscription process, due to |
|---|
| 111 | | running <command>TRUNCATE</command>, copying data, and altering table |
|---|
| 112 | | schemas, requires <emphasis>extensive</emphasis> exclusive table |
|---|
| 113 | | locks, and the changes in trigger behaviour do not change those |
|---|
| 114 | | requirements. </para> |
|---|
| 115 | | |
|---|
| 116 | | <para> However, note that the ability to enable and disable triggers |
|---|
| 117 | | in a &postgres;-supported fashion means that we have had no need to |
|---|
| 118 | | <quote>corrupt</quote> the system catalog, so we have the considerable |
|---|
| 119 | | advantage that <application>pg_dump</application> may be used to draw |
|---|
| 120 | | a completely consistent backup against any node in a &slony1; |
|---|
| 121 | | cluster.</para> |
|---|
| 122 | | |
|---|
| 123 | | </listitem> |
|---|
| 124 | | |
|---|
| 125 | | <listitem><para> If you take a <application>pg_dump</application> of a |
|---|
| 126 | | &slony1; node, and drop out the &slony1; namespace, this now cleanly |
|---|
| 127 | | removes <emphasis>all</emphasis> &slony1; components, leaving the |
|---|
| 128 | | database, <emphasis>including its schema,</emphasis> in a |
|---|
| 129 | | <quote>pristine</quote>, consistent fashion, ready for whatever use |
|---|
| 130 | | may be desired. </para> </listitem> |
|---|
| 131 | | |
|---|
| 132 | | <listitem><para> &rddlchanges; is now performed in quite a different |
|---|
| 133 | | way: rather than altering each replicated table to <quote>take it out |
|---|
| 134 | | of replicated mode</quote>, &slony1; instead simply shifts into the |
|---|
| 135 | | <command>local</command> status for the duration of this event. </para> |
|---|
| 136 | | |
|---|
| 137 | | <para> On the origin, this deactivates the |
|---|
| 138 | | <function>logtrigger</function> trigger. </para> |
|---|
| 139 | | |
|---|
| 140 | | <para> On each subscriber, this deactivates the |
|---|
| 141 | | <function>denyaccess</function> trigger. </para> |
|---|
| 142 | | |
|---|
| 143 | | <para> This may be expected to allow DDL changes to become |
|---|
| 144 | | <emphasis>enormously</emphasis> less expensive, since, rather than needing to |
|---|
| 145 | | take out exclusive locks on <emphasis>all</emphasis> replicated tables (as used |
|---|
| 146 | | to be mandated by the action of dropping and adding back the |
|---|
| 147 | | &slony1;-created triggers), the only tables that are locked are those |
|---|
| 148 | | ones that the DDL script was specifically acting on. </para> |
|---|
| 149 | | |
|---|
| 150 | | </listitem> |
|---|
| 151 | | |
|---|
| 152 | | <listitem><para> At the time of invoking <xref linkend="stmtmoveset"/> |
|---|
| 153 | | against the former origin, &slony1; must transform that node into a |
|---|
| 154 | | subscriber, which requires dropping the <function>lockset</function> |
|---|
| 155 | | triggers, disabling the <function>logtrigger</function> triggers, and |
|---|
| 156 | | enabling the <function>denyaccess</function> triggers. </para> |
|---|
| 157 | | |
|---|
| 158 | | <para> At about the same time, when processing <xref |
|---|
| 159 | | linkend="stmtmoveset"/> against the new origin, &slony1; must transform |
|---|
| 160 | | that node into an origin, which requires disabling the formerly active |
|---|
| 161 | | <function>denyaccess</function> triggers, and enabling the |
|---|
| 162 | | <function>logtrigger</function> triggers. </para> |
|---|
| 163 | | |
|---|
| 164 | | <para> From a locking perspective, this will not behave differently |
|---|
| 165 | | from older versions of &slony1;; the locking that takes place here is |
|---|
| 166 | | quite necessary. </para> |
|---|
| 167 | | |
|---|
| 168 | | </listitem> |
|---|
| 169 | | |
|---|
| 170 | | <listitem><para> Similarly to <xref linkend="stmtmoveset"/>, <xref |
|---|
| 171 | | linkend="stmtfailover"/> transforms a subscriber node into an origin, |
|---|
| 172 | | which requires disabling the formerly active |
|---|
| 173 | | <function>denyaccess</function> triggers, and enabling the |
|---|
| 174 | | <function>logtrigger</function> triggers. The locking implications |
|---|
| 175 | | are again, much the same. </para> </listitem> |
|---|
| | 124 | <listitem><para> Avant que la réplication soit en place, |
|---|
| | 125 | <emphasis>chaque</emphasis> chaque base de données démarre avec |
|---|
| | 126 | le statut <quote>origin<quote> et, par défaut, tous les triggers sont du type |
|---|
| | 127 | <command>ENABLE TRIGGER</command>, afin qu'ils soient exécutés, comme |
|---|
| | 128 | dans un systÚme non-répliqué. </para> </listitem> |
|---|
| | 129 | |
|---|
| | 130 | <listitem><para> Lorsqu'un abonnement &slony1; est mis en place, |
|---|
| | 131 | sur le noeud d'origine, les triggers <function>logtrigger</function> |
|---|
| | 132 | et <function>denyaccess</function> sont ajoutés, le premier est activé |
|---|
| | 133 | et exécuté, le second est désactivé. </para> |
|---|
| | 134 | |
|---|
| | 135 | <para> Au niveau des verrous, chaque instructions <xref |
|---|
| | 136 | linkend="stmtsetaddtable"/> demandera briÚvement un verrou |
|---|
| | 137 | exclusif sur les table ou seront attachés les triggers, ce qui a |
|---|
| | 138 | toujours été le cas avec &slony1;. </para> |
|---|
| | 139 | </listitem> |
|---|
| | 140 | |
|---|
| | 141 | <listitem><para> Sur le noeud abonné, le processus d'abonnement ajoutera |
|---|
| | 142 | les même triggers, mais avec une polarité <quote>inversée</quote>, |
|---|
| | 143 | pour protéger les données d'une corruption accidentelle. </para> |
|---|
| | 144 | |
|---|
| | 145 | <para> Au niveau des verrous, encore une fois, cela fait peu de différences |
|---|
| | 146 | avec l'ancien comportement, car le processus d'abonnement qui utilise |
|---|
| | 147 | <command>TRUNCATE</command>, copie les données, et altÚre le schéma des tables |
|---|
| | 148 | nécessite de <emphasis>nombreux</emphasis> verrous exclusifs sur les tables, |
|---|
| | 149 | et les changements dans le comportement des triggers ne change pas ce besoin. |
|---|
| | 150 | </para> |
|---|
| | 151 | |
|---|
| | 152 | <para> Toutefois, notez que la capacité d'activer ou désactiver les triggers |
|---|
| | 153 | d'une maniÚre supportée par &postgres; signifie qu'il n'est pas nécessaire |
|---|
| | 154 | de <quote>corrompre</quote> le catalogue systÚme, ainsi nous avons l'avantage |
|---|
| | 155 | considérable de pouvoir utiliser <application>pg_dump</application> pour |
|---|
| | 156 | obtenir une sauvegarde complÚte et consistante sur n'importe quel noeud du |
|---|
| | 157 | cluster &slony1;.</para> |
|---|
| | 158 | |
|---|
| | 159 | </listitem> |
|---|
| | 160 | |
|---|
| | 161 | <listitem><para> Si vous effectuez un <application>pg_dump</application> sur |
|---|
| | 162 | un noeud &slony1;, et supprimez le namespace &slony1;, cela supprime |
|---|
| | 163 | <emphasis>tous</emphasis> les composants &slony1; et laisse la base |
|---|
| | 164 | de données, <emphasis>y compris son schéma</emphasis>, dans un |
|---|
| | 165 | état consistant et <quote>vierge</quote>, prêt pour n'importe quelle |
|---|
| | 166 | utilisation. </para> </listitem> |
|---|
| | 167 | |
|---|
| | 168 | <listitem><para> L'opération &rddlchanges; est désormais réalisée d'une façon |
|---|
| | 169 | toute à fait différente : plutÎt que d'altérer chaque table répliquée pour |
|---|
| | 170 | la <quote>retirer du mode répliqué</quote>, &slony1; glissera simplement |
|---|
| | 171 | en statut <command>local</command> pour le temps de l'opération. </para> |
|---|
| | 172 | |
|---|
| | 173 | <para> Sur le noeud origine, cela désactive le trigger |
|---|
| | 174 | <function>logtrigger</function>. </para> |
|---|
| | 175 | |
|---|
| | 176 | <para> Sur chaque noeud abonné, cela désactive le trigger |
|---|
| | 177 | <function>denyaccess</function>. </para> |
|---|
| | 178 | |
|---|
| | 179 | <para>Ceci devrait rendre les modifications DDL |
|---|
| | 180 | <emphasis>énormément</emphasis> moins coûteuses, car plutÎt que de poser des verrous |
|---|
| | 181 | exclusif sur <emphasis>toutes</emphasis> les tables répliquées ( nécessaire pour les |
|---|
| | 182 | opérations de suppression et re-création des triggers &slony1;), seules les tables impactées |
|---|
| | 183 | par le script DDL sont verrouillées. </para> |
|---|
| | 184 | |
|---|
| | 185 | </listitem> |
|---|
| | 186 | |
|---|
| | 187 | <listitem><para> Au moment d'invoquer <xref linkend="stmtmoveset"/> sur l'ancien |
|---|
| | 188 | noeud origine, &slony1; doit transformer ce noeud en noeud abonné, ce qui nécessite |
|---|
| | 189 | de supprimer les triggers <function>lockset</function>, désactiver les triggers |
|---|
| | 190 | <function>logtrigger</function> et activer les triggers <function>denyaccess</function>. |
|---|
| | 191 | </para> |
|---|
| | 192 | |
|---|
| | 193 | <para> Au même moment, en réalisant <xref linkend="stmtmoveset"/> sur le |
|---|
| | 194 | nouveau noeud origine, &slony1; doit transformer ce noeud en origine, ce qui |
|---|
| | 195 | implique la désactivation des triggers <function>denyaccess</function>, |
|---|
| | 196 | et d'activer les triggers <function>logtrigger</function>. |
|---|
| | 197 | </para> |
|---|
| | 198 | |
|---|
| | 199 | <para> Au niveau des verrous, ceci ne change pas par rapport aux nouvelles versions |
|---|
| | 200 | de &slony1; le verrouillage effectué ici est tout à fait nécessaire.</para> |
|---|
| | 201 | |
|---|
| | 202 | </listitem> |
|---|
| | 203 | |
|---|
| | 204 | <listitem><para> De le même maniÚre que <xref linkend="stmtmoveset"/>, <xref |
|---|
| | 205 | linkend="stmtfailover"/> transforme un noeud abonné en noeud origine, ce qui |
|---|
| | 206 | nécessite de désactiver les triggers <function>denyaccess</function>, et |
|---|
| | 207 | d'activer les triggers <function>logtrigger</function>. Encore une fois, |
|---|
| | 208 | l'implémentation des verrous est quasiment identique.</para> |
|---|
| | 209 | </listitem> |
|---|