| 8 | | <title>Defining &slony1; Replication Sets</title> |
|---|
| 9 | | |
|---|
| 10 | | <indexterm><primary>defining replication sets</primary></indexterm> |
|---|
| 11 | | |
|---|
| 12 | | <para>Defining the nodes indicated the shape of the cluster of |
|---|
| 13 | | database servers; it is now time to determine what data is to be |
|---|
| 14 | | copied between them. The groups of data that are copied are defined |
|---|
| 15 | | as <quote>replication sets.</quote></para> |
|---|
| 16 | | |
|---|
| 17 | | <para>A replication set consists of the following:</para> |
|---|
| 18 | | <itemizedlist> |
|---|
| 19 | | |
|---|
| 20 | | <listitem><para>Keys on tables that are to be replicated that have no |
|---|
| 21 | | suitable primary key</para></listitem> |
|---|
| 22 | | |
|---|
| 23 | | <listitem><para>Tables that are to be replicated</para></listitem> |
|---|
| 24 | | |
|---|
| 25 | | <listitem><para>Sequences that are to be replicated</para></listitem> |
|---|
| | 8 | <title>Définir les ensembles de réplication</title> |
|---|
| | 9 | |
|---|
| | 10 | <indexterm><primary>définir les ensembles de réplication</primary></indexterm> |
|---|
| | 11 | |
|---|
| | 12 | <para>En définissant les noeuds on a conçu l'architecture du cluster |
|---|
| | 13 | de réplication; il est temps de déterminer quelles données doivent être |
|---|
| | 14 | copiées entre les noeuds. Les groupes de données qui sont copiés |
|---|
| | 15 | sont nommés <quote>ensembles de réplication</quote>.</para> |
|---|
| | 16 | |
|---|
| | 17 | <para>Un ensemble de réplication comprend :</para> |
|---|
| | 18 | <itemizedlist> |
|---|
| | 19 | |
|---|
| | 20 | <listitem><para>Les clefs des tables à répliquer qui n'ont pas de clef primaire possible ;</para></listitem> |
|---|
| | 21 | |
|---|
| | 22 | <listitem><para>Les tables qui doivent être répliquées;</para></listitem> |
|---|
| | 23 | |
|---|
| | 24 | <listitem><para>Les séquences qui doivent être répliquées.</para></listitem> |
|---|
| 28 | | <sect2><title>Primary Keys</title> |
|---|
| 29 | | |
|---|
| 30 | | <indexterm><primary>primary key requirement</primary></indexterm> |
|---|
| 31 | | |
|---|
| 32 | | <para>&slony1; <emphasis>needs</emphasis> to have a primary key or |
|---|
| 33 | | candidate thereof on each table that is replicated. PK values are |
|---|
| 34 | | used as the primary identifier for each tuple that is modified in the |
|---|
| 35 | | source system. Note that they can be composite keys composed of |
|---|
| 36 | | multiple NOT NULL columns; they don't need to consist of single |
|---|
| 37 | | fields. There are three ways that you can get &slony1; to use a |
|---|
| 38 | | primary key:</para> |
|---|
| 39 | | |
|---|
| 40 | | <itemizedlist> |
|---|
| 41 | | |
|---|
| 42 | | <listitem><para> If the table has a formally identified primary key, |
|---|
| 43 | | <xref linkend="stmtsetaddtable"/> can be used without any need to |
|---|
| 44 | | reference the primary key. &slony1; can automatically pick up that |
|---|
| 45 | | there is a primary key, and use it.</para></listitem> |
|---|
| 46 | | |
|---|
| 47 | | <listitem><para> If the table hasn't got a primary key, but has some |
|---|
| 48 | | <emphasis>candidate</emphasis> primary key, that is, some index on a |
|---|
| 49 | | combination of fields that is both UNIQUE and NOT NULL, then you can |
|---|
| 50 | | specify that key, as shown in the following example. </para> |
|---|
| | 27 | <sect2><title>Les clefs primaires</title> |
|---|
| | 28 | |
|---|
| | 29 | <indexterm><primary>importance des clefs primaires</primary></indexterm> |
|---|
| | 30 | |
|---|
| | 31 | <para>&slony1; <emphasis>a besoin</emphasis> d'une clef primaire ou |
|---|
| | 32 | d'un ensemble de champ éligible au statut de clef primaire pour chacune |
|---|
| | 33 | des tables qui seront répliquées. |
|---|
| | 34 | Les valeurs de clefs primaires ( "PK" ) sont utilisées comme identifiant |
|---|
| | 35 | primaire pour chaque tuple qui est modifié sur le systÚme source. |
|---|
| | 36 | Notons que les clefs primaires peuvent être des clefs composées de plusieurs |
|---|
| | 37 | colonnes NOT NULL; elles ne doivent pas obligatoirement être constituées |
|---|
| | 38 | de champs uniques. |
|---|
| | 39 | Il y a 3 façons de précise à &slony1; quelle clef primaire utiliser :</para> |
|---|
| | 40 | |
|---|
| | 41 | <itemizedlist> |
|---|
| | 42 | |
|---|
| | 43 | <listitem><para> Si la table a déjà une clef primaire identifiée, |
|---|
| | 44 | <xref linkend="stmtsetaddtable"/> peut être utilisé sans qu'il |
|---|
| | 45 | soit nécessaire de préciser la clef primaire. &slony1; peut |
|---|
| | 46 | automatiquement comprendre qu'il existe une clef primaire et |
|---|
| | 47 | l'utiliser.</para></listitem> |
|---|
| | 48 | |
|---|
| | 49 | <listitem><para> Si la table ne dispose pas d'une clef primaire, |
|---|
| | 50 | mais a une clef primaire <emphasis>candidate</emphasis>, |
|---|
| | 51 | c'est à dire, un index sur une combinaison de champs qui |
|---|
| | 52 | sont à la fois UNIQUE et NOT NULL , |
|---|
| | 53 | alors vous pouvez spécifier cette clef, comme ceci : |
|---|
| | 54 | </para> |
|---|
| 69 | | <para>If your application is not somehow referencing the index by name, |
|---|
| 70 | | the this should not lose you anything, and it gives you the clear design |
|---|
| 71 | | benefit that a primary key has been declared for the table. </para> |
|---|
| 72 | | |
|---|
| 73 | | <para> Notice that while you need to specify the namespace for the |
|---|
| 74 | | table, you must <emphasis>not</emphasis> specify the namespace for the |
|---|
| 75 | | key, as it infers the namespace from the table.</para></listitem> |
|---|
| 76 | | |
|---|
| 77 | | |
|---|
| 78 | | <listitem><para> If the table hasn't even got a candidate primary key, |
|---|
| 79 | | you might ask &slony1; to provide one using |
|---|
| | 73 | <para>Si votre application utilise l'index ma_table_nom, vous ne |
|---|
| | 74 | perdrez rien et cela vous donnera l'avantage d'avoir une clef primaire |
|---|
| | 75 | sur votre table. </para> |
|---|
| | 76 | |
|---|
| | 77 | <para> Notons que si vous devez spécifier une espace de nom ("namespace") |
|---|
| | 78 | pour la table, vous <emphasis>ne devez pas</emphasis> préciser l'espace |
|---|
| | 79 | de nom de la clef, car cela peut interférer avec d'autres espaces de |
|---|
| | 80 | noms de la table.</para></listitem> |
|---|
| | 81 | |
|---|
| | 82 | |
|---|
| | 83 | <listitem><para> Si la table n'a pas de clef primaire candidate, |
|---|
| | 84 | vous devez demander à &slony1; de produire une en utilisant la commande |
|---|
| 91 | | <para> It is not terribly important whether you pick a |
|---|
| 92 | | <quote>true</quote> primary key or a mere <quote>candidate primary |
|---|
| 93 | | key;</quote> it is, however, strongly recommended that you have one of |
|---|
| 94 | | those instead of having &slony1; populate the PK column for you. If you |
|---|
| 95 | | don't have a suitable primary key, that means that the table hasn't got |
|---|
| 96 | | any mechanism, from your application's standpoint, for keeping values |
|---|
| 97 | | unique. &slony1; may, therefore, introduce a new failure mode for your |
|---|
| 98 | | application, and this also implies that you had a way to enter confusing |
|---|
| 99 | | data into the database.</para> |
|---|
| | 97 | <para> Il n'est pas terriblement important de sélectionner |
|---|
| | 98 | une <quote>vraie</quote> clef primaire ou une simple <quote>clef primaire |
|---|
| | 99 | </quote>. Cependant il est fortement recommandé d'utiliser une de ces deux |
|---|
| | 100 | solution plutÃŽt que de laisser &slony1; remplir la colonne de clef primaire |
|---|
| | 101 | Ã votre place. Si vous n'avez pas de clef primaire candidate, cela signifie |
|---|
| | 102 | que la table ne fournit aucun mécanisme à votre application pour garder |
|---|
| | 103 | les tuples uniques. Dans ce cadre &slony1; peut introduire des erreurs |
|---|
| | 104 | dans votre application, de plus cela implique que vous pouvez entrer des |
|---|
| | 105 | données erronées dans la base de données. |
|---|
| | 106 | </para> |
|---|
| 102 | | <sect2 id="definesets"><title>Grouping tables into sets</title> |
|---|
| 103 | | |
|---|
| 104 | | <indexterm><primary> grouping tables into replication sets </primary></indexterm> |
|---|
| 105 | | |
|---|
| 106 | | <para> It will be vital to group tables together into a single set if |
|---|
| 107 | | those tables are related via foreign key constraints. If tables that |
|---|
| 108 | | are thus related are <emphasis>not</emphasis> replicated together, |
|---|
| 109 | | you'll find yourself in trouble if you switch the <quote>master |
|---|
| 110 | | provider</quote> from one node to another, and discover that the new |
|---|
| 111 | | <quote>master</quote> can't be updated properly because it is missing |
|---|
| 112 | | the contents of dependent tables.</para> |
|---|
| 113 | | |
|---|
| 114 | | <para> There are also several reasons why you might |
|---|
| 115 | | <emphasis>not</emphasis> want to have all of the tables in one |
|---|
| 116 | | replication set: |
|---|
| 117 | | |
|---|
| 118 | | <itemizedlist> |
|---|
| 119 | | |
|---|
| 120 | | <listitem><para> The initial <command>COPY_SET</command> event for a |
|---|
| 121 | | large set leads to a <link linkend="longtxnsareevil"> long running |
|---|
| 122 | | transaction </link> on the provider node. The <link linkend="faq"> |
|---|
| 123 | | FAQ </link> outlines a number of problems that result from long |
|---|
| 124 | | running transactions that will injure system performance.</para> |
|---|
| 125 | | |
|---|
| 126 | | <para> If you can split such a large set into several smaller pieces, |
|---|
| 127 | | that will shorten the length of each of the transactions, lessening |
|---|
| 128 | | the degree of the <quote>injury</quote> to performance.</para> |
|---|
| 129 | | |
|---|
| 130 | | <para> Another issue comes up particularly frequently when replicating |
|---|
| 131 | | across a WAN; sometimes the network connection is a little bit |
|---|
| 132 | | unstable, such that there is a risk that a connection held open for |
|---|
| 133 | | several hours will lead to <command>CONNECTION TIMEOUT.</command> If |
|---|
| 134 | | that happens when 95% done copying a 50-table replication set |
|---|
| 135 | | consisting of 250GB of data, that could ruin your whole day. If the |
|---|
| 136 | | tables were, instead, associated with separate replication sets, that |
|---|
| 137 | | failure at the 95% point might only interrupt, temporarily, the |
|---|
| 138 | | copying of <emphasis>one</emphasis> of those tables. </para> |
|---|
| 139 | | |
|---|
| 140 | | <para> These <quote>negative effects</quote> tend to emerge when the |
|---|
| 141 | | database being subscribed to is many gigabytes in size and where it |
|---|
| 142 | | takes many hours or even days for the subscriber to complete the |
|---|
| 143 | | initial data copy. For relatively small databases, this shouldn't be |
|---|
| 144 | | a material factor. |
|---|
| | 109 | <sect2 id="definesets"><title>Regrouper les tables en ensembles</title> |
|---|
| | 110 | |
|---|
| | 111 | <indexterm><primary> grouper les tables dans des ensembles de réplication </primary></indexterm> |
|---|
| | 112 | |
|---|
| | 113 | <para> Il est vital de regrouper les tables dans un seul ensemble lorsque |
|---|
| | 114 | ces tables sont reliées par une clef étrangÚre. |
|---|
| | 115 | Si des tables reliées de cette maniÚres ne sont <emphasis>pas</emphasis> |
|---|
| | 116 | répliquées ensembles. Vous rencontrerez des problÚmes lors de la bascule |
|---|
| | 117 | du noeud <quote>fournisseur maître</quote> vers un autre noeud, |
|---|
| | 118 | et vous obtiendrez un nouveau <quote>maître</quote> qui ne peut pas |
|---|
| | 119 | être mis à jour correctement car le contenu de certaines tables n'est |
|---|
| | 120 | pas disponible.</para> |
|---|
| | 121 | |
|---|
| | 122 | <para> Il y a également plusieurs raisons pour ne <emphasis>pas</emphasis> |
|---|
| | 123 | placer toutes les tables dans un ensemble unique : |
|---|
| | 124 | |
|---|
| | 125 | <itemizedlist> |
|---|
| | 126 | |
|---|
| | 127 | <listitem><para>Sur un ensemble trÚs large, l'événement initial <command>COPY_SET</command> provoquent de |
|---|
| | 128 | <link linkend="longtxnsareevil"> trÚs longues transactions</link> |
|---|
| | 129 | sur le noeud fournisseur. La <link linkend="faq"> |
|---|
| | 130 | FAQ </link> décrit un certain nombre de problÚmes qui conduisent à |
|---|
| | 131 | des transactions qui ralentissent les performances du systÚme.</para> |
|---|
| | 132 | |
|---|
| | 133 | <para> Si vous pouvez découper un grand ensemble en plusieurs |
|---|
| | 134 | plus petits ensembles, cela réduira la longueur de chaque transactions et |
|---|
| | 135 | diminuera leur impact négatif sur les performances.</para> |
|---|
| | 136 | |
|---|
| | 137 | <para> Un autre problÚme survient fréquemment lorsque l'on |
|---|
| | 138 | réplique via un WAN; parfois la connexion réseau est un peu |
|---|
| | 139 | instable, si bien qu'il y a des risques qu'une connexion reste |
|---|
| | 140 | ouverte pendant plusieurs heures et entraîne un <command>CONNECTION TIMEOUT.</command> Si cela se produit à 95% d'une copie |
|---|
| | 141 | d'un ensemble de réplication de 50 tables, représentant 250GB de données, |
|---|
| | 142 | cela va gâcher votre journée. Au contraire si les tables sont séparées |
|---|
| | 143 | en plusieurs ensembles de réplication, cette panne réseau qui intervient à 95% |
|---|
| | 144 | n'interrompra que la copie d'<emphasis>un seul</emphasis> ensemble. |
|---|
| | 145 | </para> |
|---|
| | 146 | |
|---|
| | 147 | <para>Certains <quote>effets négatifs</quote> émergent lorsque la |
|---|
| | 148 | base de données est répliquée contient plusieurs gigabytes de données, |
|---|
| | 149 | et qu'il faut des heures ou des jours pour qu'un noeud abonné réalise |
|---|
| | 150 | une copie complÚte des données initiales. Pour les bases relativement |
|---|
| | 151 | petites, cela n'est pas un facteur important. |
|---|
| 148 | | <listitem><para> Any time you invoke <xref linkend="stmtddlscript"/>, |
|---|
| 149 | | this requests a lock on <emphasis> every single table in the |
|---|
| 150 | | replication set, first, on the origin node, and then, as the event |
|---|
| 151 | | propagates to other nodes, to each subscriber node. </emphasis></para> |
|---|
| 152 | | |
|---|
| 153 | | <para> There have been reports <quote>in the field</quote> of this |
|---|
| 154 | | leading to deadlocks such that the <xref linkend="stmtddlscript"/> |
|---|
| 155 | | request had to be submitted many times in order for it to actually |
|---|
| 156 | | complete successfully.</para> |
|---|
| 157 | | |
|---|
| 158 | | <para> The more tables you have in a set, the more tables need to be |
|---|
| 159 | | locked, and the greater the chances of deadlocks. </para> |
|---|
| 160 | | |
|---|
| 161 | | <para> By the same token, if a particular DDL script only needs to |
|---|
| 162 | | affect a couple of tables, you might use <xref |
|---|
| 163 | | linkend="stmtsetmovetable"/> to move them temporarily to a new |
|---|
| 164 | | replication set. By diminishing the number of locks needed, this |
|---|
| 165 | | should ease the ability to get the DDL change into place.</para> |
|---|
| 166 | | |
|---|
| 167 | | <para> There is a further <link linkend="locking"> discussion of |
|---|
| 168 | | locking </link> which outlines where &slony1; requires locks likely to |
|---|
| 169 | | intrude on your applications.</para> |
|---|
| | 155 | <listitem><para> Chaque invocation de la commande <xref linkend="stmtddlscript"/> |
|---|
| | 156 | nécessite un verrou sur <emphasis> chaque table de l'ensemble de réplication |
|---|
| | 157 | , d'abord sur le noeud d'origine, puis avec la propagation |
|---|
| | 158 | de l'événement sur chacun des noeuds abonnés. </emphasis></para> |
|---|
| | 159 | |
|---|
| | 160 | <para> De retours d'expériences <quote>de terrain</quote> indique que |
|---|
| | 161 | cela peut conduire à des inter-blocages de verrous ("deadlocks"), ce qui nécessite |
|---|
| | 162 | d'appeler la requête <xref linkend="stmtddlscript"/> plusieurs fois |
|---|
| | 163 | pour réussir à l'exécuter complÚtement.</para> |
|---|
| | 164 | |
|---|
| | 165 | <para> Plus vous avez de tables dans un ensemble de réplication, plus |
|---|
| | 166 | ces tables doivent être verrouiller et plus les chances d'obtenir un |
|---|
| | 167 | inter-blocage des verrous sont grandes. </para> |
|---|
| | 168 | |
|---|
| | 169 | <para> Dans le même ordre d'idées, si un script DDL particulier |
|---|
| | 170 | doit simplement affecter deux tables, vous devez utiliser |
|---|
| | 171 | <xref linkend="stmtsetmovetable"/> pour les déplacer temporairement |
|---|
| | 172 | dans un nouvel ensemble de réplication. |
|---|
| | 173 | En diminuant le nombre de verrous nécessaire, cela simplifiera |
|---|
| | 174 | la mise en place des changements DDL.</para> |
|---|
| | 175 | |
|---|
| | 176 | <para> Il y a de plus amples <link linkend="locking"> discussions sur les verrous </link> |
|---|
| | 177 | qui décrivent quand &slony1; a besoin de verrous et leur impact sur vos applications.</para> |
|---|
| 176 | | <sect2> <title> The Pathology of Sequences </title> |
|---|
| 177 | | |
|---|
| 178 | | <indexterm><primary>sequence pathology</primary></indexterm> |
|---|
| 179 | | |
|---|
| 180 | | <para> Each time a SYNC is processed, values are recorded for |
|---|
| 181 | | <emphasis>all</emphasis> of the sequences in the set. If there are a |
|---|
| 182 | | lot of sequences, this can cause <xref linkend="table.sl-seqlog"/> to |
|---|
| 183 | | grow rather large.</para> |
|---|
| 184 | | |
|---|
| 185 | | <para> This points to an important difference between tables and |
|---|
| 186 | | sequences: if you add additional tables that do not see much/any |
|---|
| 187 | | activity, this does not add any material load to the work being done |
|---|
| 188 | | by replication. For a replicated sequence, values must |
|---|
| 189 | | <emphasis>regularly</emphasis> be propagated to subscribers. Consider |
|---|
| 190 | | the effects: |
|---|
| 191 | | |
|---|
| 192 | | <itemizedlist> |
|---|
| 193 | | |
|---|
| 194 | | <listitem><para> A replicated table that is never updated does not |
|---|
| 195 | | introduce much work to the system.</para> |
|---|
| 196 | | |
|---|
| 197 | | <para> If it is not updated, the trigger on the table on the origin |
|---|
| 198 | | never fires, and no entries are added to <xref |
|---|
| 199 | | linkend="table.sl-log-1"/>. The table never appears in any of the |
|---|
| 200 | | further replication queries (<emphasis>e.g.</emphasis> in the |
|---|
| 201 | | <command>FETCH 100 FROM LOG</command> queries used to find |
|---|
| 202 | | replicatable data) as they only look for tables for which there are |
|---|
| 203 | | entries in <xref linkend="table.sl-log-1"/>.</para></listitem> |
|---|
| 204 | | |
|---|
| 205 | | <listitem><para> In contrast, a fixed amount of work is introduced to |
|---|
| 206 | | each SYNC by each sequence that is replicated.</para> |
|---|
| 207 | | |
|---|
| 208 | | <para> Replicate 300 sequence and 300 rows need to be added to <xref |
|---|
| 209 | | linkend="table.sl-seqlog"/> on a regular basis.</para> |
|---|
| 210 | | |
|---|
| 211 | | <para> It is more than likely that if the value of a particular |
|---|
| 212 | | sequence hasn't changed since it was last checked, perhaps the same |
|---|
| 213 | | value need not be stored over and over; some thought needs to go into |
|---|
| 214 | | how to do that safely.</para></listitem> |
|---|
| | 184 | <sect2> <title> La pathologie des séquences</title> |
|---|
| | 185 | |
|---|
| | 186 | <indexterm><primary>Pathologie de séquence</primary></indexterm> |
|---|
| | 187 | |
|---|
| | 188 | <para> Chaque fois qu'un évÚnement SYNC est traité, les valeurs sont enregistrées |
|---|
| | 189 | pour <emphasis>toutes</emphasis> les séquences de l'ensemble de réplication. Si |
|---|
| | 190 | vous avez beaucoup de séquence, cela peut augmenter fortement la volumétrie de |
|---|
| | 191 | la table <xref linkend="table.sl-seqlog"/> .</para> |
|---|
| | 192 | |
|---|
| | 193 | <para> Cela illustre une différence importantes entre les tables et les séquences : |
|---|
| | 194 | si vous ajouter des tables supplémentaire qui peu voire aucune activité, cela n'ajoute |
|---|
| | 195 | pas de charge supplémentaire pour le systÚme de réplication. |
|---|
| | 196 | Pour les séquences répliquées, les valeurs doivent être |
|---|
| | 197 | <emphasis>réguliÚrement</emphasis> propagées aux abonnés. |
|---|
| | 198 | Considérons les conséquences : |
|---|
| | 199 | |
|---|
| | 200 | <itemizedlist> |
|---|
| | 201 | |
|---|
| | 202 | <listitem><para> Une table répliquée mais qui n'est jamais mise à jour |
|---|
| | 203 | n'entraîne pas de travail supplémentaire. |
|---|
| | 204 | </para> |
|---|
| | 205 | |
|---|
| | 206 | <para> Si elle n'est jamais mise à jour, le trigger sur la table sur le noeud |
|---|
| | 207 | origine n'est jamais déclenché, et aucune entrée n'est ajoutées dans <xref |
|---|
| | 208 | linkend="table.sl-log-1"/>. La table n'apparaît jamais dans aucune |
|---|
| | 209 | des requêtes de réplication (<emphasis>par exemple :</emphasis> dans les requêtes |
|---|
| | 210 | <command>FETCH 100 FROM LOG</command> utilisées pour trouver les données à répliquer) |
|---|
| | 211 | car elles ne recherchent que les tables qui ont des entrées dans |
|---|
| | 212 | <xref linkend="table.sl-log-1"/>.</para></listitem> |
|---|
| | 213 | |
|---|
| | 214 | <listitem><para> Au contraire, une certaine quantité de travail est ajoutée |
|---|
| | 215 | lors d'un événement SYNC pour chaque séquence qui est répliquée. |
|---|
| | 216 | </para> |
|---|
| | 217 | |
|---|
| | 218 | <para> Pour répliquer 300 séquences, 300 lignes doivent être ajoutées dans la |
|---|
| | 219 | <xref linkend="table.sl-seqlog"/> de maniÚre réguliÚre.</para> |
|---|
| | 220 | |
|---|
| | 221 | <para> Il est probable que si une valeur d'une séquence particuliÚre n'a pas changé |
|---|
| | 222 | depuis la derniÚre vérification, alors il n'est peut être pas nécessaire |
|---|
| | 223 | de stocker cette valeur encore et encore. Certaines reflexions sont en cours sur |
|---|
| | 224 | comment réaliser cela de maniÚre sécurisée. |
|---|
| | 225 | </para></listitem> |
|---|