Accès et écriture simultanée d'un fichier texte

WRInaute occasionnel
Bonjour,

J'ai une question concernant l'écriture sur un fichier texte. Imaginons que je stocke des informations dans un fichier texte pour ne pas avoir à faire un nombre impressionnant d'appels à la base de données. Le fichier peut-être modifier par un script php suite à une action de l'utilisateur. Si deux utilisateurs effectuent une action qui modifie le fichier au même moment T, que va-t-il se passer?

D'après vous, est-ce une solution viable pour un site avec beaucoup d'utilisateurs? Quelles peuvent être les solutions alternatives si ce n'est pas viable?

Merci pour vos réponses.
 
WRInaute impliqué
si tu veux autoriser des accès concurents c'est possible mais il faudra que tu gères toi même la concurence en utilisant par exemple flock. Ensuite qui dit vérouillage dit process en attente donc faut voir par rapport à une base de données qui gère cela forcément mieux
 
WRInaute impliqué
Théoriquement c'est le système d'exploitation qui gère celà. Quand un fichier est ouvert en écriture, il est bloqué et personne d'autre ne peut l'ouvrir en écriture (mise en file d'attente).
 
WRInaute accro
FloBaoti a dit:
Théoriquement c'est le système d'exploitation qui gère celà. Quand un fichier est ouvert en écriture, il est bloqué et personne d'autre ne peut l'ouvrir en écriture (mise en file d'attente).

Ah bon? Ben tiens. Va falloir nous dire quel OS, et quelle doc dit ça... Sur la plupart des OS que je connais, rien n'empêche plusieurs process d'ouvrir le même fichier en lecture ou en écriture en même temps et faire tout plein de trucs dedans en même temps.

D'ailleurs dans certains cas, ça ne pose aucun problème: si tous les processus sont en "append" sur un fichier, et qu'ils écrivent tous de façon "atomique" les éléments qui ne doivent pas être "mélangés", ça marche très bien (ce qui est quand même très pratique pour les logs et autres choses du genre).

Mais à partir du moment où tu fais des accès aléatoires, il te faut mettre en place du locking toi même, que ce soit avec flock, les appels fcntl qui vont bien, les options O_SHLOCK/O_EXLOCK de open, ou d'autres méthodes.

Ceci étant dit, pour répondre au posteur original, c'est justement tout là l'intérêt d'utiliser une base de données (décente) qui va gérer le locking à ta place aussi finement que possible (locker l'ensemble du fichier à chaque accès ça limite beaucoup les accès concurrents, sur un serveur web ça peut vite devenir assez embêtant), en plus de te permettre de faire des requêtes plus ou moins complexes, de tirer parti d'index, etc.

La question serait donc plutôt: pourquoi vouloir se passer de la base de données pour ça?

Jacques.
 
Nouveau WRInaute
je géré un systeme d'environ 700 000 pages par jours avec plusieurs serveur en load balancing.

Les logs sont enregistré sur chaque machine de cette facon, et cela fonctionne beaucoup plus vite que par un DB (serveur dual core 4 Gb...). C'est le systeme d'exploitation (fedora) qui gere les écritures.

Par contre a chaque fois je n'ajoute qu'une seule ligne au fichier (avec des infos genre date;referrer;...)
 
WRInaute impliqué
j'ai déjà vu dans un php_error.log deux notices s'imbriquées..., le système gère la concurence matérielle pour pas que deux process écrivent simultanément au même endroit, mais pour la cohérence logiciel c'est bien au développeur de locker comme il le faudrait
 
WRInaute accro
julienr a dit:
j'ai déjà vu dans un php_error.log deux notices s'imbriquées..., le système gère la concurence matérielle pour pas que deux process écrivent simultanément au même endroit, mais pour la cohérence logiciel c'est bien au développeur de locker comme il le faudrait

Comme je le disais, ça marche très bien sans locks pour les logs à condition d'écrire de façon atomique (i.e. avec un seul appel système "write").

Suivant le language utilisé et les empilements divers de librairies c'est plus ou moins évident, mais en général si on s'assure qu'une notice soit écrite en un seul appel ça marche très bien (i.e. on concatène tous les bouts en mémoire, et on écrit tout d'un coup, plutôt que de faire une série de "print" ou autre choses du genre).

Par exemple:

Code:
print STDERR localtime();
print STDERR " $$ ";
print STDERR $erreur;
print STDERR "\n";
Ca ne marchera pas comme il faut. Par contre:

Code:
print STDERR localtime()." $$ $erreur\n";
Ca marche très bien.

Evidemment je parle de FS locaux, quand on commence à faire du NFS et autres joyeusetés du genre tout ça devient nettement moins certain...

Jacques.
 
Discussions similaires
N
Réponses
3
Affichages
2K
ninonsclcme
N
Haut