Vous n'êtes pas identifié(e).
oui, c'est ce qu'il m'a été répondu par Frédéric BROUARD sur fr.comp.applications.sgbd :
Message-ID: <5075abb8$0$1720$426a74cc@news.free.fr>
uuid a deux algo possible md5 et sha1.
clairement l'uuid/md5 par ex est tout simplement le md5 tronçonné.
voire : http://phpdevblog.free.fr/?p=12
donc, du seul point de vue de mon utilisation c'est kifkif.
je concatène mon objet en string et j'en prend le sha1, plus long que le md5 me semble t'il pour la même chaine.
cerise sur le gateau les algos php et ruby donnent le même résultat, je viens juste de tester "à la main".
yapuka )))
non, ce n'est pas évident de synchroniser deux bases : trouver les insertions, c'est fastoche, trouver les modifs aussi MAIS à condition qu'il n'y en ait que sur un seul ordi, sinon ce n'est pas possible.
DONC, ça implique une discipline : n'utiliser qu'un ordi à la fois et synchroniser dès que la connection est possible...
pour les suppressions, c'est autre chose, il faut que mon code enregistre dans une base à part les suppressions sinon à la synchro suivante le code recréerait de l'autre côté...
bon, je viens d'éditer le sujet à partir de mon premier message.
Merci bien pour cette précision, je vais donc devoir lire la doc sur ctid.
M'enfin là c'était juste pour un dépannage suite à fausse manip.
Donc, si je comprends bien il vaut mieux ajouter un rowid ou quelque chose dans le genre.
Justement, je profite de ce fil pour avoir des tuyaux concernant les clés sur une base.
En fait ce que je cherche à faire c'est à synchroniser deux bases sur deux ordis différents.
Je trouve que ce n'est pas facile.
Par exemple le rowid d'une base n'est pas vraiment utile pour la synchro.
Ce que j'ai imaginé :
- créer, à l'insertion d'une nouvelle entrée, une clé qui serait le md5 de la concatenation de tous les champs, appelons-la "cle_insert" , elle sera la clé primaire pour repérer les objets ;
- enregistrer le datetime à la création soit la colonne "dt_insert" ;
- créer à chaque modif d'une ligne une clé, au départ de valeur identique à "cle_insert" et qui serait elle le md5 de la concatenation de la ligne modifiée, appellons-la "cle_modif", bien sûr "cle_insert" ne change jamais.
- enregistrement le datetime à la modif soit la colonne "dt_modif" ;
donc avec ces deux cles je peux repérer très facilement :
- les insertions, "cle_insert" existe d'un côte mais pas de l'autre ;
- les modifications simples càd celles où un objet n'a été changé que d'un côté, les dt_modif seront différents, les cle_modif aussi et ce pour la meme cle -invariable- cle_insert ;
- vient le problème plus délicat où une ligne de même cle_insert a été changée des deux côtés "en même temps" du point de vue de la synchronisation. car la synchro ne pourra se faire que lorsque les deux ordis seront connectés au net, ce qui n'est pas toujours le cas, l'un des deux étant un portable.
dans ce cas, je ne vois pas trop comment faire mis à part avoir une sorte de cache enregistrant l'état de la base à chaque synchro.
aussi je ne vois pas trop comment régler le problème des suppressions de ligne sinon qu'il faut enregistrer qu'une ligne a été supprimée pour que ce soit su au moment de la synchro.
bon tout cela est un peu en vrac...
OUI, merci, c'est ce que j'ai pensé aussi, jsute après avoir posté.
Erreur stupide de ma part (j'ai fait deux manips en même temps).
RESOLU
tiens au fait sur ce forum, y a t'il un moyen d'ajouter "Résolu" sur le sujet ???
je cherche des pistes...
je viens de faire, en ruby, des insertions sur un serveur distant.
d'après ce que me dit ruby, les insertions non seulement ont bien marché mais aussi je peux encore interroger la base en ruby.
par contre depuis php j'ai droit au message :
Error 500 (Internal Server Error)
bien sûr je ne demande pas de solution )))
mais des conseils pour investiguer ce qu'il a pu se passer.
NB : "le serveur distant", c'est le portable à côté de moi, aussi j'ai pu vérifier en cli que je puis toujours interroger la base.
Bon, j'ai trouvé une solution élégante sur le net http://www.postgresonline.com/journal/a … Table.html "DELETING DUPLICATE RECORDS IN A TABLE" :
yt_tests=# select ctid, * from cities where cities.name like 'Merr%' ;
ctid | name | location
-------+--------+----------
(0,2) | Merris | (0.5,49)
(0,4) | Merris | (0.5,49)
(2 rows)
yt_tests=# select max(ctid) from cities where cities.name like 'Merr%' ;
max
-------
(0,4)
(1 row)
yt_tests=# delete from cities where ctid not in (select max(ctid) from cities where cities.name like 'Merr%');
DELETE 1
yt_tests=# select ctid, * from cities where cities.name like 'Merr%' ;
ctid | name | location
-------+--------+----------
(0,4) | Merris | (0.5,49)
(1 row)
Toute l'astuce est de prendre le max de ctid...
Je me gouratte, c'est bien "ctid" et non "cityid" comme je l'ai écrit précédemment.
ça retourne d'ailleurs un couple de valeurs :
yt_tests=# select ctid, * from cities where cities.name like 'Merr%' ;
ctid | name | location
-------+--------+----------
(0,2) | Merris | (0.5,49)
(0,4) | Merris | (0.5,49)
(2 rows)
je dois regarder la doc pour savoir comment faire un delete sur un des couples ctid retournés.
Ah d'accord, merci beaucoup, je ne savais pas du tout que le limit n'était que pour la présentation du résultat.
Dans ma base de test, il n'y a pas de cityid, c'est créé tout seul ?
Je veux dire c'est interne à postgres ?
c'est juste un petit test que je viens de faire.
j'ai une table cities qui a des doublons, en fait toutes les entrées sont en double suite à une fausse manip de ma part...
bon si je fais un :
select cities.name from cities where cities.name like 'Merr%' limit 1;
j'ai un résultat unique (limit 1) :
name
--------
Merris
(1 row)
normal, MAIS ce qui ne "me" semble pas normal c'est que si je fais un delete in avec le précédent select, ça m'endelete 2 :
delete from cities where cities.name in (select cities.name from cities where cities.name like 'San%' limit 1);
DELETE 2
j'sais bien, c'est forcément SQL qui a raison...
Oui, merci, j'ai lu, à la page :
http://willbryant.net/software/mac_os_x … on_leopard
qu'il fallait changer shmall et shmax.
Sur Mac OS X , la page précédente parle de Leopard, ça marche aussi sur Mountain Lion.
Pour essai, ce qu'il faut faire au terminal :
$ sudo sysctl -w kern.sysv.shmall=65536
$ sudo sysctl -w kern.sysv.shmmax=16777216
Et après avoir vérifié que c'est OK, rendre ce changement permanent après reboot dans un fichier de conf "/etc/sysctl.conf" :
kern.sysv.shmall=65536
kern.sysv.shmmax=16777216
Il faut créer ce fichier (ie. "/etc/sysctl.conf") s'il n'existe pas, c'est le cas sur une installation fraiche.
Ce qui était mon cas.
En tout cas merci bien pour votre diligente réponse.
Sur Mac OS X Mountain Lion, je viens juste d'installer psql.
le serveur ne se lance pas et le fichier de log m'indique :
cat /usr/local/var/postgres/server.log
FATAL: could not create shared memory segment: Cannot allocate memory
DETAIL: Failed system call was shmget(key=5432002, size=3809280, 03600).
HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory or swap space, or exceeded your kernel's SHMALL parameter. You can either reduce the request size or reconfigure the kernel with larger SHMALL. To reduce the request size (currently 3809280 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
The PostgreSQL documentation contains more information about shared memory configuration.
j'ai déjà installé psql sur Lion, sans problème, là j'ai utilisé HomeBrew pour son installation.
au cas où quelqu'un aurait une "recette" pour remédier à ce problème.
Très juste car, après avoir changé le port pour 5432 dans mon fichier de conf, au redémarrage de postgresql, j'ai eu droit à ce message d'erreur :
$ sudo /etc/init.d/postgresql restart
[sudo] password for yt:
* Restarting PostgreSQL 9.1 database server * Error: Port conflict: another instance is already running on /var/run/postgresql with port 5432
je suis donc resté à 5433.
Par contre je ne pige pas d'où vient le premier postgresql sur le port 5432...
En fait j'ai réinstallé Xubuntu 12.04, après un crash disk MAIS j'ai utilisé le "même" iso de Xubuntu / Voyager 12.04 LTS.
Et comme j'enregistre dans un répertoire ~/Installations, toutes les installations et configs que je fais, dans l'ordre chronologique, je suppute que l'iso downloadé fin aout n'était pas le même qu'en avril ???
Merci bien pour votre réponse.
En fait j'ai trouvé le problème, "un peu par hazard", je ne sais pas pourquoi MAIS, dans le fichier postgresql.conf le port par défaut est 5433 au lieu de celui, usuel, de 5432...
Je ne sais pas du tout ce qui a fait ce changement de port, en tk, c'est pas moi )))
OK, merci bien.
J'ai bien vu que /usr/bin/psql n'est qu'un symlink vers un wrapper.
je regarderai ce wrapper et son perl.
du coup je ne comprends pas pour quoi ça ne marche pas avec php.
un truc bizarre aussi est que si, depuis php, je mets la variable $host à l'adresse IPV6 d'un autre serveur, ça marche très bien.
autrement, depuis php ça ne marche pas uniquement pour le server en localhost...
par ailleurs ceci résulte d'une seconde installation d'Ubuntu 12.04, à la première je n'ai pas eu ce problème, mais peut-être est-ce que ça provients des updates...
Je viens de réinstaller Xubuntu / Voyager 12.04 sur ma bécanne, suite à "crash" du disk.
J'en suis à rétablir mes bases de données PostgreSQL.
Comme je l'avais fait lors de ma première installation j'ai installé PostgreSQL et les modules complémentaires.
Ensuite j'ai installé Apache2 et php par :
yt@D620 $ sudo apt-get install apache2 php5 php5-cli php-pear php5-xsl php5-curl php5-pgsql
Puis je fait le setup Apache et php, c'est OK.
Enfin je règle en CLI, Postgresql, et fait le setup des fichiers de conf.
ça marche, je peux me connecter à une base de test "yt_tests" par la commande :
yt@D620 $ psql -h <IPV4 or IPV6 du serveur> -U yt -d yt_tests
l'étape suivante est de faire la même chose en php.
là ça ne marche pas du tout, au niveau du butineur j'ai une erreur 500.
je finis par comprendre que dans mon installation de PostgreSQL j'ai deux binaires psql :
le premier :
/usr/bin/psql
symlink pointant vers :
lrwxrwxrwx 1 root root 37 mars 6 2012 /usr/bin/psql -> ../share/postgresql-common/pg_wrapper
le second :
/usr/lib/postgresql/9.1/bin/psql
et que lors de mes premiers essais, j'ai utilisé le premier (/usr/bin/psql).
je comprends alors pourquoi ça ne marche pas en php, enfin je l'intuite : php serait "linké" au second psql qui lui ne marche pas car quand je lance ce psql là j'ai :
yt@D620 $ sudo -s -u postgres
[sudo] password for yt:
avec le premier :
postgres@D620 $ /usr/bin/psql
psql (9.1.5)
Type "help" for help.
postgres=# \q
avec le second :
postgres@D620 $ /usr/lib/postgresql/9.1/bin/psql
psql: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
could not send startup packet: Relais brisé (pipe)
zsh: exit 2 /usr/lib/postgresql/9.1/bin/psql
bien sûr, si je poste c'est parce que je ne sais pas quoi faire, je ne comprends pas l'existence de ces deux psql, je suis abolument sûr ne pas avoir eu ces problèmes lors de la première installation de Xubuntu / Voyager 12.04.
Comme j'enregistre systématiquement toutes mes commandes d'installations dans un répertoire idoine (~/Installations) dans leur ordre chronologique, j'ai fait "la même chose" cette fois-ci.
Comment sortir de ce bazard ? càd comment faire en sorte que php voie le "bon" psql ?
Mais pourquoi donc supprimer les trous? En avez-vous réellement besoin?
Comme dit rjuju, dans 99% des cas, on laisse la séquence faire son travail (elle garantit l'unicité, pas l'absence de trous)
Si on a vraiment besoin de ne pas avoir de trous, on fait autrement (mais attention alors à bien gérer la concurrence, et ne pas oublier la possibilité d'un rollback)
Non, pas du tout si ce n'est que j'ai le sentiment que la séquence automatique a buggé au moins une fois justement en remplaçant un trou.
Pour quoi tu ne fais pas un VACUUM.
Ben, je viens de le faire :
$sql='VACUUM VERBOSE ANALYZE items;';
echo "$sql<br />";
$ret=$db->exec($sql);
if($ret){
while($row=$ret->fetch()){
print_r($row);
echo "<br />";
}
}
J'y ai même ajouté une réindexation :
$sql='REINDEX TABLE items;';
echo "$sql<br />";
$ret=$db->exec($sql);
if($ret){
while($row=$ret->fetch()){
print_r($row);
echo "<br />";
}
}
Résultat décevant : rien de neuf, j'ai toujours des trous, mon "rowid" passe de 26 à 40...
Bonne idée, je vais regarder ça !
Merci !
Disons que dans la liste des IDs il y avait un trou à 8.
Après une insertion psql avait occupé ce trou, du coup à l'insertion suivante donc ID à 9, il y avait collision d'ID car cet ID était occupé.
Donc j'ai fait un setval de la séquence au max(id) et ça roule.
Mais aussi j'utilisais la base -simultanément- par php, ou ruby ET en CLI (Command Line Interface).
Depuis j'ai nettoyé mon code SQL qui provenait d'une précédente adaptation à SQLite.
Oui, je suis tout à fait d'accord.
Si j'ai manipulé ma 'items_rowid_seq' c'est parce que j'ai cru (?) y voir un problème.
Maintenant, après quelques de dilétion / insertion, ça roule, même avec des trous dans le rowid.
Du coup, je ne pige pas pourquoi ça déconnait avant...
Peut-être parce que ma database était ouverte en CLI ?
j'ai une base 'items' où je supprime des lignes, ce qui crée des trous dans la succession de ma séquence rowid.
et je ne parviens pas à m'en dépatouiller.
pourtant, je sélection le max(rowid) et je l'attribue à ma séquence 'items_rowid_seq' si et seulement si last_value de items_rowid_seq est inférieur à max(rowid).
le code PHP :
$max_rowid=-1;
$sql="SELECT MAX(rowid) FROM items;";
$ret=$db->query($sql);
while($row=$ret->fetch()){
$max_rowid=$row['max'];
}
$last_value=-1;
$sql="SELECT last_value FROM items_rowid_seq;";
$ret=$db->query($sql);
while($row=$ret->fetch()){
$last_value=$row['last_value'];
}
if($last_value<$max_rowid){
$sql="SELECT setval('items_rowid_seq', max(rowid)) FROM items;";
$ret=$db->query($sql);
while($row=$ret->fetch()){
$last_value=$row['setval'];
}
if($last_value<$max_rowid){
// générer une erreur
}
}
$rowid=-1;
$sql="INSERT INTO items (ctime, [...], infos) VALUES (
'".$dat."', '".$dat."', [...]', '".str2sql(quoteAsAre($_GET["infos"]))."') RETURNING rowid;";
$ret=$db->query($sql);
while($row=$ret->fetch()){
$rowid=$row['rowid'];
}
Pour PHP, c'est $ret qui n'est pas un objet, je ne peux donc faire $ret->fetch().
Une idée pour me dépatouiller ?
NB : rowid est de type :
CREATE TABLE items (rowid SERIAL PRIMARY KEY, ...
Si le serveur PostgreSQL n'est destiné à servir que des clients qui sont sur le réseau local privé (192.168.0.0)
l'ouverture du port sur la Freebox et la redirection d'adresses ne sont non seulement pas nécessaires mais
inutilement risqués.
non, ce n'est pas le cas, les clients sont sur des portables en vadrouille...
Çà roule )))
$ psql -h 192.168.0.10 -U yt -d landp_public
Password for user yt:
psql (9.1.3)
Type "help" for help.
landp_public=> select * from categories;
rowid | idx | name | ctime | mtime
-------+-----+-----------------------+------------------------+------------------------
1 | 0 | Formulaires | 2012-04-03 09:21:25+02 | 2012-04-03 09:21:25+02
2 | 1 | Groupes de discussion | 2012-04-03 09:21:25+02 | 2012-04-03 09:21:25+02
3 | 2 | Comptes EMail | 2012-04-03 09:21:25+02 | 2012-04-03 09:21:25+02
4 | 3 | Clés de logiciels | 2012-04-03 09:21:25+02 | 2012-04-03 09:21:25+02
5 | 4 | Banque en ligne | 2012-04-03 09:21:25+02 | 2012-04-03 09:21:25+02
6 | 5 | Cartes de paiement | 2012-04-03 09:21:25+02 | 2012-04-03 09:21:25+02
7 | 6 | Essai add item | 2012-04-03 09:39:04+02 | 2012-04-03 09:39:04+02
(7 rows)
landp_public=> \q
avec la ligne :
host all yt 192.168.0.20/32 password
Merci à tous pour votre aide préciseuse !
unbewusst a écrit :J
donc, la ligne :host all yt 192.168.0.20 md5
est incorrecte ?
oui faut mettre 192.168.0.20/32
dans les logs de start vous avez surement la ligne qui vous dis que le pg-hba est erroné.
oui, merci bien, il faut que je prenne l'habitude de lire les logs :
$ sudo cat /Library/PostgreSQL/9.1/data/pg_log/postgresql-2012-04-04_164956.log
2012-04-04 16:49:56 CEST LOG: invalid IP mask "md5": nodename nor servname provided, or not known
2012-04-04 16:49:56 CEST CONTEXT: line 95 of configuration file "/Library/PostgreSQL/9.1/data/pg_hba.conf"
2012-04-04 16:49:56 CEST FATAL: could not load pg_hba.conf
edlm a écrit :L'IPV6 où se trouvent les bases étant fixe (freebox).
Le DNAT est il bien en place ? Port ouvert sur la freebox et redirigé sur le port qui est à l'écoute sur le serveur PostgreSQL ?
Ah purée, qu'elle andouille je fais, je n'ai pas redirigé 5432 sur 198.162.0.10
damned !
Bon, ça se complique un peu, j'ai deux serveurs psql l'un en 198.162.0.10 sous Mac OS X et un autre en 198.162.0.20 sous Xubuntu.
Il faudra que je change de port sur l'un des côtés.
Bon, j'ai fait la manip sur la FB, j'ai vérifié que le port 5432 est bien ouvert et là j'ai:
$ psql -h 192.168.0.10 -U yt -d landp_public
psql: FATAL: no pg_hba.conf entry for host "192.168.0.20", user "yt", database "landp_public", SSL off
il me faut trouver la syntaxe correcte pour permettre une connection avec password sur 192.168.0.20...