root/traduc/trunk/slony/ddlchanges.xml

Revision 1173, 14.4 kB (checked in by gleu, 3 weeks ago)

Modifications pour permettre la génération du manuel.
Patch de Christophe Bouchet, avec quelques modifications supplémentaires de ma
part.
Cependant, il reste encore du travail pour avoir une génération parfaite.

Line 
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- DerniÚre modification
3      le       $Date$
4      par      $Author$
5      révision $Revision$ -->
6
7 <sect1 id="ddlchanges">
8 <title>Changements du schéma de la base (DDL)</title>
9
10 <indexterm>
11  <primary>Changements DDL</primary>
12  <secondary>changements du schéma de la base</secondary>
13 </indexterm>
14
15 <para>Lorsque des changements sont faits sur la base,
16 <emphasis>tels que</emphasis> - l'ajout de champs à une table, il est nécessaire
17 de la faire prudemment, pour éviter que certains noeuds
18 ne soient bloqués lors de la création de certaines tables
19 .</para>
20
21 <para>Si vous opérez les changements à travers &slony1; via <xref
22 linkend="stmtddlscript"/> (slonik) / &funddlscript; (fonction stockée),
23 cela vous garantie que les changements prendront effets
24 au même niveau dans les flux de transactions sur tous les noeuds. Cela n'est pas aussi vital
25 si vous pouvez arrêter votre systÚme pour appliquer vos modifications de schéma,
26 mais si vous voulez faire vos mises à jour en même temps que vos transactions continuent de processer à travers votre systÚme,
27 cela est nécessaire.  </para>
28
29 <para>Il est essentiel d'utiliser <command>EXECUTE SCRIPT</command> si vous
30 modifiez des tables pour changer leurs schémas.  Si vous ne le faites pas, vous pouvez rencontrer
31 des problÚmes <link linkend="neededexecddl"> décrits
32 ici </link> où les triggers des tables modifiées ne tiennent pas compte des changements
33 de schéma faits. Cela peut conduire à une corruption de données sur le
34 noeud abonné.</para>
35
36 <para>Il est utile de faire quelques <quote>recommandations</quote> sur
37  <xref linkend="stmtddlscript"/>:</para>
38
39 <itemizedlist>
40
41 <listitem><para>Le script <emphasis>ne doit pas</emphasis> contenir
42 de transaction <command>BEGIN</command> ou <command>END</command>
43 , car il s'exécute déjà dans une transaction.
44 Avec la version 8 de &postgres;, l'introduction des transactions imbriquées
45 change cela quelque peu, mais vous devez rester attentif au fait que
46 les actions du script sont exécutées comme une transaction simple
47 dans laquelle on ne maîtrise pas le <command>BEGIN</command> et le <command>END</command>
48 .</para></listitem>
49
50 <listitem><para>Si il y a une erreur<emphasis>quelconque</emphasis> dans le script
51 , ou un problÚme quelconque sur la maniÚre dont il s'éxécute sur un noeud particulier,
52 cela conduira le démon <xref linkend="slon"/> de ce noeud à paniquer et à tomber.
53 Vous pouvez consulter plusieurs types de messages attendus lors d'un déroulement normal ou anormal
54 à <xref linkend="ddllogs"/>.  Si vous redémarrez le &lslon;, il tentera,
55 de maniÚre trÚs probable, de
56 <emphasis>rejouer</emphasis> le script DDL, ce qui conduira certainement au même échec que la premiÚre tentative.
57 J'ai eu un tel scénario, m'obligeant à supprimer du noeud
58 <quote>maître</quote> l'évÚnement de la table
59 <envar>sl_event</envar> pour arrêter de le voir tomber en échec.</para>
60
61 <para> La conséquence de cela est qu'il est
62 <emphasis>vital</emphasis> que les modifications ne soient pas faites
63 de maniÚre hasardeuse sur un noeud ou un autre. Les schémas doivent toujours
64 rester synchronisés.</para>
65 </listitem>
66
67 <listitem><para> Pour &lslon; aussi, à ce niveau, <quote>panic</quote>
68 est probablement la réponse
69 <emphasis>correcte</emphasis>, car il permet au DBA de sortir la base du noeud défecteux,
70 de fixer manuellement le problÚme en supprimant l'évÚnement incorrect et de redémarrer
71 &lslon;.  Vous pouvez être certain que les mises à jour faites
72 <emphasis>aprÚs</emphasis> le changement DDL sur le noeud maître sont enregistrées
73 dans une file d'attente, en attente d'être traitées par l'abonné.
74 Vous ne courrez ainsi pas le risque que des updates non centralisés par DDL
75
76 You don't run the
77 risk of there being updates made that depended on the DDL changes in
78 order to be correct.</para></listitem>
79
80 <listitem><para> Lorsque vous exécutez <xref linkend="stmtddlscript"/>, cela
81 conduit &lslonik; à poser, <emphasis>pour chaque table faisant partie du jeu de réplication</emphasis>,
82 un verrou exclusif table.</para>
83
84 <para> Cela commence par la pose du lock, l'altération de la table pour supprimer les
85 &slony1; triggers, et la restauration de tous les triggers qui ont étés cachés
86
87 <screen>
88 BEGIN;
89 LOCK TABLE table_name;
90 SELECT _oxrsorg.altertablerestore(tab_id);
91 --tab_id is _slony_schema.sl_table.tab_id
92 </screen></para>
93
94 <para> AprÚs l'exécution du script, chaque table est
95 <quote>restorée</quote> dans le but d'ajouter en fin soit le trigger qui collecte
96 les mises à jour sur le noeud origine soit celui qui rejette les mises à jour sur l'abonné.
97
98 <screen>
99 SELECT _oxrsorg.altertableforreplication(tab_id);
100 --tab_id is _slony_schema.sl_table.tab_id
101 COMMIT;
102 </screen></para>
103
104 <para>Notez que c'est ce qui permet à &slony1; de prendre connaissance de
105 l'altération de tables: <emphasis>avant</emphasis>
106 ce <command>SYNC</command>, &slony1; réplique des tuples suivant le
107  <emphasis>vieux</emphasis>
108 schéma; <emphasis>aprÚs</emphasis> le script <command>DDL_SCRIPT</command>,
109 les tuples sont répliqués suivant le <emphasis>nouveau</emphasis>
110 schéma. </para>
111
112 <para> Sur un systÚme réalisant de nombreuses mises à jour, il peut être
113 difficile <quote>d'obtenir</quote> tous les verrous nécéssaires.
114  Les verrous peuvent conduire à des deadlocks.
115 Vous pouvez régler le problÚme de 2 maniÚres différentes :
116 </para></listitem>
117
118 <listitem><para> Vous devez envisager de <link linkend="definesets"> définir des jeux de réplication </link>
119  représentant un plus petit nombre de tables
120 de maniÚre à ce que moins de verrous soient posés et permettent au script DDL d'être joué.</para>
121
122 <para> Si un script DDL affecte une seule table, il ne devrait pas
123 être nécessaire de verrouiller <emphasis>toutes</emphasis> les tables de
124 l'application.</para>
125
126 <note><para> Véritablement, à partir de la version 1.1.5 ou plus, ce
127 n'est <emphasis>plus vrai.</emphasis> Le danger que quelqu'un opÚre des changements
128 DDL interférant avec le jeux de réplication est suffisamment évident pour que
129 &lslon; verrouille  <emphasis>toutes</emphasis> les tables
130 répliquées, qu'elles soient ou pas dans le jeu de réplication
131 . </para></note></listitem>
132
133 <listitem><para> Vous pouvez avoir besoin de faire un arrêt de votre systÚme
134 pour vous assurer que vos applications ne demandent pas des verrous
135 qui rentreraient en conflit avec ceux dont vous auriez besoin pour faire les changements de schéma de base.
136 .</para></listitem>
137
138 <listitem><para> Dans les versions 1.0 à 1.1.5 de &slony1; le script s'exécute
139 comme une simple requête, ce qui peut poser problÚme si vous réaliser des modifications
140 complexes. A partir de la version 1.2, le script est découpé en traitements SQL individuels,
141 et chaque requête est soumise séparemment, ce qui est préférable.</para>
142
143 <para> Le problÚme avec une requête traitant une <quote>requête imbriquée</quote> est que le parser SQL
144 réalise son plan d'exécution pour le jeu entier de requête <emphasis>avant même</emphasis>
145  l'exécution de la requête.</para>   
146
147 <para> Cela ne pose pas de problÚme particulier si les requêtes
148 sont indépendantes les unes des autres, tel que 2 requêtes d'ajout de 2 colonnes
149 à une table.</para>
150
151 <para> <command> alter table t1 add column c1 integer; alter table t1 add
152 column c2 integer; </command></para>
153
154 <para> Par contre, les problÚmes se rencontrent si vous devez référencer une requête précédente.
155 Considérer la requête DDL suivante ...</para>
156
157 <para><command> alter table t1 add column c1 integer; create sequence s1;
158 update t1 set c1=nextval('s1'); alter table t1 alter column c1 set not
159 null; alter table t1 add primary key(c1); </command></para>
160
161 <para> Jusqu'à la version 1.2 de  &slony1; cette requête aurait <emphasis> échouée
162 </emphasis>, lors de l'atteinte de la conditon
163 <command>UPDATE</command> , indiquant l'inexistence de la colonne
164 <envar>c1</envar>.  Cela est dû au fait que <emphasis>toutes</emphasis> ces requêtes sont découpées
165  et analysées avant même l'exécution de l'une d'entre elles.
166 Ainsi, l'<command>UPDATE</command> est évalué sur une table avant que la colonne n'ai été ajoutée.
167  Oops. </para>
168
169 <para>Si vous avez des versions antérieures, vous pouvez contourner cela en
170 invoquant une requête séparée <xref linkend="stmtddlscript"/> dans un script distinct
171 , en générant un nouveau script pour chaque requête qui  référence un objet créé dans une requête précédente.
172 . </para>
173
174 <para> Dans le version 1.2 de &slony1; , il y a un mécanisme qui sépare
175 le script DDL en requêtes individuelles.  Chaque requête est soumise par une requête
176 <function>PQexec()</function> séparée, ce qui ne pose plus de problÚme. </para>
177 </listitem>
178
179 </itemizedlist>
180
181 <para>Malheureusement, cela conduit à une vulnérabilité du script DDL, suivant la maniÚre
182 dont les changements DDL sont écrits.
183 Si vos applications n'ont pas de schémas SQL suffisamment stables,
184 l'utilisation de &slony1; pour le mécanisme de réplication peut ne
185 pas être adaptée. Voir la section <link linkend="locking"> questions de verrous </link>
186 pour plus de discussion sur le sujet.</para>
187
188
189 <para>Voici un article sur l'administration des changements de schémas avec &slony1;:
190  <ulink url="http://www.varlena.com/varlena/GeneralBits/88.php">
191 Varlena General Bits</ulink></para>
192
193 <sect2><title> Changements <emphasis>hors</emphasis> utilisation de
194  <command>EXECUTE SCRIPT</command></title>
195
196
197 <para> Alors qu'il est <emphasis> vital </emphasis> d'utiliser
198 <command>EXECUTE SCRIPT</command> pour propager des modifications DDL sur des tables répliquées,
199 il y a plusieurs autres modifications que vous pouvez vouloir réaliser d'une autre façon :
200
201 <itemizedlist>
202
203 <listitem><para> Il y a plusieurs types d'objets n'ayant pas de trigger que
204 &slony1; <emphasis>ne</emphasis> peut répliquer, tels que les fonctions
205 stockées. Et il est assez probable que cela vous posera problÚme de propager ces mises à jour
206 en association avec un jeu de réplication où <command>EXECUTE SCRIPT</command>
207 va vérouiller tout un jeu de tables qui n'ont pas réellement besoin de l'être.</para>
208
209 <para> Si vous propagez une procédure stockée qui n'est pas utilisée tout le temps
210 (de telle sorte que vous acceptiez une petite desynchronisation entre les noeuds), alors vous pouvez
211 simplement la soumettre à chaque noeud par l'intermédiare d'une commande <application>psql</application>,
212 ne faisant pas d'utilisation particuliÚre de &slony1;</para>
213
214 <para>Si vous <emphasis>avez</emphasis> besoin d'une parfaite synchronisation sur l'ensemble des noeuds,
215 a ce moment là, vous devez utiliser <command>EXECUTE SCRIPT</command>
216  pour verrouiller vos travaux.</para></listitem>
217
218 <listitem><para> Vous pouvez avoir besoin d'index suplémentaires sur quelques
219 noeuds répliqués pour accroître les performances.</para>
220
221 <para> For instance, a table consisting of transactions may only need
222 indices related to referential integrity on the <quote>origin</quote>
223 node, and maximizing performance there dictates adding no more indices
224 than are absolutely needed.  But nothing prevents you from adding
225 additional indices to improve the performance of reports that run
226 against replicated nodes.</para>
227
228 <para> Il serait imprudent d'ajouter des indicateurs qui
229 <emphasis>contraindraient</emphasis> les évÚnements sur les noeuds répliqués,
230 en cas de problÚme, cela conduirait la réplication à s'arrêter
231 car le ou les  noeuds abonnés ne pourraient appliquer les changements provenant
232  du noeud origine violant la contrainte.</para>
233
234 <para> Cela ne pose pas de difficultes d'ajouter quelques mesures d'ameliorations de performances.
235 Il ne faut pratiquement <emphasis>jamais</emphasis> utiliser
236 <command>EXECUTE SCRIPT</command> dans ce cadre; cela conduit certains jeux de replication a
237 verrouiller/deverouiller des tables et potentiellement échouer à appliquer l'evenement a cause de verrous en cours
238 sur les objets, puis devoir reessayer un certain nombre de fois avant de pouvoir effectuer le changement.
239
240
241
242 A la place, si vous appliquer l'index <quote>directement</quote>, au travers de
243 <application>psql</application>, vous pouvez determiner le moment auquel
244 le verrou s'exerce sur la table.
245
246 Ajouter un index a une table necessite un verrou exlusif pour la duree
247 de creation de cet index: cela va implicitement stopper la replication, pendant la duree
248 de construction de l'index, mais sans causer de problemes particuliers.
249
250
251 Si vous ajoutez un index sur une table et que sa construction dure 20 minutes, la replication sera stoppee
252 pendant 20 minutes, mais repartira juste apres la fin de la creation.
253 .</para></listitem>
254
255 <listitem><para> &slony1; stocke le nom de l'<quote>index primaire</quote> dans
256  <xref linkend="table.sl-table"/>, et utilise ce nom pour controler les colonnes considérées
257  comme les <quote>colonnes cles"</quote> lorsque le declencheur de log est present.
258  Il pourrait etre envisageable de supprimer cet index et de le remplacer
259 par une autre cle primaire potentielle, mais un changement de nom de cette cle primaire
260 casserait certainement certaines choses.</para> </listitem>
261
262 </itemizedlist></para></sect2>
263
264 <sect2><title> Tester les changements DDL </title>
265
266 <indexterm><primary> tester les changements DDL </primary></indexterm>
267
268
269 <para> Une methode de test des changements DDL a ete validee
270  comme <quote>bonne pratique.</quote></para>
271  
272 <para> Vous <emphasis>devez</emphasis>
273  tester les scripts DDL de facon non destructrice.</para>
274
275
276 <para> Si les noeuds sont, pour une raison ou une autre, totalement desynchonisés,
277 la replication va tres certainement echouer, et cela a lieu la plupart du temps
278 au plus mauvais moment: celui ou vous vouliez que cela
279  <emphasis> fonctionne. </emphasis></para>
280
281
282 <para> Vous pouvez verifier si vos scripts DDL fonctionnent bien ou pas en les executant manuellement
283 en ajoutant <command>BEGIN; </command>  au debut et <command> ROLLBACK; </command> a la fin.
284  De cette facon, les changements effectuent un retour arriere.</para>
285
286 <para> Si le script s'effectue correctement sur tous les noeuds, cela semble dire
287 qu'il devrait s'executer également correctement via &lslonik;.
288 Si des problÚmes apparaissent sur certains noeuds, cela devrait vous permettre
289 de remettre ces machines a niveau, de facon a ce que le script
290  <emphasis> s'exécute</emphasis>  sans erreur.
291
292   <warning><para>Attention Si le script contient un  <command> COMMIT;
293   </command> n'importe ou avant le <command> ROLLBACK; </command>, cela va
294   effectuer des changements auxquels vous ne vous attendiez pas.</para></warning></para>
295   </sect2>
296 </sect1>
297
Note: See TracBrowser for help on using the browser.