SegmentNotFoundException und IllegalArgumentException
Das Ausführen einer Offline-Komprimierung kann mit SegmentNotFoundException oder IllegalArgumentException fehlschlagen. In diesem Artikel werden Möglichkeiten zum Beheben der Fehler und zum erfolgreichen Abschluss der Offline-Komprimierung erläutert. Bevor Sie jedoch fortfahren, führen Sie ein vollständiges Backup Ihres Repositorys durch.
Beschreibung description
Umgebung
Adobe Experience Manager (AEM)
Problem
Szenario 1
Das Ausführen einer Offline-Komprimierung kann mit SegmentNotFoundException fehlschlagen, wenn Integritätsprobleme des Repositorys auftreten.
Sie beobachten SegmentNotFoundException in AEM-Protokolldateien und AEM funktioniert nicht erwartungsgemäß.
Szenario 2
Das Ausführen einer Offline-Komprimierung kann mit SegmentNotFoundException fehlschlagen, wenn Integritätsprobleme des Repositorys auftreten.
In den Protokollen wird ein Stacktrace angezeigt, der dem unten ähnelt:
13:51:21.523 [ main] ERROR o.a.j.o.p.segment.SegmentTracker - Segment not found: 4d139bc4-150c-4f0a-b82a-4867593098a. Creation date delta is 4 ms.
org.apache.jackrabbit.oak.plugins.segment.SegmentNotFoundException: Segment 4d139bc4-150c-4f0a-b82a-4867593098a not found
at org.apache.jackrabbit.oak.plugins.segment.file.FileStore.readSegment(FileStore.java:855) [ oak-run-1.0.22.jar:1.0.22]
at org.apache.jackrabbit.oak.plugins.segment.SegmentTracker.getSegment(SegmentTracker.java:134) ~[ oak-run-1.0.22.jar:1.0.22]
at org.apache.jackrabbit.oak.plugins.segment.SegmentId.getSegment(SegmentId.java:101) [ oak-run-1.0.22.jar:1.0.22]
...
Exception in thread "main" org.apache.jackrabbit.oak.plugins.segment.SegmentNotFoundException: Segment 4d139bc4-150c-4f0a-b82a-4867593098a not found
at org.apache.jackrabbit.oak.plugins.segment.file.FileStore.readSegment(FileStore.java:855)
at org.apache.jackrabbit.oak.plugins.segment.SegmentTracker.getSegment(SegmentTracker.java:134)
at org.apache.jackrabbit.oak.plugins.segment.SegmentId.getSegment(SegmentId.java:101)
...
Szenario 3
Das Ausführen einer Offline-Komprimierung kann mit der Ausnahme IllegalArgument fehlschlagen, wenn Integritätsprobleme des Repositorys auftreten.
In den Protokollen wird ein Stacktrace angezeigt, der dem unten ähnelt:
java.lang.IllegalArgumentException
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:77)
at org.apache.jackrabbit.oak.plugins.segment.ListRecord.(ListRecord.java:41)
at org.apache.jackrabbit.oak.plugins.segment.ListRecord.getEntry(ListRecord.java:64)
at org.apache.jackrabbit.oak.plugins.segment.ListRecord.getEntries(ListRecord.java:81)
at org.apache.jackrabbit.oak.plugins.segment.SegmentStream.read(SegmentStream.java:153)
at org.apache.jackrabbit.oak.commons.IOUtils.readFully(IOUtils.java:53)
at org.apache.jackrabbit.oak.plugins.segment.Compactor.getBlobKey(Compactor.java:412)
at org.apache.jackrabbit.oak.plugins.segment.Compactor.compact(Compactor.java:362)
at org.apache.jackrabbit.oak.plugins.segment.Compactor.compact(Compactor.java:321)
at org.apache.jackrabbit.oak.plugins.segment.Compactor.access$500(Compactor.java:54)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff.propertyAdded(Compactor.java:227)
at org.apache.jackrabbit.oak.plugins.segment.CancelableDiff.propertyAdded(CancelableDiff.java:47)
at org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.compareAgainstEmptyState(EmptyNodeState.java:156)
at org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:434)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff.diff(Compactor.java:214)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff.childNodeAdded(Compactor.java:263)
at org.apache.jackrabbit.oak.plugins.segment.CancelableDiff.childNodeAdded(CancelableDiff.java:74)
at org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.compareAgainstEmptyState(EmptyNodeState.java:161)
at org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:434)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff. diff (Compactor.java:214)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff.childNodeAdded(Compactor.java:263)
at org.apache.jackrabbit.oak.plugins.segment.CancelableDiff.childNodeAdded(CancelableDiff.java:74)
at org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.compareAgainstEmptyState(EmptyNodeState.java:161)
at org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:434)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff. diff (Compactor.java:214)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff.childNodeAdded(Compactor.java:263)
at org.apache.jackrabbit.oak.plugins.segment.CancelableDiff.childNodeAdded(CancelableDiff.java:74)
at org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.compareAgainstEmptyState(EmptyNodeState.java:161)
at org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:434)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff. diff (Compactor.java:214)
at org.apache.jackrabbit.oak.plugins.segment.Compactor$CompactDiff.childNodeAdded(Compactor.java:263)
at org.apache.jackrabbit.oak.plugins.segment.CancelableDiff.childNodeAdded(CancelableDiff.java:74)
Lösung resolution
Es gibt mehrere Verfahren, die wir befolgen können, um die Situation zu beheben und die Offline-Komprimierung erfolgreich abzuschließen.
Wichtig: Führen Sie ein vollständiges Backup Ihres Repositorys durch, bevor Sie die folgenden Schritte ausführen.
A. Kehren Sie zur letzten zweifelsfrei funktionierenden Revision des Segmentspeichers zurück.
Mit dem Ausführungsmodus „Überprüfen“ von oak-run kann die letzte zweifelsfrei funktionierende Revision eines Segmentspeichers ermittelt werden.
Dies kann verwendet werden, um einen beschädigten Segmentspeicher manuell auf die letzte zweifelsfrei funktionierende Revision zurückzusetzen.
Achtung: Durch diesen Prozess werden die Daten im System auf einen früheren Zeitpunkt zurückgesetzt.
Wenn Sie vermeiden möchten, dass Änderungen in Ihrem System verloren gehen, können Sie stattdessen Option B unten versuchen.
Gehen Sie wie folgt vor, um die Prüfung und Wiederherstellung durchzuführen:
-
Laden Sie die
oak-run
JAR-Datei von hier herunter https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/. -
Beenden Sie AEM.
-
Führen Sie diesen Befehl aus:
java -jar oak-run-*.jar check --bin=-1 crx-quickstart/repository/segmentstore/
Dieser Befehl durchsucht die Revisionen rückwärts, bis er einen konsistenten findet:
14:00:30.783 [ main] INFO o.a.j.o.p.s.f.t.ConsistencyChecker - Found latest good revision afdb922d-ba53-4a1b-aa1b-1cb044b535cf:234880
(Falls der ConsistencyChecker fehlschlägt, fahren Sie mit dem nächsten Abschnitt fort.)
-
Setzen Sie das Repository auf diese Revision zurück, indem Sie Folgendes bearbeiten:
/crx-quickstart/repository/segmentstore/journal.log
Löschen Sie alle Zeilen nach der Zeile, die die letzte zweifelsfrei funktionierende Revision enthält.
Wenn Sie herausfinden möchten, auf welches Datum und welche Uhrzeit Sie das Repository zurücksetzen, führen Sie diesen Befehl im
segmentstore
aus (ersetzen Sie afdb922d-ba53-4a1b-aa1b-1cb044b535cf durch die letzte zweifelsfrei funktionierende Revision in Ihremjournal.log
):find . -type f -name "data*.tar" -exec sh -c "tar -tvf {} |grep afdb922d-ba53-4a1b-aa1b-1cb044b535cf" \; -print
Die Ausgabe zeigt Ihnen ein ungefähres Datum und eine ungefähre Uhrzeit dieser Revision.
-
Entfernen Sie alle
./crx-quickstart/repository/segmentstore/*.bak files.
. -
Wenn Sie AEM 6.0 verwenden, laden Sie die oak-run-Version herunter, die mit dem übereinstimmt, was in AEM für die restlichen Schritte installiert ist.
Laden Sie sie von hier herunter https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/.
-
Führen Sie Checkpoint-Bereinigung“ aus um verwaiste Checkpoints zu entfernen:
java -jar oak-run-*.jar checkpoints ./crx-quickstart/repository/segmentstore rm-unreferenced
-
Komprimieren Sie schließlich das Repository:
java -jar oak-run-*.jar compact ./crx-quickstart/repository/segmentstore/
B. Entfernen Sie beschädigte Knoten manuell.
In AEM-TarMK-Setups ohne konfigurierten FileDatastore und in Situationen, in denen die Binärdateien beschädigt sind, können Sie Folgendes tun.
Achtung: Die unten beschriebene Vorgehensweise ist für Power-User gedacht.
Wenn Sie die beschädigten Knoten löschen, müssen Sie sicherstellen, dass es sich nicht um Systemknoten (wie /home
, /jcr:system
usw.) handelt.
Oder wenn es sich um Systemknoten handelt, müssen Sie sicherstellen, dass Sie sie wiederherstellen können.
Wenden Sie sich an das AEM-Kundenunterstützungs-Team, um Unterstützung bei den hier beschriebenen Schritten zu erhalten, wenn Sie sich nicht sicher sind.
-
Beenden Sie AEM.
-
Verwenden Sie die Oak-Ausführungskonsole und laden Sie das Skript "
childCount
groovy“, um die beschädigten Knoten im Segmentspeicher zu identifizieren:Laden Sie die Oak-Run-Konsolen-Shell:
java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore
Führen Sie die beiden folgenden Befehle in der Shell aus, um das Skript zu laden und auszuführen:
:load
https://gist.githubusercontent.com/stillalex/e7067bcb86c89bef66c8/raw/d7a5a9b839c3bb0ae5840252022f871fd38374d3/childCount.groovy
countNodes(session.workingNode)
Dies führt zur folgenden Ausgabe, die den Pfad zu dem/den beschädigten Knoten angibt:
21:21:42.029 [ main] ERROR o.a.j.o.p.segment.SegmentTracker - Segment not found: 63ae05a4-b506-445c-baa2-cfa1b13b6e2f. Creation date delta is 3 ms.
warning unable to read node /content/dam/test.txt/jcr:content/renditions/original/jcr:content
In einigen Fällen hängt das Problem mit binären Eigenschaften zusammen und das Skript "
childCount
groovy“ kann keine beschädigten Knoten finden.In diesen Fällen können Sie stattdessen den folgenden Befehl verwenden, der die ersten 1024 Byte für jede während der Durchlaufphase aufgefundene Binärdatei liest (beachten Sie, dass dieser Befehl langsamer ist und nur verwendet werden sollte, wenn das oben genannte nicht die erwarteten Ergebnisse zurückgibt):
countNodes(session.workingNode,true)
-
Entfernen Sie mithilfe von
rmNodes.groovy
alle identifizierten beschädigten Knoten, die in der Ausgabe des letzten Befehls aufgelistet sind.Laden Sie die Oak-Run-Konsolen-Shell:
java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore
Laden Sie das Skript „groovy“:
:load
https://gist.githubusercontent.com/stillalex/43c49af065e3dd1fd5bf/raw/9e726a59f75b46e7b474f7ac763b0888d5a3f0c3/rmNode.groovy
Führen Sie den Befehl
rmNode
aus, um den beschädigten Knoten zu entfernen, und ersetzen Sie/path/to/corrupt/node
durch den Pfad zu dem beschädigten Knoten, den Sie entfernen möchten.rmNode(session, "/path/to/corrupt/node")
Wobei der Pfad des beschädigten Knotens der Pfad ist, der in Schritt 2 ermittelt wurde, zum Beispiel:
/content/dam/test.txt/jcr:content/renditions/original/jcr:content/
.
Hinweis: Wenn Sieoak-run.jar
Version 1.6.13 und höher verwenden, legen Sie--read-write
JVM-Parameter fest, wenn ein Fehler wie der folgende auftritt:code language-none /> rmNode(session,"/path/to/corrupt/node") Removing node /path/to/corrupt/node ERROR java.lang.UnsupportedOperationException: Cannot write to read-only store at org.apache.jackrabbit.oak.segment.SegmentWriterBuilder$1.execute (SegmentWriterBuilder.java:171) at org.apache.jackrabbit.oak.segment.SegmentWriter.writeNode (SegmentWriter.java:318) at org.apache.jackrabbit.oak.segment.SegmentNodeBuilder.getNodeState (SegmentNodeBuilder.java:111) at org.apache.jackrabbit.oak.segment.SegmentNodeStore$Commit.<init> (SegmentNodeStore.java:581) at org.apache.jackrabbit.oak.segment.SegmentNodeStore.merge (SegmentNodeStore.java:333) at org.apache.jackrabbit.oak.spi.state.NodeStore$merge.call (Unknown Source) at groovysh_evaluate.rmNode (groovysh_evaluate:11)
-
Wiederholen Sie Schritt 3 für alle in Schritt 2 gefundenen Knoten.
Der obige
rmNode
-Befehl sollte für den beschädigten Pfad „true“ zurückgeben, was bedeutet, dass er ihn gelöscht hat.Stellen Sie sicher, dass die drei gefundenen beschädigten Pfade gelöscht werden, indem Sie den
rmNode
-Befehl für diese Pfade erneut ausführen.Für die nächste Ausführung sollte
false
zurückgegeben werden.Wenn Sie immer noch sehen, dass die gleichen Pfade im Repository vorhanden sind, dann verwenden Sie die gepatchte Version von oak-run jar (d. h. oak-run-1.2.18-NPR-17596).
Was bewirkt die gepatchte Version von oak-run jar?
Diese Version von JAR überspringt unlesbare Binärdateien bei der Komprimierung, ersetzt sie durch 0-Byte-Binärdateien und protokolliert die Ausnahme und den Pfad zu syserr.
Das so komprimierte Repository sollte dann die Oak-run-Prüfung, also das Knotenzählungsskript, bestehen und Sie sollten es auch mit einem nicht gepatchten Oak-run erneut komprimieren können.
-
Führen Sie eine Checkpoint-Bereinigung durch, indem Sie Checkpoints wie unten beschrieben auflisten.
Wenn es mehr als einen Checkpoint gibt, bereinigen Sie die Liste:
nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-all>>nohup.out &
-
Führen Sie eine Offline-Komprimierung aus.
Wenn Sie nicht wissen, wie Sie die Offline-Komprimierung ausführen, lesen Sie Anweisungen zur Offline-Komprimierung von Oak auf GitHub Gist.
-
Starten Sie den Server und warten Sie auf den Abschluss der Indizierung.
Ursache
Eine SegmentNotFoundException wird zurückgegeben, wenn ein Segment nicht vorhanden ist, während die Komprimierung versucht, den Knoten zu lesen.
Dafür kann es verschiedene Ursachen geben:
- Das Segment wurde durch manuelles Eingreifen entfernt (z. B.: rm -rf /).
- Das Segment wurde durch die Revisionsspeicherbereinigung entfernt.
- Das Segment kann aufgrund eines Fehlers im Code nicht gefunden werden.
Falls das Problem durch die Revisionsdatenbereinigung verursacht wird (Ursache #2), stellen Sie sicher, dass die Online-Komprimierung deaktiviert ist, um zu verhindern, dass weitere Knoten beschädigt werden.