Strategie: Speichervorgang gegen unvollständiges Speichern absichern?

-horn-

Bekanntes Mitglied
moien,

ich baue gerade checkpoints in mein programm ein, von dem aus weiter gerechnet werden kann, falls das programm mal abschmiert. so wären nicht alle berechneten daten weg und man müsste das nochmal neu machen.

aber ich würde gerne eine vernünftige strategie erfahren, falls die speicherung während des vorgangs abbricht und unvollständig speichert. das wäre dann ja doof und man müsste trotzdem von vorne anfangen UND man müsste dem programm noch beibringen vollständiges von nichtvollständigen daten zu verstehen.

wie würdet ihr das machen? immernoch eine vorherige speicherung mitschleppen und speichern und dann das neue? so hätte man zur sicherung immernoch 2 dateien und wenn die erste kaputt geht, dann sollte die vorherige ja noch gehen, weil der abbruch beim erstellen der letzteren geschah.

ideen?

grüße,

Andreas
 
G

Gast2

Gast
Du könntest ans Ende der Datei ne Kontrollsequenz schreiben. Dann weißt du beim einlesen ob die Datei korrekt ist oder nicht.
 

Ark

Top Contributor
Vor dem Erstellen der richtigen Datei erzeugst du eine Art Logdatei, in der du notierst (durch Anhängen, niemals durch Ersetzen!), bis wohin du schon sicher gekommen bist, indem du z.B. die bisher gültige Länge der "richtigen" Datei speicherst. Diese Logdatei beschreibst du ungepuffert(!).

In regelmäßigen Abständen (zeitliches Intervall oder bestimmte Datenmenge) flushst du den Ausgabestrom in die richtige Datei und schreibst dann in die Logdatei, wie weit du gekommen bist. Da es aber durch unglückliche Umstände beim Caching seitens des Betriebssystems dazu kommen kann, dass die Logdatei schon einen Eintrag bekommt, die richtigen Daten aber in Wirklichkeit noch gar nicht geschrieben sind (obwohl du, wie gesagt, flush() aufrufst), musst du beim Wiederaufnehmen nach dem Absturz überprüfen, ob die Datei die im Log eingetragene Länge wirklich erreicht hat, und falls nicht, entsprechend auf einen älteren Stand im Log zurückgreifen und den "fehlerhaften" Teil des Logs und der Daten löschen.

Das alles funktioniert übrigens nur, wenn du die Daten fortlaufend schreibst! Zwischendurch die richtige Datei zu ändern, ist nicht gerade prickelnd und bedarf eines höheren Aufwands.

War das so weit verständlich?

Ark
 

Wortraum

Bekanntes Mitglied
Den umgekehrten Fall gibt es auch noch: die Daten wurden bereits „richtig“ geschrieben, davon ist aber nichts im Log vermerkt. Solch eine klassische Protokollierung ergibt wirklich nur bei Dateisystemen einen Sinn.

Diese Konsistenzprobleme fallen weg, wenn man eine einzige Datei verwendet. Am einfachsten ist es, wenn man die Sicherungspunkte zeilenweise schreibt, denn entweder gibt es ein Zeilenende, wenn der Schreibvorgang erfolgreich war, oder es gibt keines. Kann man nicht zeilenweise speichern, benötigt man eine Endmarkierung.

Es kann aber auch sein, daß die Sicherungspunkte zu groß sind, um sie fortlaufend zu speichern, so daß man nur einige vorhalten kann. Entweder hat man dazu einen festen Bereich in einer Datei für einen Sicherheitspunkt, oder man muß mehrere Dateien verwenden. Der älteste Stand wird mit dem neuen Sicherungspunkt überschrieben. Problem hierbei: Es ist möglich, daß alle Sicherungspunkte einmal überschrieben wurden, ohne daß die Daten auf die Platte gelangen. Man kann sich zwar informieren, in welcher Zeit ein Dateisystem spätestens Daten schreibt und welche Garantie es zur Wiederherstellung gibt, aber schon wäre man dateisystemgebunden und von Betriebssystemeinstellungen abhängig. Das ist keine gute Idee!

Gleiches gilt, wenn man explizit einen Systemaufruf aufruft, der den Puffer schreibt. Dann doch lieber die Daten auf einem zusätzlichen Dateisystem speichern, das synchron eingehängt wurden, wo also niemals gepuffert wird. Aus Anwendungssicht ist das am einfachsten.

Um es kurz zu machen: Mehr als eine Datei zu verwenden, ist problematisch; kleine Sicherungspunkte sind mit höherer Wahrscheinlichkeit vollständig als große; fortlaufende Sicherung mit einer Endmarkierung ist einfach (der letzte Sicherpunkt zwischen zwei Endpunkten ist der gültige).
 

slawaweis

Bekanntes Mitglied
es gibt da mehrere Strategien. Zuerst ist es aber wichtig herauszufinden und aufzuschreiben, aus welchem Grund es überhaupt schief laufen kann. Das kann sein: Strom weg, Festplatte kaputt, Festplatte voll, zu wenig RAM, Behinderung durch ein anderes Programm usw. Danach muss man versuchen so viele Fehlerquellen wie möglich schon im voraus zu vermeiden, z.B. mit USV, RAID, Speicherplatzreservierung, andere Programme vorher abschalten usw.

Ansonsten sind die gängigsten Methoden den aktuellen Berechnungsstand zu protokollieren, z.B. "angefangen Sicherung zu schreiben" -> "beendet" -> "überprüft". Abhängig vom Feinheitsgrad, kann man so später überprüfen, wo die Berechnung abgebrochen wurde und an einer sicheren Stelle weitermachen.

Eine Methode bei größeren Daten ist, diese nicht im Speicher zu halten, sondern in kleinen Blöcken auf der Festplatte abzulegen. In der Computergrafik, während einer aufwändigen Videoberechnung, werden die einzelnen Bilder als solche auf der Festplatte abgelegt, im Speicher ist nur jeweils ein Bild pro Thread. Erst wenn alle Einzelbilder berechnet wurden, wird in einem zweiten Durchlauf daraus eine einzige Videodatei erstellt. Das hat auch den Vorteil, dass man auch hinterher noch einzelne Stellen neuberechnen oder weglassen kann, ohne alles von vorne auszurechnen.

Slawa
 
G

Gast2

Gast
Code:
WriteShadowFile();
CopyShadowToReal();

wenn er beim Schreiben der Shadow-Datei abbricht, hast Du beim Neustart noch die letzte Speicherung

wenn er beim Kopieren abbricht (Hardwareprobleme/Stromausfall), dann kannst Du beim Neustart auf die Shadow-Datei zugreifen
 

Wortraum

Bekanntes Mitglied
wenn er beim Schreiben der Shadow-Datei abbricht, hast Du beim Neustart noch die letzte Speicherung
Aber auch hier nur, wenn das Dateisystem eine Vollprotokollierung durchführt oder keinen Puffer verwendet. Wenn es einem nur darum geht, daß das eigene Programm abgebrochen werden kann, dann muß man natürlich die Probleme auf Ebene des Dateisystems nicht berücksichtigen.
 

Ark

Top Contributor
Den umgekehrten Fall gibt es auch noch: die Daten wurden bereits „richtig“ geschrieben, davon ist aber nichts im Log vermerkt. Solch eine klassische Protokollierung ergibt wirklich nur bei Dateisystemen einen Sinn.
Es stimmt zwar, dass es einen solchen Fall gibt, aber der ist nicht weiter problematisch. In diesem Fall verwirft man einfach alles, was nicht im Protokoll vermerkt ist. Das führt zwar unter Umständen dazu, dass die letzte Berechnung noch einmal durchgeführt werden muss, obwohl sie schon einmal erfolgreich abgeschlossen wurde, aber es kommt nicht anderweitig zu Fehlern oder Inkonsistenzen.

  1. Größe laut Log stimmt mit tatsächlicher Größe überein: alles okay.
  2. solange Größe laut Log größer ist als die tatsächliche Größe: gehe im Log einen Schritt zurück. Wenn dann ein passender Eintrag gefunden wurde: Verwirf alles, was noch danach im Log und laut diesem in der "richtigen" Datei kam. Beginne ab dort die Berechnungen noch einmal neu.
  3. Größe laut Log ist kleiner als die tatsächliche Größe: Verwirf die "richtigen" Daten, die laut Log gar nicht existieren dürften. Beginne ab dort die Berechnungen noch einmal neu.
(Ich hoffe, dass damit alle Fälle abgedeckt sind. :oops: )

Ark
 

Wortraum

Bekanntes Mitglied
[…] In diesem Fall verwirft man einfach alles, was nicht im Protokoll vermerkt ist. Das führt zwar unter Umständen dazu, dass die letzte Berechnung noch einmal durchgeführt werden muss, obwohl sie schon einmal erfolgreich abgeschlossen wurde, aber es kommt nicht anderweitig zu Fehlern oder Inkonsistenzen.
Ich glaube, ich hörte dort auf zu denken, wo mir auffiel, daß ein Sicherungspunkt protokolliert werden kann, ohne daß er bereits geschrieben wurde. Aber gut, daß Du weiterdachtest, denn Du hast natürlich recht. :)
 

-horn-

Bekanntes Mitglied
moien,

also ich speichere das als xml ab, aberda ichbis jetzt nurxml auslesen mit DOM machen konnte, erzeuge ich weiterhin die xmldatei zeilenweise und gebe die werte in die nodes und auch die tags dazu an. ist vielleicht kein schöner weg, aber er geht.
da ich die ganze datei zeilenweise erzeuge müsste ich eigentlich nur gucken, ob der allumschliessende tag, bei mir <result> auch mit einem </result> kommplet in der letzten zeile abgeschlossen wurde. wenn da auch nur das ">" fehlt wurde der schreibvorgang unterbrochen.

jetzt müsste ich nach der dateiexistenzsprüfung noch vorher in die datei rein und in die letzte zeile springen und dort schauen, ob da der tag richtig ist. ich muss dann zwar schauen, wie ichdas mache, bin ja anfänger :D, aber das sollte ja gehen.

aber ihr merkt sicherlich, dass das erstmal viel gefrickel ist. ich hätte da lieber erstmal was einfaches, was mir die anfälligkeitfalscher speicherei reduziert und dann irgendeine art backup unddann erst diese konsitenzprüfung.

grüße,

Andreas
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Sportwetten Daten Atomatisch analysieren um optimale Strategie zu erhalten Java Basics - Anfänger-Themen 6
N Stoploss Strategie Java Basics - Anfänger-Themen 3
T Entwurfsmuster Strategie Java Basics - Anfänger-Themen 10
W Entwurfsmuster Strategie Java Basics - Anfänger-Themen 2
A Zahlenratespiel mit Strategie Java Basics - Anfänger-Themen 10
M Greedy-Strategie Java Basics - Anfänger-Themen 3
H Strategie um einen Bug zu finden Java Basics - Anfänger-Themen 4
G Strategie oder ? Java Basics - Anfänger-Themen 2
A Bei VierGewinnt fragen ob man gegen CPU oder Menschen spielen will. Java Basics - Anfänger-Themen 7
A Bei VierGewinnt vorher fragen, ob man gegen den Computer spielen möchte oder gegeneinander. Java Basics - Anfänger-Themen 1
A Bei VierGewinnt fragen, ob man gegen den Computer spielen möchte oder gegeneinander Java Basics - Anfänger-Themen 1
M Nach einer erstmaligen Eingabe, eine zweite Eingabe nur noch gegen bestätigung möglich Java Basics - Anfänger-Themen 2
D Was tun gegen zu komplzierten Denken beim Programmieren Java Basics - Anfänger-Themen 27
V String Array gegen null-Eintrag sichern Java Basics - Anfänger-Themen 11
G gegen (etwas) programmieren Java Basics - Anfänger-Themen 11
C Reference - wird gegen meinen Willen - auf null gesetzt Java Basics - Anfänger-Themen 2
S Implementierung gegen Interfaces / List, ArrayList, LinkedList Java Basics - Anfänger-Themen 11
O Neuen Blackberry 8800 oder Curve gegen kleines Programm Java Basics - Anfänger-Themen 9
A Programmieren gegen Interfaces Java Basics - Anfänger-Themen 4
L Was kann ich gegen "CMitarbeiterBeispiel has no main me Java Basics - Anfänger-Themen 5
F gegen interfaces programmieren Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben