Par bastien le 06/11/2005 - 03:18
Bonjour,
Je lance une bouteille à la mer sur ce forumn au cas ou une âme charitable pourait me venir en aide :)
J'éxplique mon problème:
J'utilise proffesionellement Postgresql depuis plusieurs années avec succsès pour des bases de plusieur dizaines de giga.
Sur la derniere plateforme que je met en place la majorité des données sont stockées sur un SAN (en l'occurence l'implémentation Apple de StorNext, XSsan). Tous les fichiers de la base sont stockés sur ce SAN, la base est gégée par un des noeuds du SAN (un XServe sous OSX 10.4.3).
La version de postgres est une 8.0.4.
Jusque là , pas de pb...
L'initdb se passe bien,
le createdb se passe bien,
les inserts se passent bien
Le démarage et l'arret u postmaster se passent aussi très bien.
Mais alors que-ce qui va pas ?
Et bien lorsque la base est stopée, que tous les fichiers sont fermés (j'insiste, j'ai vérifié avec fs_usage, un genre de trace kernel sur les IOs) : Si je démonte le volume SAN du noeud en question, puis que je le remonte, les fichiers xlog sont CORRMPUES !!!
Au pire (en utilisant le fsync() de base comme méthode de synchronisation WAL, la base ne redémarre plus, il faut faire un pg_restxlog,
Au mieux (en utilisant open_fsync()), la base redémare mais les dernières transactions on disparue!!!!
J'ai tenté de faire un 'sync' à la main avant le démontage du volume SAN mais rien n'y fait.....
Pour illustrer :
meta1:~ postgres1$ ./start.sh
meta1:~ postgres1$ ps x
PID TT STAT TIME COMMAND
1846 ?? Ss 0:04.92 update
3918 p0 S 0:00.10 -su
4383 p0 S 0:00.20 /opt/local/lib/pgsql8/bin/postmaster -D /Volumes/SAN1/ged1/sgbd1/pos
4385 p0 S 0:00.00 postgres: writer process
4386 p0 S 0:00.00 postgres: stats buffer process
4387 p0 S 0:00.00 postgres: stats collector process
4118 p1 S 0:00.02 -su
4123 p1 S+ 0:00.25 tail -f postgres1.log
meta1:~ postgres1$ psql xxxx
Welcome to psql 8.0.4, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
atlas=# select * from utilisateur ;
nom | hash_password
-------+---------------
test | test
test2 | test
test3 | test
(3 rows)
atlas=# insert into utilisateur(nom, hash_password) values ('test4','test'); <---- On insere une ligne
INSERT 17307 1
atlas=# commit;
WARNING: there is no transaction in progress
COMMIT
atlas=# select * from utilisateur ;
nom | hash_password
-------+---------------
test | test
test2 | test
test3 | test
test4 | test <---- La nouvelle ligne apparait bien
(4 rows)
atlas=# \q
meta1:~ postgres1$ ./stop.sh <---- On arrete la base
waiting for postmaster to shut down.... done
postmaster stopped
meta1:~ postgres1$ ./start.sh <---- On la redemarre sans avoir demonté le volume
meta1:~ postgres1$ ps x
PID TT STAT TIME COMMAND
1846 ?? Ss 0:04.96 update
3918 p0 S 0:00.11 -su
4413 p0 S 0:00.20 /opt/local/lib/pgsql8/bin/postmaster -D /Volumes/SAN1/ged1/sgbd1/pos
4415 p0 S 0:00.00 postgres: writer process
4416 p0 S 0:00.00 postgres: stats buffer process
4417 p0 S 0:00.00 postgres: stats collector process
4118 p1 S 0:00.02 -su
4123 p1 S+ 0:00.27 tail -f postgres1.log
meta1:~ postgres1$ psql atlas
Welcome to psql 8.0.4, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
atlas=# select * from utilisateur ;
nom | hash_password
-------+---------------
test | test
test2 | test
test3 | test
test4 | test <---- Tous va bien la ligne est bien là .
(4 rows)
atlas=# \q
meta1:~ postgres1$ ./stop.sh <---- On arrette à nouveau la base
waiting for postmaster to shut down.... done
postmaster stopped
meta1:~ postgres1$ md5 data/pg_xlog/000000010000000000000000 <---- On fait une photo du fichier de transaction.
MD5 (data/pg_xlog/000000010000000000000000) = 6bfd49780b71eb5820f3bc7fa507ef80
meta1:~ root# mount
/dev/disk0s3 on / (local, journaled)
devfs on /dev (local)
fdesc on /dev (union)
on /.vol
automount -nsl [227] on /Network (automounted)
automount -fstab [236] on /automount/Servers (automounted)
automount -static [236] on /automount/static (automounted)
/dev/disk3 on /Volumes/SAN1 (local) <---- On vas démonter le volume sur lequel ce trouve la base.
meta1:~ root# mount
/dev/disk0s3 on / (local, journaled)
devfs on /dev (local)
fdesc on /dev (union)
on /.vol
automount -nsl [227] on /Network (automounted)
automount -fstab [236] on /automount/Servers (automounted)
automount -static [236] on /automount/static (automounted) <---- Le volume est bien démonté, on le remonte
meta1:~ root# mount
/dev/disk0s3 on / (local, journaled)
devfs on /dev (local)
fdesc on /dev (union)
on /.vol
automount -nsl [227] on /Network (automounted)
automount -fstab [236] on /automount/Servers (automounted)
automount -static [236] on /automount/static (automounted)
/dev/disk3 on /Volumes/SAN1 (local) <---- Le volume est bien remonté.
meta1:~ postgres1$ md5 data/pg_xlog/000000010000000000000000
MD5 (data/pg_xlog/000000010000000000000000) = d744c013a939a247bf23723ff90f1a13 <---- Bouum! le fichier a changé!
meta1:~ postgres1$ ./start.sh <---- On redemare la base.
meta1:~ postgres1$ psql atlas
Welcome to psql 8.0.4, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
atlas=# select * from utilisateur ; <----- Et la, c'est le drame....
nom | hash_password
-----+---------------
(0 rows)
atlas=#
Si quelqu'un a déjà rencontré le problème ou a une idée je suis preneur....
J'ai commencé à jeter un oueil dans le source de postgres 8.0.4 ( dans xlog.c ) la gestion des synchros disques, il semble qu'apple préconise l'appel de la fonction fcntl(F_FULLFSYNC) à la place de fsync() pour s'afranchir des éventuels problème de caches résidants, ce n'est pas imémenté dans postgres mais c'est peut être une piste....
A l'aiiiiiiiiiiiiiiiiiide !!!!
Bastien.