Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Push Meldungen
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
 
 
 

PHP fsync(): Daten wirklich auf die Festplatte schreiben

Sie befinden sich: Home > Php Tutorial > PHP fsync(): Daten wirklich...

PHP fsync(): Daten wirklich auf die Festplatte schreiben
Veröffentlicht am:
20.09.2026
Hits / Besucher:
7
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Ein Importlauf verarbeitet zwanzigtausend Datensätze und meldet am Ende Erfolg. Zwei Minuten später fällt der Strom aus. Nach dem Neustart fehlen die letzten dreihundert Zeilen, obwohl jeder Schreibaufruf einen gültigen Wert zurückgegeben hatte.

Illustration zum Tutorial: PHP fsync(): Daten wirklich auf die Festplatte schreiben

Im Bild liegen zwischen der Anwendung und der Platte zwei Zwischenspeicher. Wer nur schreibt, gibt die Daten am ersten ab und weiß nicht, wie weit sie kommen.

Was PHP fsync() macht

PHP fsync() verlangt vom Betriebssystem, alle für eine geöffnete Datei zwischengespeicherten Daten auf das Speichergerät zu schreiben. Der Aufruf kehrt erst zurück, wenn das Betriebssystem diesen Vorgang bestätigt. Genau darin liegt der Unterschied zu einem gewöhnlichen Schreibaufruf, der sofort weiterläuft.

<?php

$handle = fopen('/var/daten/buchungen.log', 'ab');

fwrite($handle, "4711;120,50;2026-09-20\n");

if (!fsync($handle)) {
error_log('Synchronisierung fehlgeschlagen');
}

fclose($handle);

Der Rückgabewert ist wahr oder falsch und gehört geprüft. Schlägt der Aufruf fehl, liegen die Daten weiterhin nur im Zwischenspeicher, und die Anwendung sollte das keinesfalls als erfolgreichen Abschluss melden.

Die Signatur im Original

Die englische Beschreibung macht in einem Satz klar, worin sich die Funktion von ihren Verwandten unterscheidet:

fsync(resource $stream): bool


/* stream - an open file pointer, as returned by fopen()
return value - true on success or false on failure

The function synchronizes changes to the file, including its
meta-data, with the storage device. It asks the operating system
to flush all buffered modifications of the open file descriptor
to the disk. Unlike fflush() it does not stop at the operating
system, it waits until the write has been acknowledged. */

Der letzte Halbsatz ist der ganze Punkt. Ein gewöhnliches Leeren des Puffers reicht die Daten weiter, PHP fsync() wartet auf die Bestätigung.

Der Weg der Daten: zwei Puffer bis zur Platte

Zwischen einem Schreibaufruf im PHP-Skript und der physischen Speicherung liegen zwei Zwischenstationen. PHP hält einen eigenen Puffer, damit nicht jeder kleine Schreibvorgang das Betriebssystem bemüht. Das Betriebssystem hält einen zweiten, damit die Platte nicht bei jeder Änderung anlaufen muss.

flowchart TD
    A[PHP-Skript] -->|fwrite| B
    B[Puffer in PHP] -->|fflush| C
    C[Puffer im Betriebssystem] -->|fsync| D
    D[Speichergeraet]
    C -->|irgendwann von selbst| D

Der untere Pfeil ist der Normalfall. Das Betriebssystem schreibt seinen Puffer nach eigenem Ermessen weg, meist innerhalb weniger Sekunden. Bei einem Absturz in diesem Zeitfenster sind die Daten verloren, und genau dieses Fenster schließt PHP fsync().

fflush(), fsync() und fdatasync() im Vergleich

Drei Funktionen mit ähnlichen Namen, die an drei verschiedenen Stellen ansetzen. Die Verwechslung von fflush() und PHP fsync() ist der häufigste Irrtum in diesem Umfeld.

Funktion Bringt die Daten bis Metadaten Kosten
fflush() zum Betriebssystem nein sehr gering
fdatasync() auf das Gerät nur wenn nötig hoch
fsync() auf das Gerät ja hoch
<?php

/* fflush leert nur den Puffer von PHP. Danach liegt alles
im Betriebssystem und ist bei einem Absturz weiterhin weg. */
fflush($handle);

/* fdatasync schreibt die Nutzdaten auf das Geraet, laesst
aber Metadaten wie die Aenderungszeit aussen vor. */
fdatasync($handle);

/* fsync schreibt Nutzdaten und Metadaten. */
fsync($handle);

Wenn eine Datei ihre Größe behält und nur der Inhalt an bekannten Stellen geändert wird, genügt fdatasync() und spart einen Schreibvorgang. In allen anderen Fällen, besonders beim Anhängen, ist PHP fsync() die richtige Wahl, weil die neue Dateigröße selbst ein Metadatum ist.

Das sichere Speichermuster

Eine synchronisierte Datei kann trotzdem halb geschrieben sein, wenn der Absturz mitten im Schreiben passiert. Der Ausweg ist, gar nicht erst in die Zieldatei zu schreiben. Stattdessen entsteht eine temporäre Datei im selben Verzeichnis, die erst nach der Synchronisierung an ihren Platz rückt.

<?php

function sicherSpeichern(string $ziel, string $inhalt): bool
{
$temp = $ziel . '.tmp' . getmypid();
$handle = fopen($temp, 'wb');

if ($handle === false) {
return false;
}

fwrite($handle, $inhalt);
fsync($handle); /* jetzt liegt der Inhalt sicher */
fclose($handle);

return rename($temp, $ziel); /* atomar im selben Dateisystem */
}

Das Umbenennen innerhalb desselben Dateisystems ist unteilbar. Es gibt keinen Moment, in dem die Zieldatei halb alt und halb neu ist: Entweder zeigt der Verzeichniseintrag auf die alte Fassung oder auf die vollständige neue. Wer parallel schreibende Prozesse hat, kombiniert das mit PHP flock() für Dateisperren beim parallelen Schreiben.

Was PHP fsync() kostet

Der Aufruf wartet auf die Hardware, und das dauert. Je nach Gerät und Dateisystem liegt eine einzelne Synchronisierung im Bereich von wenigen Millisekunden. Das klingt harmlos, summiert sich aber sofort: Bei zwanzigtausend Datensätzen und je einem Aufruf pro Satz wird aus einem Importlauf von zwei Sekunden einer von mehreren Minuten.

<?php

$zaehler = 0;

foreach ($datensaetze as $satz) {
fwrite($handle, $satz . "\n");

/* Nicht nach jeder Zeile, sondern in Bloecken.
Im schlimmsten Fall gehen 500 Zeilen verloren,
dafuer bleibt der Lauf brauchbar schnell. */
if (++$zaehler % 500 === 0) {
fsync($handle);
}
}

fsync($handle);

Die Blockgröße ist eine bewusste Abwägung zwischen Geschwindigkeit und der Menge, die im Ernstfall verloren geht. Fachlich getrieben wird sie von der Frage, wie viel Nacharbeit ein Verlust bedeutet. Bei Buchungen ist die Antwort meist eine andere als bei Messwerten.

Das Verzeichnis nicht vergessen

Eine neu angelegte Datei besteht aus zwei Teilen: dem Inhalt und dem Eintrag im Verzeichnis. PHP fsync() sichert den Inhalt. Der Verzeichniseintrag gehört aber zum Verzeichnis, und das ist unter Unix ebenfalls eine Datei.

<?php

/* Nur unter Unix. Windows laesst ein Verzeichnis
nicht als Datei oeffnen und meldet einen Fehler. */
if (DIRECTORY_SEPARATOR === '/') {
$verzeichnis = fopen(dirname($ziel), 'r');

if ($verzeichnis !== false) {
fsync($verzeichnis);
fclose($verzeichnis);
}
}

In der Praxis fällt dieser Schritt selten auf, weil die meisten Dateisysteme Verzeichnisänderungen ohnehin zügig festschreiben. Wer eine lückenlose Zusage braucht, kommt aber nicht darum herum.

Verfügbarkeit: erst ab PHP 8.1

Die Funktion kam mit PHP 8.1 dazu, zusammen mit fdatasync(). Auf älteren Umgebungen führt der Aufruf zu einem schwerwiegenden Fehler, weshalb auf gemeinsam genutzten Servern eine Prüfung sinnvoll ist.

<?php

if (function_exists('fsync')) {
fsync($handle);
} else {
fflush($handle); /* schwaechere Zusage, aber besser als nichts */
}

Dass die Funktion so spät kam, hat nichts mit fehlendem Bedarf zu tun. Datenbanken und Protokolldienste haben denselben Systemaufruf immer schon genutzt, PHP hatte ihn nur nie zugänglich gemacht. Wer Dateien schreibt, findet die passenden Grundlagen in PHP file_put_contents zum Schreiben, Anhängen und Sichern von Dateien.

Wo die Zusage endet

Ein Punkt gehört zur Ehrlichkeit dazu: PHP fsync() gibt die Bestätigung des Betriebssystems weiter, und diese ist nur so verlässlich wie die Ebene darunter. Festplatten und SSDs haben einen eigenen Schreibcache und melden den Vorgang gelegentlich als abgeschlossen, bevor die Daten dauerhaft liegen.

Bei Netzlaufwerken gilt die Zusage des Protokolls, nicht die einer Platte. Und in virtuellen Umgebungen hängt das Ergebnis davon ab, wie der Wirt seine Speicherschicht konfiguriert hat. Für die allermeisten Anwendungen ist das ohne Belang, für eine Nachweispflicht dagegen ein Punkt, den man mit dem Betrieb klären sollte.

Fazit

Ein erfolgreicher Schreibaufruf sagt aus, dass PHP die Daten übergeben hat. Wo sie in diesem Moment liegen, sagt er nicht. PHP fsync() schließt diese Lücke, indem es auf die Bestätigung des Betriebssystems wartet, und fflush() tut das ausdrücklich nicht.

Praktisch bleiben drei Dinge hängen. Das Muster aus temporärer Datei, Synchronisierung und Umbenennen macht halb geschriebene Dateien unmöglich. Gesynct wird in Blöcken, nicht nach jedem Datensatz, sonst wird der Lauf unbrauchbar langsam. Und die Funktion gibt es erst ab PHP 8.1, was auf gemeinsam genutzten Servern eine Prüfung wert ist.

 


 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.