NEWS
Kein Backup nach Systemupdate (gelöst)
-
Könnte es ein Bild in den mqtt Objekten sein?
-
Könnte es ein Bild in den mqtt Objekten sein?
-
Hmm, ich hatte die Meldung auch vor kurzem und ich hab auch Redis. Das Backup konnte nicht erstellt werden und bei mir lag es ein an einem Objekt was von einem Bild gekommen ist. Beim erstellen des Backups wird diese Datei objects.jsonl ja angelegt.
edit
Du musst herausfinden welches Objekt diesen Fehler verursacht, löschen und dann läuft das Backup durch. -
Die Meldung kommt nicht von Backitup, sondern vom js-controller. Backitup ruft nur iobroker backup auf, und der macht Folgendes:
- Er legt den Ordner /opt/iobroker/node_modules/iobroker.js-controller/tmp/backup/ an.
- Er holt alle Objekte aus der laufenden Datenbank und schreibt jedes als eine Zeile in eine neue objects.jsonl in diesem Ordner. Dasselbe passiert mit den States.
- Er liest beide Dateien zeilenweise zurück und prüft jede Zeile mit JSON.parse. Darum bezieht sich „line 1 column 32145" auf eine einzelne Zeile, nicht auf die ganze Datei.
- Schlägt die Prüfung fehl, löscht er den tmp-Ordner sofort wieder. Deshalb findet man die geprüfte Datei hinterher nicht mehr.
Die objects.jsonl in iobroker-data ist also nicht die geprüfte Datei. Selbst wenn dort eine Zeile defekt wäre, überspringt der js-controller sie beim Start, und der Export aus dem Speicher wäre trotzdem gültig.
Was die Meldung bedeutet
Der Export erzeugt nie kaputtes JSON. Wenn die zurückgelesene Zeile nach 32 KB mitten in einem String endet, wurde sie beim Schreiben abgeschnitten. Typische Ursachen: Platte voll oder Schreibfehler im Dateisystem, etwa eine sterbende SD-Karte. Erster Blick:
df -h /opt/iobroker df -i /opt/iobroker dmesg | grep -iE "i/o error|ext4|mmc" | tailDann iobroker backup einmal von Hand in der Konsole starten. Dort sieht man die komplette Ausgabe, die Backitup nur im Debug-Log zeigt. Interessant sind die Zeilen „Cannot get objects: …" oder „Cannot get states: …" direkt vor „Validating backup …".
Die betroffene Zeile finden
Weil der tmp-Ordner gelöscht wird, muss man die Datei während des Laufs wegkopieren. Im ersten Terminal:
while true; do cp /opt/iobroker/node_modules/iobroker.js-controller/tmp/backup/objects.jsonl /tmp/objects_dump.jsonl 2>/dev/null; cp /opt/iobroker/node_modules/iobroker.js-controller/tmp/backup/states.jsonl /tmp/states_dump.jsonl 2>/dev/null; sleep 0.2; doneIm zweiten Terminal:
iobroker backupNach dem Fehler das erste Terminal mit Strg+C beenden. Der folgende Einzeiler liest die Kopie genauso wie der js-controller und nennt Zeilennummer, Objekt-ID, Zeilenlänge und die 120 Zeichen vor der gemeldeten Position:
node -e 'const {open}=require("fs/promises");(async()=>{const fd=await open(process.argv[1]);let n=0;for await(const line of fd.readLines()){n++;try{JSON.parse(line)}catch(e){const m=line.match(/"_?id":"([^"]+)"/);const p=+((e.message.match(/position (\d+)/)||[0,line.length])[1]);console.log("Zeile "+n+": "+(m?m[1]:"ID unlesbar")+" | Laenge "+line.length+" | "+e.message);console.log("..."+line.slice(Math.max(0,p-120),p)+" <<< Position "+p)}}})()' /tmp/objects_dump.jsonlFür die States denselben Aufruf mit /tmp/states_dump.jsonl am Ende.
Einordnung des Ergebnisses
- Ist die gemeldete Zeile die letzte in der Kopie, wurde der Export mittendrin abgebrochen. Dann zuerst Platz schaffen, zum Beispiel alte Backups in /opt/iobroker/backups und im Backitup-Zielordner löschen, und den Lauf wiederholen.
- Steht die Zeile mitten in der Datei, ist die Objekt-ID der Ausgangspunkt. Das Objekt im Admin unter „Objekte" ansehen und prüfen, welcher Adapter es angelegt hat.
Zur Kontrolle der Live-Dateien reicht ein Blick auf die letzten 100 Zeichen. Endet die Ausgabe mit }$, ist die letzte Zeile vollständig, fehlt das $, ist sie abgeschnitten:
tail -c 100 /opt/iobroker/iobroker-data/objects.jsonl | cat -A tail -c 100 /opt/iobroker/iobroker-data/states.jsonl | cat -A -
Die Meldung kommt nicht von Backitup, sondern vom js-controller. Backitup ruft nur iobroker backup auf, und der macht Folgendes:
- Er legt den Ordner /opt/iobroker/node_modules/iobroker.js-controller/tmp/backup/ an.
- Er holt alle Objekte aus der laufenden Datenbank und schreibt jedes als eine Zeile in eine neue objects.jsonl in diesem Ordner. Dasselbe passiert mit den States.
- Er liest beide Dateien zeilenweise zurück und prüft jede Zeile mit JSON.parse. Darum bezieht sich „line 1 column 32145" auf eine einzelne Zeile, nicht auf die ganze Datei.
- Schlägt die Prüfung fehl, löscht er den tmp-Ordner sofort wieder. Deshalb findet man die geprüfte Datei hinterher nicht mehr.
Die objects.jsonl in iobroker-data ist also nicht die geprüfte Datei. Selbst wenn dort eine Zeile defekt wäre, überspringt der js-controller sie beim Start, und der Export aus dem Speicher wäre trotzdem gültig.
Was die Meldung bedeutet
Der Export erzeugt nie kaputtes JSON. Wenn die zurückgelesene Zeile nach 32 KB mitten in einem String endet, wurde sie beim Schreiben abgeschnitten. Typische Ursachen: Platte voll oder Schreibfehler im Dateisystem, etwa eine sterbende SD-Karte. Erster Blick:
df -h /opt/iobroker df -i /opt/iobroker dmesg | grep -iE "i/o error|ext4|mmc" | tailDann iobroker backup einmal von Hand in der Konsole starten. Dort sieht man die komplette Ausgabe, die Backitup nur im Debug-Log zeigt. Interessant sind die Zeilen „Cannot get objects: …" oder „Cannot get states: …" direkt vor „Validating backup …".
Die betroffene Zeile finden
Weil der tmp-Ordner gelöscht wird, muss man die Datei während des Laufs wegkopieren. Im ersten Terminal:
while true; do cp /opt/iobroker/node_modules/iobroker.js-controller/tmp/backup/objects.jsonl /tmp/objects_dump.jsonl 2>/dev/null; cp /opt/iobroker/node_modules/iobroker.js-controller/tmp/backup/states.jsonl /tmp/states_dump.jsonl 2>/dev/null; sleep 0.2; doneIm zweiten Terminal:
iobroker backupNach dem Fehler das erste Terminal mit Strg+C beenden. Der folgende Einzeiler liest die Kopie genauso wie der js-controller und nennt Zeilennummer, Objekt-ID, Zeilenlänge und die 120 Zeichen vor der gemeldeten Position:
node -e 'const {open}=require("fs/promises");(async()=>{const fd=await open(process.argv[1]);let n=0;for await(const line of fd.readLines()){n++;try{JSON.parse(line)}catch(e){const m=line.match(/"_?id":"([^"]+)"/);const p=+((e.message.match(/position (\d+)/)||[0,line.length])[1]);console.log("Zeile "+n+": "+(m?m[1]:"ID unlesbar")+" | Laenge "+line.length+" | "+e.message);console.log("..."+line.slice(Math.max(0,p-120),p)+" <<< Position "+p)}}})()' /tmp/objects_dump.jsonlFür die States denselben Aufruf mit /tmp/states_dump.jsonl am Ende.
Einordnung des Ergebnisses
- Ist die gemeldete Zeile die letzte in der Kopie, wurde der Export mittendrin abgebrochen. Dann zuerst Platz schaffen, zum Beispiel alte Backups in /opt/iobroker/backups und im Backitup-Zielordner löschen, und den Lauf wiederholen.
- Steht die Zeile mitten in der Datei, ist die Objekt-ID der Ausgangspunkt. Das Objekt im Admin unter „Objekte" ansehen und prüfen, welcher Adapter es angelegt hat.
Zur Kontrolle der Live-Dateien reicht ein Blick auf die letzten 100 Zeichen. Endet die Ausgabe mit }$, ist die letzte Zeile vollständig, fehlt das $, ist sie abgeschnitten:
tail -c 100 /opt/iobroker/iobroker-data/objects.jsonl | cat -A tail -c 100 /opt/iobroker/iobroker-data/states.jsonl | cat -A@Shadowhunter23
Vielen Dank für die Details. Ich hab beides mal gemacht:State des Systems scheint gut (ich hab auch mal alle nvme meldungen aus dmesg mitgegeben:
stormy@stormbroker:~ $ dmesg | grep -iE "i/o error|ext4|mmc|nvme" | tail [ 2.176827] nvme nvme0: Ignoring bogus Namespace Identifiers [ 2.185052] nvme0n1: p1 p2 [ 2.664564] sdhci-brcmstb 1000fff000.mmc: Got CD GPIO [ 2.664644] mmc1: CQHCI version 5.10 [ 2.669737] mmc0: CQHCI version 5.10 [ 2.714064] mmc0: SDHCI controller on 1000fff000.mmc [1000fff000.mmc] using ADMA 64-bit [ 2.863102] mmc1: SDHCI controller on 1001100000.mmc [1001100000.mmc] using ADMA 64-bit [ 2.903687] mmc1: new ultra high speed DDR50 SDIO card at address 0001 [ 3.590822] EXT4-fs (nvme0n1p2): mounted filesystem ce208fd3-38a8-424a-87a2-cd44114eb820 ro with ordered data mode. Quota mode: none. [ 4.448618] EXT4-fs (nvme0n1p2): re-mounted ce208fd3-38a8-424a-87a2-cd44114eb820 r/w. stormy@stormbroker:~ $Vollständig ist die Datei schon - der Fehler kommt aus einem State - da muss ich schauen wo der genau her kommt.
Allerdings sehe ich da trotzdem einen Bug im JS-Controller - beim Fehler muss die Datei entweder erhalten bleiben, oder eine bessere Meldung gegeben werden - sonst kommt man da nie drauf.
da mach ich morgen einen Bug Report im JS-Controller.
Nochmal vielen Dank.
-
Wie gesagt bei mir war es ein Bild unter mqtt welches den file is corrupted erzeugt hat. Nach dem löschen des Objektes lief das Backup wieder fehlerfrei durch.
-
Wie gesagt bei mir war es ein Bild unter mqtt welches den file is corrupted erzeugt hat. Nach dem löschen des Objektes lief das Backup wieder fehlerfrei durch.
@Shadowhunter23 Bei mir sind es Einträge im
nativedie aus dem icloud2 Adapter kommen. Das zu finden ist selbst mit deinen Code-Schnipseln (nochmal danke dafür) nicht einfach.Ich hab einen Issue am JS-Controller zum Thema löschen der Daten auch wenn Fehler beim Parsen auftreten aufgemacht. https://github.com/ioBroker/ioBroker.js-controller/issues/3484
A.
-
Ich frag mich nur warum irgendwelche Einträge im native das Backup crashen dürfen. Das sieht eigentlich nach eine Fehler im Backupkonzept oder im adpater-core aus. Solange ich etwas (egal was) mit den Systemroutinen in meine Objekte schreiben kann darf m.E. das Backup nicht daran scheitern sonern muss das 1:1 sichern und restaurieren.
Ev. wäre da ein zweites Issue mit der Forderung nach Backup muss alles sichern oder Schreiben ungültiger Daten muss verhindert werden angebracht. Wenn du das noch infos hast welcher Art die ungültigen Daten waren schreib das ggF.
P.S. Ich gehe davon aus, dass die ungültigen Daten NICHT durch manuelle Aktionen oder Dehle im Datei / Datenbanksystem oder Crashes entstanden sind.
-
Ich frag mich nur warum irgendwelche Einträge im native das Backup crashen dürfen. Das sieht eigentlich nach eine Fehler im Backupkonzept oder im adpater-core aus. Solange ich etwas (egal was) mit den Systemroutinen in meine Objekte schreiben kann darf m.E. das Backup nicht daran scheitern sonern muss das 1:1 sichern und restaurieren.
Ev. wäre da ein zweites Issue mit der Forderung nach Backup muss alles sichern oder Schreiben ungültiger Daten muss verhindert werden angebracht. Wenn du das noch infos hast welcher Art die ungültigen Daten waren schreib das ggF.
P.S. Ich gehe davon aus, dass die ungültigen Daten NICHT durch manuelle Aktionen oder Dehle im Datei / Datenbanksystem oder Crashes entstanden sind.
Ich frag mich nur warum irgendwelche Einträge im native das Backup crashen dürfen. Das sieht eigentlich nach eine Fehler im Backupkonzept oder im adpater-core aus. Solange ich etwas (egal was) mit den Systemroutinen in meine Objekte schreiben kann darf m.E. das Backup nicht daran scheitern sonern muss das 1:1 sichern und restaurieren.
Soweit habe ich noch nicht gedacht - es ist (leider) für jeden nachzuvollziehen wie das Backup gestört werden kann ohne das der ioBroker selber abstürzt:
Man nehme:
- einen Datenpunkt (z.Bsp.
0_userdata.0.testing.testing), typString - dieses Skript
setState('0_userdata.0.testing.testing',`{"bla":"tes${String.fromCharCode(parseInt('2028', 16))}ting"}`);Nebenbei: das ich da ein JSON als String rein schreibe dient dazu, den Fehler zu visualisieren. Der JSON Editor zeigt das falsche Zeichen sichtbar an - wenn einfach nur das Script
setState('0_userdata.0.testing.testing',`tes${String.fromCharCode(parseInt('2028', 16))}ting`);genutzt wird tritt der Fehler auch auf - ist aber deutlich schwerer zu erkennen:

vs

Nach Ausführung des Skriptes führt der ioBroker (bei mir, mit redis als state/objekt Datenbank) das Backup nicht mehr aus.
Alleine durch schreiben eines
sauberenWertes in den Datenpunkt kann das korrigiert werden - dann gehen auch wieder Backups.disclaimer: Ich hab das nicht auf einem System mit JSONL als Objekt/State DB getestet. Es ist denkbar das in diesem Fall der ioBroker nicht startet wenn er neustarten soll bevor der Fehler korrigiert wurde weil er die ObjektDB nicht einlesen kann. Testen auf eigenes Risiko
Ev. wäre da ein zweites Issue mit der Forderung nach Backup muss alles sichern oder Schreiben ungültiger Daten muss verhindert werden angebracht. Wenn du das noch infos hast welcher Art die ungültigen Daten waren schreib das ggF.
P.S. Ich gehe davon aus, dass die ungültigen Daten NICHT durch manuelle Aktionen oder Dehle im Datei / Datenbanksystem oder Crashes entstanden sind.
Bei mir sind die ungültigen Daten vom Adapter iCloud geschrieben worden. Die werden auch restauriert wenn der Adapter neu synchronisiert. Daher habe ich die Information erst einmal an den Autor des Adapters weiter gegeben.
In wieweit da der JS-Controller beim schreiben der JSONL Datei das absichern kann/soll kann ich erst einmal nicht bewerten.
- einen Datenpunkt (z.Bsp.
Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.
Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.
Mit deinem Input könnte dieser Beitrag noch besser werden 💗
Registrieren Anmelden