| 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 |
|
|---|