Londiste, la réplication vue par Skype

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
44
|
Mois de parution
octobre 2009
|


Résumé
Londiste est un autre système de réplication asynchrone basé sur les triggers. Son installation est un peu particulière, mais pas désagréable du tout. Elle est même bien plus simple que l'installation de Slony. Créé par Skype en Python pour ses besoins propres, il est disponible depuis peu de temps, mais progresse bien et mérite sa place dans ce hors-série.

Body

1. Installation de Londiste

Londiste faisant partie des Skytools, il faut installer ce paquet. Comme nous l'avons vu dans l'article sur le log shipping, nous allons utiliser le paquet disponible pour Squeeze (première version Debian à avoir ce paquet). Skytools est constitué de deux paquets sous Debian : skytools et skytools-modules. Ce dernier est spécifique à la version installée de PostgreSQL. Il n'existe pas encore à ma connaissance de modules pour 8.4. Nous allons donc utiliser un PostgreSQL version 8.3, et utiliser les modules Skytools de cette version.

debian1:~$ wget -q http://ftp.fr.debian.org/debian/pool/main/s/skytools/skytools_2.1.8-2_i386.deb

debian1:~$ wget -q http://ftp.fr.debian.org/debian/pool/main/s/skytools/skytools-modules-8.3_2.1.8-2_i386.deb

debian1:~$ aptitude install python-psycopg2

[… différents messages de progression …]

debian1:~$ dpkg -i skytools_2.1.8-2_i386.deb skytools-modules-8.3_2.1.8-2_i386.deb

[… différents messages de progression …]

Pour que la réplication fonctionne, il n'est pas nécessaire de les installer sur le serveur debian2. Cependant, l'un des buts d'un système de réplication étant de pouvoir basculer sur l'esclave si nécessaire. Il peut être intéressant d'installer immédiatement les outils sur l'esclave.

1.1 Configuration de PostgreSQL

Les démons pgqadm et londiste vont être exécutés en tant qu'utilisateur Unix postgres et vont se connecter à la base de données base1, en tant qu'utilisateur PostgreSQL postgres, à partir du serveur debian1 vers les serveurs debian1 et debian2. Il nous faut donc configurer PostgreSQL pour qu'il accepte les connexions sur l'interface réseau de debian1 et de debian2 et pour qu'il accepte l'authentification de l'utilisateur postgres. Le premier fichier à configurer est postgresql.conf dans le répertoire /etc/postgresql/8.3/main. Il faut changer le paramètre listen_addresses pour que sa valeur soit « * ». Le deuxième fichier à modifier est pg_hba.conf pour permettre les connexions à partir de debian1 et de debian2. Il nous faut donc ajouter les deux lignes suivantes :

host    all         postgres    192.168.0.8/32        md5

host    all         postgres    192.168.0.10/32       md5

Nous pouvons redémarrer PostgreSQL :

debian1:~# /etc/init.d/postgresql-8.3 restart

Restarting PostgreSQL 8.3 database server: main.

Nous devons ensuite donner un mot de passe à l'utilisateur PostgreSQL postgres :

debian1:~# su - postgres

postgres@debian1:~$ psql -c "ALTER USER postgres PASSWORD 'postgres';" postgres

ALTER ROLE

Enfin, nous allons créer le fichier .pgpass dans le répertoire personnel de l'utilisateur postgres afin que ce dernier n'ait pas à saisir son mot de passe pour la connexion à la base base1 de debian1 et de debian2.

postgres@debian1:~$ cat <<_EOF_ >>~/.pgpass

> debian1:5432:base1:postgres:postgres

> debian2:5432:base1:postgres:postgres

> _EOF_

postgres@debian1:~$ chmod 600 ~/.pgpass

Effectuez toute la configuration de ce chapitre pour le serveur debian2.

Testez la connexion depuis debian1 au serveur debian1 et debian2. Faites de même à partir de debian2. Si tout se passe bien, vous devriez pouvoir vous connecter à la base base1 des deux serveurs sans avoir à saisir de mot de passe. Si ce n'est pas le cas, vous devez corriger le problème avant de continuer.

1.2 Mise en place du PGQ

PGQ est l'acronyme de PostGresql Queue, un système de gestion de queue créé par Skype. Ce système va récupérer les modifications effectuées sur une base dans un journal (une table d'un schéma). Donc un équivalent des tables sl_log_1 et sl_log_2 de Slony.

Commençons par son paramétrage. Nous allons copier le fichier de configuration exemple dans le répertoire de configuration de PostgreSQL :

debian1:~$ cp /usr/share/doc/skytools/conf/pgqadm.ini /etc/postgresql/8.3/main

Puis, nous allons le modifier pour obtenir ce fichier :

[pgqadm]

# should be globally unique

job_name = pgqadm_replication

db = dbname=base1 host=debian1

# how often to run maintenance [minutes]

maint_delay_min = 5

# how often to check for activity [secs]

loop_delay = 0.1

logfile = ~/log/%(job_name)s.log

pidfile = ~/pid/%(job_name)s.pid

use_skylog = 0

Le paramètre job_name peut être configuré suivant votre convenance. Le paramètre db indique dans quelle base sera créé le système de gestion de queues. Cela veut dire l'ajout du langage PL/pgsql, l'ajout du schéma pgqadm et de ces tables et séquences. Remarquez que nous n'allons pas utiliser un utilisateur particulier pour les connexions. Il pourrait être intéressant de le faire. Ce n'est ni recommandé, ni déconseillé. Donc, nous ne le ferons pas, mais sachez néanmoins que c'est possible.

Vu que le démon va écrire les fichiers de trace dans le sous-répertoire log et le fichier PID dans le sous-répertoire pid du répertoire personnel de l'utilisateur postgres, il nous faut créer ces deux répertoires.

debian1:~# su – postgres

postgres@debian1:~$ mkdir ~/log ~/pid

À cause d'un bug du paquet Debian (voir http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=534310 pour les détails), il nous faut modifier le fichier /usr/lib/python2.5/site-packages/skytools/installer_config.py. En effet, ce fichier Python cherche des scripts SQL dans /usr/share/skytools alors qu'ils se trouvent dans /usr/share/postgresql/8.3/contrib. J'avoue ne pas avoir trouvé d'autres moyens que la modification de ce fichier.

postgres@debian1:~$ exit

logout

debian1:~$ cat <<_EOF_ >/usr/lib/python2.5/site-packages/skytools/installer_config.py

>

> sql_locations = [

>    "/usr/share/postgresql/8.3/contrib",

> ]

> _EOF_

Maintenant, nous pouvons installer le système PGQ :

debian1:~$ su – postgres

postgres@debian1:~$ pgqadm /etc/postgresql/8.3/main/pgqadm.ini install

2009-08-14 19:35:28,836 5200 INFO Installing plpgsql

2009-08-14 19:35:28,855 5200 INFO txid_current_snapshot is installed

2009-08-14 19:35:28,858 5200 INFO Installing pgq

2009-08-14 19:35:28,858 5200 INFO   Reading from /usr/share/postgresql/8.3/contrib/pgq.sql

L'action install de pgqadm commence par activer le langage PL/pgsql si ce dernier ne l'est pas déjà. Il vérifie que la fonction txid_current_snapshot existe, et l'installe dans le cas contraire. Enfin, il exécute le script pgq.sql pour créer le schéma pgq et ces différentes tables et séquences.

Il ne nous reste plus qu'à lancer le démon avec la commande suivante :

postgres@debian1:~$ pgqadm /etc/postgresql/8.3/main/pgqadm.ini ticker -d

1.3 Mise en place de londiste

Là aussi, nous allons commencer par son paramétrage. Nous allons copier le fichier de configuration exemple dans le répertoire de configuration de PostgreSQL :

debian1:~$ cp /usr/share/doc/skytools/conf/londiste.ini /etc/postgresql/8.3/main

Nous allons ensuite le modifier pour obtenir ceci :

[londiste]

# should be unique

job_name = replication_base1

# source queue location

provider_db = dbname=base1 host=debian1

# target database - it's preferable to run "londiste replay"

# on same machine and use unix-socket or localhost to connect

subscriber_db = dbname=base1 host=debian2

# source queue name

pgq_queue_name = londiste.replication

logfile = ~/log/%(job_name)s.log

pidfile = ~/pid/%(job_name)s.pid

# how often to poll event from provider

#loop_delay = 1

# max locking time on provider (in seconds, float)

#lock_timeout = 10.0

Le paramètre job_name peut être configuré suivant votre convenance. Le paramètre provider_db indique la base à répliquer alors que le paramètre subscriber_db précise où la répliquer.

Nous pouvons dès maintenant installer londiste sur le fournisseur et sur l'abonné :

debian1:~$ su – postgres

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste.ini provider install

2009-08-15 01:49:18,000 2184 INFO plpgsql is installed

2009-08-15 01:49:18,006 2184 INFO txid_current_snapshot is installed

2009-08-15 01:49:18,008 2184 INFO pgq is installed

2009-08-15 01:49:18,009 2184 INFO Installing londiste

2009-08-15 01:49:18,016 2184 INFO   Reading from /usr/share/postgresql/8.3/contrib/londiste.sql

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste.ini subscriber install

2009-08-15 01:49:41,430 2188 INFO Installing plpgsql

2009-08-15 01:49:41,538 2188 INFO Installing londiste

2009-08-15 01:49:41,539 2188 INFO   Reading from /usr/share/postgresql/8.3/contrib/londiste.sql

Cela ressemble beaucoup à l'installation de PGQ. Le script SQL est différent, mais ses actions correspondent aussi en gros : création d'un schéma cette fois appelé londiste, ajout de tables et de séquences.

Il est possible de lancer le démon londiste dès maintenant :

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste.ini replay -d

postgres@debian1:~$ ps -ef | grep [l]ondiste

postgres 2197     1 0 01:51 ?        00:00:00 /usr/bin/python /usr/bin/londiste /etc/postgresql/8.3/main/londiste.ini replay -d

Il est bien en cours d'exécution.

Si vous regardez les traces générées par le démon, vous verrez qu'il ne fait pas grand-chose actuellement. En effet, nous n'avons déclaré aucune table à répliquer.

Créons une table et demandons sa réplication :

postgres@debian1:~$ psql -q base1

base1=# CREATE TABLE t1 (id serial primary key, texte text);

NOTICE: CREATE TABLE créera des séquences implicites « t1_id_seq » pour la colonne serial « t1.id »

NOTICE: CREATE TABLE / PRIMARY KEY créera un index implicite « t1_pkey » pour la table « t1 »

base1=# INSERT INTO t1 (texte) SELECT 'Ligne '||i::text FROM generate_series(1, 10000) AS i;

base1=# \q

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste.ini provider add public.t1

2009-08-15 02:01:36,075 2272 INFO Adding public.t1

Remarquez que nous indiquons le schéma dans la dénomination de la table. Si vous indiquez seulement le nom de la table, Londiste ajoute automatiquement le schéma public devant. Il ne prend donc pas en considération la valeur de search_path pour trouver dans quel schéma est réellement stockée la table.

Tout ce que cette commande fait est que les modifications de cette table sont prêtes à être journalisées dès qu'un abonné sera présent. Nous allons donc abonner debian2 à cette journalisation. Dans un premier temps, nous devons créer la même table sur base1 de debian2 :

postgres@debian1:~$ psql -q -h debian2 base1

base1=# CREATE TABLE t1 (id serial primary key, texte text);

NOTICE: CREATE TABLE créera des séquences implicites « t1_id_seq » pour la colonne serial « t1.id »

NOTICE: CREATE TABLE / PRIMARY KEY créera un index implicite « t1_pkey » pour la table « t1 »

base1=# INSERT INTO t1 (texte) SELECT 'Ligne '||i::text FROM generate_series(1, 10000) AS i;

base1=# \q

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste.ini subscriber add public.t1

2009-08-15 02:05:16,861 2291 INFO Checking public.t1

2009-08-15 02:05:16,894 2291 INFO Adding public.t1

Cela ne veut pas dire que les données sont déjà présentes sur debian2. Il faudra un petit laps de temps.

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste.ini subscriber tables

Table                                           State

public.t1                                           -

Le transfert ici n'a toujours pas commencé.

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste.ini subscriber tables

Table                                           State

public.t1                                     in-copy

La copie est en cours.

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste.ini subscriber tables

Table                                           State

public.t1                                          ok

La copie est terminée. Ce qu'indiquent d'ailleurs les traces :

2009-08-15 02:05:16,861 2291 INFO Checking public.t1

2009-08-15 02:05:16,894 2291 INFO Adding public.t1

2009-08-15 02:05:52,819 2197 INFO storing state of public.t1: copy:0 new_state:in-copy

2009-08-15 02:05:52,832 2197 INFO Table public.t1 status changed to 'in-copy'

2009-08-15 02:05:52,833 2197 INFO Launching copy process

2009-08-15 02:05:53,130 2297 INFO Resetting queue tracking on dst side

2009-08-15 02:06:52,493 2297 INFO Starting full copy of public.t1

2009-08-15 02:06:52,571 2297 INFO Dropping t1_pkey

2009-08-15 02:06:52,577 2297 INFO public.t1: truncating

2009-08-15 02:06:52,593 2297 INFO public.t1: start copy

2009-08-15 02:06:52,765 2297 INFO public.t1: copy finished: 157788 bytes, 10000 rows

2009-08-15 02:06:52,767 2297 INFO Creating t1_pkey

2009-08-15 02:06:52,826 2297 INFO storing state of public.t1: copy:1 new_state:catching-up

2009-08-15 02:06:56,994 2297 INFO storing state of public.t1: copy:1 new_state:wanna-sync:44

2009-08-15 02:06:56,998 2297 INFO Table public.t1 status changed to 'wanna-sync:44'

2009-08-15 02:06:59,625 2197 INFO storing state of public.t1: copy:0 new_state:do-sync:45

2009-08-15 02:06:59,637 2197 INFO Table public.t1 status changed to 'do-sync:45'

2009-08-15 02:07:00,085 2297 INFO storing state of public.t1: copy:1 new_state:ok

2009-08-15 02:07:00,089 2297 INFO Table public.t1 status changed to 'ok'

2009-08-15 02:07:00,120 2297 INFO Resetting queue tracking on dst side

2009-08-15 02:07:00,129 2297 INFO got SystemExit(0), exiting

Ceci est somme toute assez compréhensible. N'hésitez pas à jeter un œil aux traces de Slony pour voir la différence. C'est malheureusement le jour et la nuit.

La procédure avec Slony réclame de créer un nouveau set avec la nouvelle table, d'abonner le nœud esclave à ce nouveau set, puis de fusionner l'ancien et le nouveau set. Bref, très lourd. Avec Londiste, rien de tout ça : déclaration de la table au fournisseur, puis à l'abonné... et c'est terminé !

2. Répliquer facilement une grosse base

Nous allons prendre comme exemple la base du forum fluxbb de PostgreSQL (disponible sur http://forums.postgresql.fr).

L'installation de Londiste est identique à ce qui est indiqué ci-dessus. Je n'en reparlerai donc pas. La configuration de PostgreSQL est pratiquement identique. Le seul point de différence est le nom de la base de données. Il ne s'agit plus de base1, mais de fluxbb. Le contenu du fichier ~postgres/.pgpass devient donc :

debian1:5432:fluxbb:postgres:postgres

debian2:5432:fluxbb:postgres:postgres

Nous allons ajouter le schéma de la base fluxbb de debian1 sur la base de même nom sur debian2 :

postgres@debian1:~$ pg_dump -s -n public fluxbb | psql -h debian2 fluxbb

SET                                                                     

SET                                                                     

SET                                                                     

SET                                                                     

SET                                                                     

SET                                                                     

SET                                                                     

SET                                                                     

CREATE TABLE                                                            

ALTER TABLE                                                             

CREATE SEQUENCE                                                         

ALTER TABLE                                                             

ALTER SEQUENCE                                                          

CREATE TABLE                                                            

ALTER TABLE                                                             

[… suite des messages de progression ...]

La mise en place de PGQ est aussi identique à ce qui est indiqué ci-dessus. Je ne reviendrai donc pas là-dessus. Attention à bien renommer la base de données dans le paramètre db.

Par contre, nous allons reprendre toute la mise en place de Londiste. C'est parti !

Commençons par copier le fichier de configuration exemple dans le répertoire de configuration de PostgreSQL en lui donnant un nom spécifique à notre réplication :

debian1:~$ cp /usr/share/doc/skytools/conf/londiste.ini /etc/postgresql/8.3/main/londiste_fluxbb.ini

Nous allons ensuite le modifier pour obtenir ceci :

[londiste]

# should be unique

job_name = replication_fluxbb

# source queue location

provider_db = dbname=fluxbb host=debian1

# target database - it's preferable to run "londiste replay"

# on same machine and use unix-socket or localhost to connect

subscriber_db = dbname=fluxbb host=debian2

# source queue name

pgq_queue_name = londiste.replication_fluxbb

logfile = ~/log/%(job_name)s.log

pidfile = ~/pid/%(job_name)s.pid

# how often to poll event from provider

#loop_delay = 1

# max locking time on provider (in seconds, float)

#lock_timeout = 10.0

Nous installons Londiste sur le fournisseur et sur l'abonné :

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini provider install

2009-08-15 10:13:50,414 4770 INFO plpgsql is installed

2009-08-15 10:13:50,421 4770 INFO txid_current_snapshot is installed

2009-08-15 10:13:50,424 4770 INFO pgq is installed

2009-08-15 10:13:50,426 4770 INFO Installing londiste

2009-08-15 10:13:50,427 4770 INFO   Reading from /usr/share/postgresql/8.3/contrib/londiste.sql

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini subscriber install

2009-08-15 10:13:59,215 4772 INFO Installing plpgsql

2009-08-15 10:13:59,239 4772 INFO Installing londiste

2009-08-15 10:13:59,240 4772 INFO   Reading from /usr/share/postgresql/8.3/contrib/londiste.sql

Nous lançons le démon londiste :

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini replay -d

Nous devons maintenant ajouter toutes les tables de la base fluxbb dans le système de réplication. Plutôt que d'ajouter chaque table une par une, nous allons les récupérer via une requête SQL qui cherchera les informations dans le schéma information_schema (schéma faisant partie du standard SQL) et nous allons passer chaque nom de table à l'outil londiste pour qu'il l'intègre dans la configuration du fournisseur :

postgres@debian1:~$ requete="select table_schema||'.'||table_name from information_schema.tables where table_schema NOT IN ('pg_catalog', 'information_schema', 'pgq', 'londiste') ORDER BY 1;"                                                                                                                                                                         

postgres@debian1:~$ psql -Atc "$requete" fluxbb                                                                                                                                     

public.fbb_bans                                                                                                                                                                     

public.fbb_categories                                                                                                                                                               

public.fbb_censoring                                                                                                                                                                

public.fbb_config                                                                                                                                                                   

public.fbb_forum_perms                                                                                                                                                              

public.fbb_forums                                                                                                                                                                   

public.fbb_groups                                                                                                                                                                   

public.fbb_online                                                                                                                                                                   

public.fbb_posts

public.fbb_ranks

public.fbb_reports

public.fbb_search_cache

public.fbb_search_matches

public.fbb_search_words

public.fbb_subscriptions

public.fbb_topics

public.fbb_users

La requête fonctionne bien. Nous pouvons envoyer le résultat à londiste.

postgres@debian1:~$ psql -Atc "$requete" fluxbb | xargs londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini provider add

2009-08-15 10:54:45,089 4901 INFO Adding public.fbb_bans

2009-08-15 10:54:45,120 4901 INFO Adding public.fbb_categories

2009-08-15 10:54:45,130 4901 INFO Adding public.fbb_censoring

2009-08-15 10:54:45,142 4901 INFO Adding public.fbb_config

2009-08-15 10:54:45,153 4901 INFO Adding public.fbb_forum_perms

2009-08-15 10:54:45,166 4901 INFO Adding public.fbb_forums

2009-08-15 10:54:45,178 4901 INFO Adding public.fbb_groups

2009-08-15 10:54:45,189 4901 INFO Adding public.fbb_online

Traceback (most recent call last):

  File "/usr/bin/londiste", line 134, in <module>

    script.start()

  File "/usr/bin/londiste", line 97, in start

    self.script.start()

  File "/usr/lib/python2.5/site-packages/skytools/scripting.py", line 372, in start

    run_single_process(self, self.go_daemon, self.pidfile)

  File "/usr/lib/python2.5/site-packages/skytools/scripting.py", line 96, in run_single_process

    runnable.run()

  File "/usr/lib/python2.5/site-packages/londiste/setup.py", line 73, in run

    self.admin()

  File "/usr/lib/python2.5/site-packages/londiste/setup.py", line 166, in admin

    self.provider_add_tables(self.args[3:])

  File "/usr/lib/python2.5/site-packages/londiste/setup.py", line 247, in provider_add_tables

    self.provider_add_table(tbl)

  File "/usr/lib/python2.5/site-packages/londiste/setup.py", line 271, in provider_add_table

    self.exec_provider(q, [self.pgq_queue_name, tbl])

  File "/usr/lib/python2.5/site-packages/londiste/setup.py", line 303, in exec_provider

    src_curs.execute(sql, args)

  File "/usr/lib/python2.5/site-packages/psycopg2/extras.py", line 88, in execute

    return _cursor.execute(self, query, vars, async)

psycopg2.InternalError: ERREUR: need key column

CONTEXT: PL/pgSQL function "provider_add_table" line 2 at RETURN

Aïe. Nous avons oublié de vérifier si chaque table disposait d'une clé primaire. Et, a priori, la table fbb_online n'en a pas (la table du dernier message Adding). Nous allons utiliser une requête SQL pour connaître toutes les tables qui n'ont pas de clé primaire.

postgres@debian1:~$ psql -q fluxbb

fluxbb=# SELECT relname FROM pg_class

fluxbb-# WHERE relkind='r' AND NOT relhaspkey

fluxbb-# AND relnamespace=2200;

      relname

--------------------

fbb_online

fbb_search_matches

(2 lignes)

Le filtre permet de ne récupérer que les tables (relkind='r', r pour relation, un mot généralement employé en anglais pour une table) qui n'ont pas de clé primaire (NOT relhaspkey), mais qui font partie du schéma public (relnamespace=2200). Nous filtrons sur le schéma public, car toutes les tables de cette base se trouvent dans ce schéma. Dans le cas contraire, il aurait fallu ajouter les identifiants des autres schémas à incorporer (voir le catalogue système pg_namespace).

Voyons les déclarations des tables fbb_online et fbb_search_matches, seules tables n'ayant pas de clé primaire.

fluxbb=# \d fbb_online

                        Table « public.fbb_online »

Colonne |          Type          |             Modificateurs

---------+------------------------+----------------------------------------

user_id | integer                | not null default 1

ident   | character varying(200) | not null default ''::character varying

logged | integer                | not null default 0

idle    | smallint               | not null default 0

Index :

    « fbb_online_user_id_idx » btree (user_id)

fluxbb=# \d fbb_search_matches

      Table « public.fbb_search_matches »

    Colonne    |   Type   |   Modificateurs

---------------+----------+--------------------

post_id       | integer | not null default 0

word_id       | integer | not null default 0

subject_match | smallint | not null default 0

Index :

    « fbb_search_matches_post_id_idx » btree (post_id)

    « fbb_search_matches_word_id_idx » btree (word_id)

Il est donc possible de leur ajouter une colonne id, qu'on déclarera comme clé primaire.

fluxbb=# ALTER TABLE fbb_online ADD COLUMN id serial PRIMARY KEY;

NOTICE: ALTER TABLE créera des séquences implicites « fbb_online_id_seq » pour la colonne serial « fbb_online.id »

NOTICE: ALTER TABLE / ADD PRIMARY KEY créera un index implicite « fbb_online_pkey » pour la table « fbb_online »

fluxbb=# ALTER TABLE fbb_search_matches ADD COLUMN id serial PRIMARY KEY;

NOTICE: ALTER TABLE créera des séquences implicites « fbb_search_matches_id_seq » pour la colonne serial « fbb_search_matches.id »

NOTICE: ALTER TABLE / ADD PRIMARY KEY créera un index implicite « fbb_search_matches_pkey » pour la table « fbb_search_matches »

Parfait, recommençons l'ajout des tables.

postgres@debian1:~$ psql -Atc "$requete" fluxbb | xargs londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini provider add

2009-08-15 18:29:40,173 5941 INFO Adding public.fbb_online

2009-08-15 18:29:40,217 5941 INFO Adding public.fbb_posts

2009-08-15 18:29:40,228 5941 INFO Adding public.fbb_ranks

2009-08-15 18:29:40,242 5941 INFO Adding public.fbb_reports

2009-08-15 18:29:40,253 5941 INFO Adding public.fbb_search_cache

2009-08-15 18:29:40,264 5941 INFO Adding public.fbb_search_matches

2009-08-15 18:29:40,277 5941 INFO Adding public.fbb_search_words

2009-08-15 18:29:40,289 5941 INFO Adding public.fbb_subscriptions

2009-08-15 18:29:40,299 5941 INFO Adding public.fbb_topics

2009-08-15 18:29:40,313 5941 INFO Adding public.fbb_users

Remarquez qu'il ne dit rien lorsque nous essayons d'ajouter une table déjà présente. Il s'est contenté d'ajouter les tables manquantes.

Maintenant, abonnons debian2 à toutes les tables dont debian1 est fournisseur. Pour cela, nous allons récupérer toutes les tables que fournit debian1 (argument provider tables de londiste), que nous passerons à londiste avec l'argument subscriber add.

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini provider tables | xargs londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini subscriber add

2009-08-15 18:30:57,050 5953 INFO Checking public.fbb_censoring

2009-08-15 18:30:57,097 5953 INFO Checking public.fbb_categories

2009-08-15 18:30:57,116 5953 INFO Checking public.fbb_subscriptions

2009-08-15 18:30:57,128 5953 INFO Checking public.fbb_search_matches

2009-08-15 18:30:57,151 5953 ERROR subscriber table public.fbb_search_matches has no primary key (vvv)

2009-08-15 18:30:57,152 5953 INFO Checking public.fbb_topics

2009-08-15 18:30:57,167 5953 INFO Checking public.fbb_search_words

2009-08-15 18:30:57,182 5953 INFO Checking public.fbb_forum_perms

2009-08-15 18:30:57,202 5953 INFO Checking public.fbb_reports

2009-08-15 18:30:57,217 5953 INFO Checking public.fbb_online

2009-08-15 18:30:57,235 5953 ERROR subscriber table public.fbb_online has no primary key (vvvv)

2009-08-15 18:30:57,236 5953 INFO Checking public.fbb_bans

2009-08-15 18:30:57,257 5953 INFO Checking public.fbb_users

2009-08-15 18:30:57,282 5953 INFO Checking public.fbb_forums

2009-08-15 18:30:57,313 5953 INFO Checking public.fbb_posts

2009-08-15 18:30:57,335 5953 INFO Checking public.fbb_ranks

2009-08-15 18:30:57,361 5953 INFO Checking public.fbb_config

2009-08-15 18:30:57,378 5953 INFO Checking public.fbb_search_cache

2009-08-15 18:30:57,397 5953 INFO Checking public.fbb_groups

Re-aïe ! Nous n'avons ajouté les clés primaires que sur debian1. Il faut aussi les mettre sur debian2. En effet, tout comme Slony, Londiste ne propage pas les modifications de schéma. Ajoutons donc ses deux clés sur les tables de la cible :

postgres@debian1:~$ psql -q -h debian2 fluxbb

fluxbb=# ALTER TABLE fbb_online ADD COLUMN id serial PRIMARY KEY;

NOTICE: ALTER TABLE créera des séquences implicites « fbb_online_id_seq » pour la colonne serial « fbb_online.id »

NOTICE: ALTER TABLE / ADD PRIMARY KEY créera un index implicite « fbb_online_pkey » pour la table « fbb_online »

fluxbb=# ALTER TABLE fbb_search_matches ADD COLUMN id serial PRIMARY KEY;

NOTICE: ALTER TABLE créera des séquences implicites « fbb_search_matches_id_seq » pour la colonne serial « fbb_search_matches.id »

NOTICE: ALTER TABLE / ADD PRIMARY KEY créera un index implicite « fbb_search_matches_pkey » pour la table « fbb_search_matches »

Maintenant, c'est bon. Pour savoir si le précédent appel à londiste a ajouté déjà quelques tables, nous allons utiliser l'argument subscriber missing de londiste pour connaître toutes les tables manquantes.

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini subscriber missing

Table: public.fbb_bans                                                                      

Table: public.fbb_categories                                                                

Table: public.fbb_censoring                                                                 

Table: public.fbb_config                                                                    

Table: public.fbb_forum_perms                                                               

Table: public.fbb_forums                                                                    

Table: public.fbb_groups                                                                    

Table: public.fbb_online                                                                    

Table: public.fbb_posts                                                                     

Table: public.fbb_ranks                                                                     

Table: public.fbb_reports

Table: public.fbb_search_cache

Table: public.fbb_search_matches

Table: public.fbb_search_words

Table: public.fbb_subscriptions

Table: public.fbb_topics

Table: public.fbb_users

Autrement dit, aucune n'a été ajouté à l'abonnement. Nous allons recommencer :

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini provider tables | xargs londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini subscriber add

2009-08-15 18:33:23,667 5967 INFO Checking public.fbb_censoring

2009-08-15 18:33:23,697 5967 INFO Checking public.fbb_categories

2009-08-15 18:33:23,714 5967 INFO Checking public.fbb_subscriptions

2009-08-15 18:33:23,731 5967 INFO Checking public.fbb_search_matches

2009-08-15 18:33:23,750 5967 INFO Checking public.fbb_topics

2009-08-15 18:33:23,768 5967 INFO Checking public.fbb_search_words

2009-08-15 18:33:23,785 5967 INFO Checking public.fbb_forum_perms

2009-08-15 18:33:23,800 5967 INFO Checking public.fbb_reports

2009-08-15 18:33:23,823 5967 INFO Checking public.fbb_online

2009-08-15 18:33:23,841 5967 INFO Checking public.fbb_bans

2009-08-15 18:33:23,857 5967 INFO Checking public.fbb_users

2009-08-15 18:33:23,881 5967 INFO Checking public.fbb_forums

2009-08-15 18:33:23,897 5967 INFO Checking public.fbb_posts

2009-08-15 18:33:23,914 5967 INFO Checking public.fbb_ranks

2009-08-15 18:33:23,930 5967 INFO Checking public.fbb_config

2009-08-15 18:33:23,947 5967 INFO Checking public.fbb_search_cache

2009-08-15 18:33:23,975 5967 INFO Checking public.fbb_groups

2009-08-15 18:33:24,001 5967 INFO Adding public.fbb_censoring

2009-08-15 18:33:24,022 5967 INFO Adding public.fbb_categories

2009-08-15 18:33:24,037 5967 INFO Adding public.fbb_subscriptions

2009-08-15 18:33:24,059 5967 INFO Adding public.fbb_search_matches

2009-08-15 18:33:24,077 5967 INFO Adding public.fbb_topics

2009-08-15 18:33:24,088 5967 INFO Adding public.fbb_search_words

2009-08-15 18:33:24,097 5967 INFO Adding public.fbb_forum_perms

2009-08-15 18:33:24,112 5967 INFO Adding public.fbb_reports

2009-08-15 18:33:24,122 5967 INFO Adding public.fbb_online

2009-08-15 18:33:24,131 5967 INFO Adding public.fbb_bans

2009-08-15 18:33:24,145 5967 INFO Adding public.fbb_users

2009-08-15 18:33:24,155 5967 INFO Adding public.fbb_forums

2009-08-15 18:33:24,164 5967 INFO Adding public.fbb_posts

2009-08-15 18:33:24,173 5967 INFO Adding public.fbb_ranks

2009-08-15 18:33:24,185 5967 INFO Adding public.fbb_config

2009-08-15 18:33:24,195 5967 INFO Adding public.fbb_search_cache

2009-08-15 18:33:24,204 5967 INFO Adding public.fbb_groups

Peu après, le transfert commence pour la première table :

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini subscriber tables

Table                                           State

public.fbb_censoring                          in-copy

public.fbb_categories                               -

public.fbb_subscriptions                            -

public.fbb_search_matches                           -

public.fbb_topics                                   -

public.fbb_search_words                             -

public.fbb_forum_perms                              -

public.fbb_reports                                  -

public.fbb_online                                   -

public.fbb_bans                                     -

public.fbb_users                                    -

public.fbb_forums                                   -

public.fbb_posts                                    -

public.fbb_ranks                                    -

public.fbb_config                                   -

public.fbb_search_cache                             -

public.fbb_groups                                   -

Un peu plus tard, nous pouvons vérifier la progression :

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini subscriber tables

Table                                           State

public.fbb_censoring                               ok

public.fbb_categories                              ok

public.fbb_subscriptions                           ok

public.fbb_search_matches                 catching-up

public.fbb_topics                                   -

public.fbb_search_words                             -

public.fbb_forum_perms                              -

public.fbb_reports                                  -

public.fbb_online                                   -

public.fbb_bans                                     -

public.fbb_users                                    -

public.fbb_forums                                   -

public.fbb_posts                                    -

public.fbb_ranks                                    -

public.fbb_config                                   -

public.fbb_search_cache                             -

public.fbb_groups                                   -

Et, au bout d'un moment, tout le transfert est terminé :

postgres@debian1:~$ londiste /etc/postgresql/8.3/main/londiste_fluxbb.ini subscriber tables

Table                                           State

public.fbb_censoring                               ok

public.fbb_categories                              ok

public.fbb_subscriptions                           ok

public.fbb_search_matches                          ok

public.fbb_topics                                  ok

public.fbb_search_words                            ok

public.fbb_forum_perms                             ok

public.fbb_reports                                 ok

public.fbb_online                                  ok

public.fbb_bans                                    ok

public.fbb_users                                   ok

public.fbb_forums                                  ok

public.fbb_posts                                   ok

public.fbb_ranks                                   ok

public.fbb_config                                  ok

public.fbb_search_cache                            ok

public.fbb_groups                                  ok

Voilà, la réplication est terminée. Toute modification sur le premier serveur se verra renvoyée sur le serveur abonné.

3. Surveiller Londiste

La surveillance de Londiste se fait en deux points : surveillance du lag de données entre les deux serveurs, et surveillance du schéma de données.

Le premier point peut se faire grâce à la requête suivante :

postgres@debian1:~$ psql -q fluxbb

fluxbb=# SELECT queue_name, consumer_name, lag, last_seen

fluxbb-#    FROM pgq.get_consumer_info();

         queue_name          |   consumer_name    |       lag       |   last_seen

-----------------------------+--------------------+-----------------+----------------

londiste.replication_fluxbb | replication_fluxbb | 00:00:27.567343 | 00:00:27.29114

(1 ligne)

Le lag est généralement inférieur à 1 minute. S'il est bien supérieur, il est temps de se poser quelques questions.

Quant au schéma, il vous est toujours possible d'utiliser le script Perl check_postgres.pl avec son action same_schema, mais vous disposez aussi de quelques outils du côté de la commande londiste. Nous avons déjà parlé de subscriber missing, capable de détecter les tables déclarées par le fournisseur, mais manquantes sur l'abonné. Vous pouvez aussi vérifier les différences entre deux structures avec subscriber check.

Vous pouvez même vérifier les différences de données grâce à compare. Pour résoudre ce type de problème, vous pouvez passer par un subscriber resync avec le nom de la table fautive pour ne re-synchroniser que cette table.

4. Les schémas Skytools

PGQ et Londiste, comme Slony dans l'article précédent, ont créé un schéma pour stocker la configuration.

Voici la liste des tables importantes pour le schéma pgq :

Table

Commentaires

consumer

liste des abonnés

queue

liste des queues déclarées

retry_queue


subscription

liste des abonnements

tick


  Et voici la liste des tables importantes pour le schéma londiste :

Table

Commentaires

completed


link


provider_seq

liste des séquences enregistrées pour le fournisseur

provider_table

liste des tables enregistrées pour le fournisseur

subscriber_pending_fkeys

liste des clés étrangères dont l'activité est suspendue

subscriber_pending_triggers

liste des triggers dont l'activité est suspendue

subscriber_seq

liste des séquences auxquelles est abonné l'esclave

subscriber_table

liste des tables auxquelles est abonné l'esclave

5. Ce qui est prévu pour les Skytools 3

L'idée est de conserver le bon (pratiquement tout) et d'ajouter de nouvelles fonctionnalités. On peut notamment citer parmi les fonctionnalités ajoutées :

- la copie parallélisée (permet d'accélérer la mise en place de la réplication sur un gros serveur) ;

- la commande EXECUTE pour exécuter un script SQL sur les deux serveurs (permet de faciliter la mise à jour du schéma d'une base de données répliquée) ;

- la création automatique des tables et index lors de l'abonnement de leurs modifications à l'esclave (facilite le travail de mise en place d'une réplication) ;

- le support de la cascade de serveurs (permet de gérer des cas bien plus complexes de réplication).

Certaines opérations sont facilitées, comme le changement de maître, la pause dans la réplication, etc.

6. Petit récapitulatif

Avantages majeurs :

- très simple à mettre en place ;

- très grande granularité ;

- pas de configuration compliquée ;

- les esclaves en lecture seule ;

- mise à jour de PostgreSQL rapide et avec le moins possible d'arrêt de production.

Inconvénients majeurs :

- pas de support de l'exécution de scripts SQL sur le maître et l'esclave (corrigé en version 3) ;

- pas de copie parallélisée (corrigé en version 3) ;

- pas de serveurs en cascade (corrigé en version 3) ;

- pas de réplication automatique des objets ;

- pas de réplication du TRUNCATE avant la 8.4 ;

- très peu de documentation.

Conclusion

Skype nous fournit un excellent produit, qui a profité de beaucoup plus d'attention aux détails que Slony. Exactement ce qu'il manque à Slony en fait. Cependant, la documentation est pire, étant donné qu'elle n'existe pas. Le wiki de PostgreSQL propose un guide pratique pour aider à l'installation, mais cela en reste là. Autant dire bien peu de choses.

Rien que le fait qu'il n'y ait pas d'outils aidant à la mise en place est un excellent indice pour comprendre le sérieux de produit.


Par le même auteur

Évolution de PostgreSQL en version 11

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
101
|
Mois de parution
mars 2019
|
Domaines
Résumé
La version 11 de PostgreSQL est sortie le 18 octobre. Une première version corrective est déjà sortie et la seconde est prévue pour le 14 février 2019. Cette nouvelle version est principalement une version 10 améliorée : rien de bien révolutionnaire, mais de nouvelles fonctionnalités qui aident bien.

Performances et supervision avec PostgreSQL en version 10

Magazine
Marque
GNU/Linux Magazine
Numéro
220
|
Mois de parution
novembre 2018
|
Domaines
Résumé
Après avoir présenté les nouveautés majeures de la version 10, il nous reste à nous pencher sur les performances et la supervision. Cette version apporte beaucoup d’améliorations sur ces deux sujets. Les nouveautés en termes de supervision raviront les administrateurs cherchant à mieux comprendre le comportement de PostgreSQL. Quant aux améliorations de performance, elles sont nombreuses, la plus attendue étant un meilleur support de la parallélisation. Deux excellentes raisons pour installer cette version 10… avant de passer à la version 11 !

La version 10 de PostgreSQL et la réplication

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
99
|
Mois de parution
novembre 2018
|
Domaines
Résumé
Depuis la version 9.0, les développeurs de PostgreSQL améliorent sans cesse la réplication interne. Cette version ne fait pas exception, et continue à proposer de nouvelles options sur la réplication physique. Elle ajoute aussi un type de réplication attendu depuis longtemps, la réplication logique.

PostgreSQL 10, quelques nouvelles fonctionnalités

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
97
|
Mois de parution
juillet 2018
|
Domaines
Résumé
La version 10 de PostgreSQL est sortie depuis quelques mois, il est temps de faire un tour des nouvelles fonctionnalités et des changements majeurs. Ce premier article va discuter de différents points particulièrement intéressants, mais les trois grosses nouveautés, à savoir le partitionnement, la réplication logique et les améliorations au niveau performance et supervision seront abordées chacune dans leur propre article.

Partitionnement avec PostgreSQL 10

Magazine
Marque
GNU/Linux Magazine
Numéro
217
|
Mois de parution
juillet 2018
|
Domaines
Résumé
Le partitionnement dans PostgreSQL a toujours été un contournement d’autres fonctionnalités pour arriver à une séparation plus ou moins invisible, du point de vue de l’application, des données d’une table sur plusieurs tables. Il y eut de nombreuses tentatives au fil des ans pour améliorer cela, mais il y eut autant d’échecs... sauf avec cette version 10 qui réussit haut la main ce challenge. Cet article explique les différentes améliorations liées au partitionnement en version 10. On y voit aussi que certaines limitations restent présentes.

PostgreSQL 9.6 : les fonctionnalités moteurs

Magazine
Marque
GNU/Linux Magazine
Numéro
201
|
Mois de parution
février 2017
|
Domaines
Résumé
Dans un précédent article (voir GNU/Linux Magazine n°198), nous avons pu voir la nouveauté phare de la version 9.6 de PostgreSQL. Mais il ne s’agit pas de la seule amélioration de cette nouvelle version. Les développeurs ont passé aussi beaucoup de temps sur l’API de gestion des tables distantes, sur les possibilités offertes par la réplication physique, et sur plusieurs optimisations du moteur. Ils ont aussi travaillé sur différents aspects de l’administration comme la sauvegarde et la sécurité.