» include(), MySQL-Cache und Race Conditions

Eine Datei mit zufälligem Inhalt generierenNeuen Thread eröffnenNeue Antwort erstellenflock() Alternative mkdir() optimiert
AutorNachricht
Administrator 

Name: Marc
Geschlecht:
Anmeldedatum: 28.08.2004
Beiträge: 52420
Wohnort: Lohmar


Meine eBay-Auktionen:
07.09.2014, 12:56
zitieren

Manche nutzen include() um MySQL Caches einzubinden. D.h. erst werden die Daten mit SELECT aus der MySQL Datenbank ausgelesen, mit var_export() aufbereitet und dann in eine Datei geschrieben. Diese kann man dann sehr performant per include() einlesen.

Allerdings hat man hier ein Problem und das nennt sich Race Conditions. Und das ist ganz einfach zu erklären. Der erste Besucher einer Seite führt das PHP Script aus, das die Cache-Datei erstellt, doch während dieses Script noch ausgeführt wird, kommt ein zweiter Besucher und bindet die noch nicht fertige Cache-Datei mit include() ein. Ein file_exists() hat nicht geholfen, denn die Datei existiert ja, nur eben noch nicht vollständig.

Das kann man ganz einfach selber testen:
<?php
error_reporting(E_ALL);
function mkfile($filename, $data='', $chmod=0644) {
$h = fopen($filename, 'w');
fwrite($h, $data);
fclose($h);
umask(0000);
chmod($filename, $chmod);
return $data;
}
$mysql_cache = '<?php $foo = 1; ?' . '>';
$strlen = strlen($mysql_cache);
for ($i = 0; $i < $strlen; $i++) {
// we write our cache file char by char because in a
// live environment it is possible that a second
// request tries to include a partial file as the first
// process isn't finished writing the file
$filename = 'cache3/' . $i . '.php';
if (file_exists($filename)) {
unlink($filename);
usleep(500000);
}
mkfile($filename, substr($mysql_cache, 0, $i));
usleep(500000);
include($filename);
}
echo "Done";
?>

Das Skript stoppt, sobald die eingebundene Datei erst die Zeichenkette "<?p" enthält und erreicht niemals das echo:
    <<br />
    <b>Parse error</b>:  syntax error, unexpected end of file in <b>/usr/www/users/maxrep/cache3/3.php</b> on line <b>1</b><br />

@-operator
Mit @include() könnte man die Fehlermeldungen unterdrücken, aber das Skript stoppt trotzdem an dieser Stelle.

try/catch
Mit try/catch kann man leider keine Parsing Fehler einfangen. Also auch das geht nicht.

flock
Funktioniert auch nicht. Denn es kommt zu Timeouts. Hier habe ich das Problem beschrieben und auch einen Lösungsansatz genannt:
http://www.programmierer-forum.de/flock-alternative-mkdir-optimiert-t225288.htm

Lösung
Die einzige mir bekannte Lösung ist das zuvor genannte mkdir()-Konstrukt als flock-Alternative beim Schreiben und serialize() beim Lesen.

Beim Schreiben sichert mkdir(), dass der Vorgang halbwegs atomar ist (nicht 100% atomar, daher nicht für jeden Einsatzzweck geeignet).

Die Datei enthält in dem Fall nur den serialisierten Datensatz und selbst wenn sie beim Einlesen gerade geschrieben wird, bekommt man keine Probleme:
<?php
// file was written completely
var_dump(unserialize('i:1;'));
// file partially written
var_dump(unserialize('i:1'));
var_dump(unserialize('i:'));
var_dump(unserialize('i'));
var_dump(unserialize(''));
?>

Ergebnis:
int(1)
bool(false)
bool(false)
bool(false)
bool(false)


pn email
Gast 
07.09.2014, 12:56
zitieren

Mach mit!

Wenn Dir die Beiträge zum Thread "include(), MySQL-Cache und Race Conditions" gefallen haben oder Du noch Fragen hast oder Ergänzungen machen möchtest, solltest Du Dich gleich bei uns anmelden:



Registrierte Mitglieder genießen die folgenden Vorteile:
✔ kostenlose Mitgliedschaft
keine Werbung
✔ direkter Austausch mit Gleichgesinnten
✔ neue Fragen stellen oder Diskussionen starten
✔ schnelle Hilfe bei Problemen
✔ Bilder und Videos hochladen
✔ und vieles mehr...


Neuen Thread eröffnenNeue Antwort erstellen
Ähnliche BeiträgeRe:
Letzter Beitrag
Benchmark: mysql, mysqli - Buffer, Cache und Prepared Stmt
Hallo, ich habe mir mal die Mühe gemacht und die verschiedensten Varianten, wie man eine Abfrage gestalten könnte, in einen Benchmark gepackt und ausgewertet. Hier erstmal die umfangreichen Logs: /* // vars $id = 1111; $email =...
[PHP]von mgutt
1
1.071
09.10.2009, 22:59
mgutt
HTML-Seite in Cache schreiben um MySQL-Abfragen zu sparen
Das geht ganz einfach. Hier ein Beispiel: <?php // ab hier html kopf, menü, usw., eben alles was nicht in den cache soll, weil es sich z.b. ändert, wenn sich jemand einloggt ?> <html> <head> </head> <body> <div...
[PHP]von mgutt
1
514
26.02.2012, 11:33
mgutt
[Hilfe] Tipp: Thumbnails und Seiten-Cache zurücksetzen
Methode 1 - Kommandozeile Laut der Seite soll es ab MW 1.21 mit"php pureList.php --all" gehen: https://www.mediawiki.org/wiki/Manual:PurgeList.php Es wurde bei mir zwar "Done!" angezeigt, aber es wurde bei mir kein Cache...
von mgutt
0
92
30.01.2015, 23:24
mgutt
scuid - HTTP, HTTPS & FTP Proxy Cache Script
Link:...
von mgutt
0
2.220
28.11.2007, 00:59
mgutt
Web-/Softwareentwickler (PHP/MySQL, w/m)
Sie haben praktische Erfahrungen im Webdevelopment, Interesse am eMarketing und scheuen sich nicht davor, sich sowohl in einem Team als auch im internationalen Kundenkontakt einzubringen? Dann sollten wir uns kennen lernen! Die Insecon eMarketing GmbH...
[Jobs & Stellenangebote]von Britta75
0
507
03.11.2011, 10:03
Britta75
PHP/MySQL-Entwickler (m/w) in München
PHP/MySQL-Entwickler (m/w) Wir, die social sweethearts, sind der Online Publisher der nächsten Generation: Als global führender Anbieter von viralen Webseiten, Content-Projekten und mobilen Apps, Videos und Facebook Applikationen veröffentlichen wir...
[Jobs & Stellenangebote]von social sweethearts
0
254
01.04.2016, 08:12
social sweethearts
 Toad for MySQL Freeware
Version 7.3 Ganz nett um zwei MySQL Datenbanken miteinander zu...
[Allgemein]von TaMyD
0
0
28.01.2015, 13:22
TaMyD
Datenbankadministrator (m/w) MySQL in Münster
Sie lieben Dynamik, sind begeisterungsfähig und haben Lust unser Unternehmen aktiv mitzugestalten? Wir suchen die besten Talente! Bewerben Sie sich als: Datenbankadministrator (m/w) MySQL mit mehrjähriger Berufserfahrung Als Datenbankadministrator sind...
[Jobs & Stellenangebote]von kimjob
0
237
25.02.2013, 15:27
kimjob
Suche PHP/MySQL Programmierer
Guten Tag, Wir ich möchte mich und meine Leute mal vorstellen. Wir sind eine Spiele gemeinschaft und machen dies aus Jucks. Doch wir möchten etwas größeres aufbauen in der Egoshooter welt. Darum Planen wir eine "Liga" zu gründen. Mometane...
[Projekte]von backtrack
0
322
08.12.2013, 21:47
backtrack
 UTF-8 in ISO-8859-1 konvertieren - MySQL Datenbank
Manche kennen das sicher. Man importiert eine Datenbank und vergisst den Zeichensatz oder die Daten sind aus anderen Gründen in UTF-8 umgewandelt worden. Genau hier greift dieses Script. Es werden die meisten UTF8-Zeichen in ISO konvertiert. Es müssen...
[PHP]von mgutt
0
10.165
30.05.2008, 22:48
mgutt
© 2004 - 2024 www.programmierer-forum.de | Communities | Impressum |