Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

synchroniser deux bases de données

4 réponses
Avatar
unbewusst.sein
j'ai deux bd l'une sur mon portable l'autre sur mon ordi de bureau.
assez souvent mon portable est connectable sur le net donc sur mon ordi
de bureau, je souhaite procéder à ces moments là, à une synchronisation
des deux bd.

Les bd sont en PostgreSQL, il peut y avoir eu des insertions et des
modifications des deux côtés, dans le pire des cas, plus généralement
côté portable.

Chaque table a son "rowid SERIAL PRIMARY KEY" et deux timestamps :
ctime TIMESTAMP WITH TIME ZONE NOT NULL,
mtime TIMESTAMP WITH TIME ZONE NOT NULL

ctime, la date de création ;
mtime la date de modification.

bon, trouver les modifs (non simultanées des deux côtés) c'est facile.

s'il y a modifs simultanées des deux côtés, je ne vois pas comment
faire.

sinon avoir une table de modifications temporaire vidée après synchro.

restent les cas où il y a eu insertion, je ne vois pas comment gérer le
"rowid SERIAL PRIMARY KEY", puis-je forcer sa valeur ?

par exemple, j'ai incerré un item de chaque côté, sur des bases
supposées synchronisées, ils ont donc un contenu différent et un rowid
identique.

je garderais, par exemple, la ligne correspondant à l'insertion la plus
ancienne et incrémenterait le rowid de la plus récente.

Y a t'il des tutos spécifiques à ce genre de pb ?

--
« Qui ne pète ni ne rote est voué à l'explosion. »
(Lao-Tseu)

4 réponses

Avatar
WebShaker
Le 04/04/2012 07:49, Une Bévue a écrit :
s'il y a modifs simultanées des deux côtés, je ne vois pas comment
faire.



En fait, cela ne peut se produire.
Si tu n'avais qu'une seule base et deux utilisateurs qui modifient un
enregistrement en même temps, le SGBD ferai passer une requête avant
l'autre, et s'il n'existe aucun trigger sur le ONCREATE, alors en gros
la modification du premier serait purement écrasé.
donc si tu as l'exacte même date de modification, tu peux définir
l'ordre que tu veux cela n'a pas d'importance.

sinon avoir une table de modifications temporaire vidée après synchro.

restent les cas où il y a eu insertion, je ne vois pas comment gérer le
"rowid SERIAL PRIMARY KEY", puis-je forcer sa valeur ?



Il me semble que oui tant que l'id n'existe pas (et qu'il n'existe pas
d'id superieur)
Enfin ça reste a vérifier.

par exemple, j'ai incerré un item de chaque côté, sur des bases
supposées synchronisées, ils ont donc un contenu différent et un rowid
identique.



Tout le problème est là!
Tes deux enregistrements on effectivement le même ID !
Pour peu que tu ai en plus crée d'autre enregistrement ayant une
jointure avec le premier, alors là c'est la cauchemard.

En fait il faut raisonner "Object" et non plus "Enregistrement".
En gros il faut dire: je dois synchronier un objet. Peu importe la
valeur de ses serials (qui ne sont plus représentatif dans ton cas).
Tu relis l'objet entièrement (donc éventuellement plusieurs
enregistrement liés entre eux) et tu le recrée dans la base de données
destination.
Essayer de conserver la valeur des sérials n'a aucun intérêt ici ! Ils
ne peuvent pas servir de clés.

Il te faut une clé algorithmique. C'est à dire calculée en fonction de
la valeur de l'objet qui soit différente à chaque nouvel objet, même si
deux objets sont créés en même temps sur deux bases de données différente.

Pour être clair, si tu crée les même "items" sur tes deux base de
données, exactement en même temps, il faut que tu sache qu'il ne s'agit
pas du même items répliqué mais bien de deux items distincts.

Donc tu l'as compris, ton item doit contenir une information concernant
la machine qui l'a crée (ton portable ou ton micro).
Cela peut être l'IP, l'adresse MAC, un cookie quelconque, ...

je garderais, par exemple, la ligne correspondant à l'insertion la plus
ancienne et incrémenterait le rowid de la plus récente.

Y a t'il des tutos spécifiques à ce genre de pb ?



Sans doute !
http://www.google.fr/webhp?sourceid=chrome-instant&ix=seb&ie=UTF-8&ion=1#hl=fr&output=search&sclient=psy-ab&q=synchronisation%20sgbd&oq=&aq=&aqi=&aql=&gs_l=&pbx=1&fpøef0e11bfe086e9&ix=seb&ion=1&bav=on.2,or.r_gc.r_pw.r_qf.,cf.osb&biw20&bih75

Etienne
Avatar
unbewusst.sein
WebShaker wrote:

> s'il y a modifs simultanées des deux côtés, je ne vois pas comment
> faire.

En fait, cela ne peut se produire.



oui et non, disons que oui, le timestamp sera nécessairement différent,
mais ce qui compte ce sont les moments où la synchro est faite.


> restent les cas où il y a eu insertion, je ne vois pas comment gérer le
> "rowid SERIAL PRIMARY KEY", puis-je forcer sa valeur ?

Il me semble que oui tant que l'id n'existe pas (et qu'il n'existe pas
d'id superieur) Enfin ça reste a vérifier.



oui j'ai vérifié, j'avais une base où il manquait d'un côté le rowid 2
et de l'autre le rowid 281, ça a marché sans broncher avec psql 9.1.

> par exemple, j'ai incerré un item de chaque côté, sur des bases
> supposées synchronisées, ils ont donc un contenu différent et un rowid
> identique.

Tout le problème est là! Tes deux enregistrements on effectivement le même
ID ! Pour peu que tu ai en plus crée d'autre enregistrement ayant une
jointure avec le premier, alors là c'est la cauchemard.

En fait il faut raisonner "Object" et non plus "Enregistrement".



OUI, oui, très bonne remarque, je dois "repenser" mes bases...

En gros il faut dire: je dois synchronier un objet. Peu importe la valeur
de ses serials (qui ne sont plus représentatif dans ton cas). Tu relis
l'objet entièrement (donc éventuellement plusieurs enregistrement liés
entre eux) et tu le recrée dans la base de données destination. Essayer de
conserver la valeur des sérials n'a aucun intérêt ici ! Ils ne peuvent pas
servir de clés.



C'est vrai, j'en suis convaincu, ce qui compte ce sont les objets
extraits...

Il te faut une clé algorithmique. C'est à dire calculée en fonction de la
valeur de l'objet qui soit différente à chaque nouvel objet, même si deux
objets sont créés en même temps sur deux bases de données différente.

Pour être clair, si tu crée les même "items" sur tes deux base de données,
exactement en même temps, il faut que tu sache qu'il ne s'agit pas du même
items répliqué mais bien de deux items distincts.

Donc tu l'as compris, ton item doit contenir une information concernant la
machine qui l'a crée (ton portable ou ton micro). Cela peut être l'IP,
l'adresse MAC, un cookie quelconque, ...



ouais, l'adresse MAC, c'est bon pour moi.

> je garderais, par exemple, la ligne correspondant à l'insertion la plus
> ancienne et incrémenterait le rowid de la plus récente.
>
> Y a t'il des tutos spécifiques à ce genre de pb ?

Sans doute !
http://www.google.fr/webhp?sourceid=chrome-instant&ix=seb&ie=UTF-8&ion=1#h
l=fr&output=search&sclient=psy-ab&q=synchronisation%20sgbd&oq=&aq=&aqi=&aq
l=&gs_l=&pbx=1&fpøef0e11bfe086e9&ix=seb&ion=1&bav=on.2,or.r_gc.r_pw.r_qf
.,cf.osb&biw20&bih75



je lirai certains articles attentivement.

merci bien pour cette longue réponse.

-- « Qui ne pète ni ne rote est voué à l'explosion. » (Lao-Tseu)
Avatar
Joseph Boudou
Salut,

Voici comment je ferais ça, moi (oui, je suis un bourrin). Ce qu'il
faut c'est définir un serveur central (disons le poste fixe). Pour tous
les autres (càd le portable), il suffit de conserver le rowid du
dernier machin synchronisé (last_synchro). Ensuite on fait :

- Verrouiller tout ce qui craint (surtout la séquence du rowid)
- Récupérer la valeur de la séquence sur le central
- Faire la différence (diff) avec last_synchro
- Sur le client :
Update table set rowid = rowid + diff where rowid > last_synchro
- Faire le transfert
- Mettre à jour la séquence des deux cotés
- Déverrouiller
- Mettre à jour le last_synchro

--
Le bricolage, c'est l'huile des rouages informatiques : on ne peut pas
faire un beau système qu'avec de l'huile mais ceux qui oublient que ça
existe se demandent encore pourquoi des fois ça bloque...
-- Paul Gaborit dans fcou --
Avatar
Une Bévue
Le 08/04/2012 22:26, Joseph Boudou a écrit :
Salut,

Voici comment je ferais ça, moi (oui, je suis un bourrin). Ce qu'il
faut c'est définir un serveur central (disons le poste fixe). Pour tous
les autres (càd le portable), il suffit de conserver le rowid du
dernier machin synchronisé (last_synchro). Ensuite on fait :

- Verrouiller tout ce qui craint (surtout la séquence du rowid)
- Récupérer la valeur de la séquence sur le central
- Faire la différence (diff) avec last_synchro
- Sur le client :
Update table set rowid = rowid + diff where rowid> last_synchro
- Faire le transfert
- Mettre à jour la séquence des deux cotés
- Déverrouiller
- Mettre à jour le last_synchro




peut-être bourrin, mais efficace et assez simple...
merci !