Frage

Lassen Sie uns sagen Sie bauen ein Journaling / Write-Ahead-Logging-Speichersystem. Können Sie dies einfach implementieren, indem (für jede Transaktion), um die Daten angehängt werden (mit write (2)), das Anhängen einer Markierung verpflichten, und dann fsync-ing?

Das Szenario zu berücksichtigen ist, wenn Sie eine große Menge von schreibt in dieses Protokoll dann tun fsync es, und es gibt einen Ausfall im fsync . Sind die Inode direkt / indirekt Blockzeiger erst, nachdem alle Datenblöcke gespült gespült, oder gibt es keine Garantien, dass Blöcke, um gespült werden? Wenn letzteres, dann während der Wiederherstellung, wenn Sie eine Commit Markierung am Ende der Datei angezeigt wird, können Sie nicht darauf vertrauen, dass die Daten zwischen ihm und den vorherigen begehen Marker sinnvoll ist. So müssen Sie sich auf einem anderen Mechanismus beruhen (zumindest eine weitere fsync Beteiligung), um zu bestimmen, inwieweit der Protokolldatei ist konsistent (zum Beispiel Schreib- / fsyncing die Daten, dann schreiben / fsyncing der Commit-Marker).

Wenn es einen Unterschied macht, vor allem Gedanken über ext3 / ext4 als Kontext.

War es hilfreich?

Lösung

Beachten Sie, dass Linux und Mac OS ist fsync und fdatasync standardmäßig nicht korrekt sind. Windows ist richtig standardmäßig, aber kann Linux emulieren für Benchmarking-Zwecke.

Auch fdatasync Probleme mehrere Datenträger schreibt, wenn Sie an das Ende einer Datei anzuhängen, da es die Datei Inode mit der neuen Länge aktualisieren muss. Wenn Sie einen Schreib haben pro verpflichten wollen, ist Ihre beste Wette ist, um Log-Speicherplatz vorbelegt, speichern Sie eine CRC der Log-Einträge in der Marker begehen, und eine einzelne fdatasync Ausgabe () bei begehen. Auf diese Weise, egal wie viel die OS / Hardware-Neuordnungs hinter Ihrem Rücken, können Sie einen Präfix des Protokolls finden, dass Datenträger tatsächlich treffen.

Wenn Sie das Protokoll für eine dauerhafte Commits oder Schreib voraus verwenden möchten, werden die Dinge schwieriger, da Sie brauchen, um sicherzustellen, dass fsync tatsächlich funktioniert. Unter Linux, sollten Sie die Disk Write Cache mit hdparm deaktivieren oder die Partition mit Barriere-Set auf true montieren. [Edit: Ich stehe korrigiert, Barriere scheint nicht die richtige Semantik zu geben. SATA und SCSI führen eine Anzahl von Grundelementen, wie zum Beispiel Schreibsperre und Native Command Queuing, dass es für Betriebssysteme möglich machen Primitiven zu exportieren, die Wal-Prinzip ermöglichen. Von dem, was ich von manpages sagen kann und online, Linux macht nur diese Entwickler des Dateisystems, nicht zu User-Space.]

Paradoxerweise Deaktivieren der Plattenschreibcache manchmal führt zu einer besseren Leistung, da Sie mehr Kontrolle über Schreibplanung im Benutzerraum erhalten; Wenn die Festplatte Warteschlangen ein Bündel von synchronen Schreibanforderungen, erhalten Sie seltsame Latenzspitzen an die Anwendung auszusetzen oben. Deaktivieren des Schreib-Cache verhindert, dass dies geschieht.

Schließlich reale Systeme verwenden Gruppe verpflichten, und tun <1 sync Schreib pro mit Parallel-Workloads begehen.

Andere Tipps

Es gibt keine Garantie auf die Reihenfolge, in der Blöcke auf die Platte geschrieben werden. In diesen Tagen auch den Antrieb selbst kann wieder um Blöcke auf ihrem Weg zu den Platten.

Wenn Sie Bestellung erzwingen möchten, müssen Sie mindestens fdatasync() zwischen den schreibt, dass Sie bestellt werden sollen. Alle ein Sync-Versprechen ist, dass wenn er zurückkehrt , alles vor dem sync geschrieben hat getroffen Speicher.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top