Debuggen von SegmentNotFoundException, wenn Problem in AEM 6.x gemeldet wird
In diesem Artikel erfahren Sie, wie Sie SegmentNotFoundException debuggen, wenn in AEM 6.x ein Problem gemeldet wird, indem Sie zur letzten zweifelsfrei funktionierenden Revision des Segmentspeichers zurückkehren.
Beschreibung description
Umgebung
Experience Manager 6.x
Problem/Symptome
Das Fehlerprotokoll zeigt eine SegmentNotFound-Ausnahme wie im folgenden Beispiel:
org.apache.jackrabbit.oak.segment.SegmentNotFoundException: Segment d2c720c4-c146-4ab1-ac37-542aad93c33f not found at
org.apache.jackrabbit.oak.segment.file.FileStore$8.call(FileStore.java:602) at
org.apache.jackrabbit.oak.segment.file.FileStore$8.call(FileStore.java:542) at
org.apache.jackrabbit.oak.segment.SegmentCache.getSegment(SegmentCache.java:95) at
org.apache.jackrabbit.oak.segment.file.FileStore.readSegment(FileStore.java:542) at
org.apache.jackrabbit.oak.segment.SegmentId.getSegment(SegmentId.java:125) at
org.apache.jackrabbit.oak.segment.Record.getSegment(Record.java:70) at
org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:424) at
org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:433) at
org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:391) at
org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:608) at
org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148) at
org.apache.jackrabbit.oak.segment.MapRecord$3.childNodeChanged(MapRecord.java:442) at
org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:490) at
org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:433) at
org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:608) at
org.apache.jackrabbit.oak.spi.commit.EditorDiff.process(EditorDiff.java:52) at
org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.updateIndex(AsyncIndexUpdate.java:695) at
org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.runWhenPermitted(AsyncIndexUpdate.java:543) at
org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.run(AsyncIndexUpdate.java:402) at
org.apache.sling.commons.scheduler.impl.QuartzJobExecutor.execute(QuartzJobExecutor.java:118) at
org.quartz.core.JobRunShell.run(JobRunShell.java:202) at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at
java.lang.Thread.run(Thread.java:745)
Auflösung resolution
Anzuwendende Schritte
Es gibt zwei Ansätze, um das Problem zu beheben und die Inkonsistenzen im Repository zu entfernen
Kehren Sie zur letzten zweifelsfrei funktionierenden Revision des Segmentspeichers zurück.
Zuerst Verwenden Sie das Oak-Run-Tool, ein ausführbares JAR[ 1], das alles enthält, was Sie für eine einfache Oak-Installation und die Durchführung von Oak-bezogenen Vorgängen benötigen.
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 die unten stehende Option B ausprobieren.
So führen Sie die Prüfung und Wiederherstellung durch:
-
Laden Sie von https://mvnrepository.com/artifact/org.apache.jackrabbit/oak-run eine Version von oak-run herunter, die Ihrer Oak-Core-Version entspricht.
-
Um einen beschädigten Segmentspeicher wieder in den letzten zuverlässig funktionierenden Zustand zu versetzen, wechseln Sie in das Arbeitsverzeichnis von CQ (das Verzeichnis, in dem sich der Ordner „crx-quickstart“ befindet) und sichern Sie alle Dateien in ./crx-quickstart/repository/segmentstore/.
-
Führen Sie die Konsistenzprüfung durch.
java -Xmx6000m -jar oak-run-*.jar check —bin=-1 /path/to/crx-quickstart/repository/segmentstore
Dadurch werden die Revisionen rückwärts durchsucht, bis eine konsistente gefunden wird:
Suchen Sie nach einer Nachricht wie der folgenden:
code language-none main INFO o.a.j.o.p.s.f.t.ConsistencyChecker - Found latest good revision afdb922d-ba53-4a1b-aa1b-1cb044b535cf:234880 -
Setzen Sie das Repository auf diese Revision zurück, indem Sie bearbeiten./crx-quickstart/repository/segmentstore/journal.log und Löschen aller Zeilen nach der Zeile, die die letzte zweifelsfrei funktionierende Revision enthält.
-
Alle entfernen ./crx-quickstart/repository/segmentstore/*.bak-Dateien.
-
Führen Sie mit dem folgenden Befehl eine Checkpoint-Bereinigung aus, um verwaiste Checkpoints zu entfernen:
code language-none java -Xmx6000m -jar oak-run-*.jar checkpoints /path/to/crx-quickstart/repository/segmentstore rm-unreferenced -
Komprimieren Sie schließlich das Repository:
java -Xmx6000m -jar oak-run-*.jar compact /path/to/crx-quickstart/repository/segmentstore/
Es kann vorkommen, dass die Oak-Ausführungsprüfung die korrekte Revision nicht finden kann und wir beim Ausführen des Befehls check den Hinweis „ConsistencyChecker - No good revision found“ erhalten.
Beheben von Fehlern bei der Konsistenzprüfung mit „ConsistencyChecker - Keine gute Revision gefunden“
Entfernen Sie beschädigte Knoten manuell.
Sie können Folgendes in AEM-, TarMK-Setups ohne konfigurierten FileDatastore und in Situationen tun, in denen die Binärdateien beschädigt sind.
Achtung: Die unten beschriebene Vorgehensweise ist für fortgeschrittene Benutzer gedacht. Beim Löschen der beschädigten Knoten müssen Sie sicherstellen, dass es sich nicht um Systemknoten (wie /home, /jcr:system usw.) handelt. Wenn es sich um Systemknoten handelt, müssen Sie sicherstellen, dass Sie sie wiederherstellen können. Wenden Sie sich an das Team der AEM-Kundenunterstützung, 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:
code language-none java -jar oak-run-*.jar console crx-quickstart/repository/segmentstoreFühren Sie die beiden folgenden Befehle in der Shell aus, um das Skript zu laden und auszuführen:
code language-none :load https://gist.githubusercontent.com/stillalex/e7067bcb86c89bef66c8/raw/d7a5a9b839c3bb0ae5840252022f871fd38374d3/childCount.groovy countNodes(session.workingNode)Dies führt zur folgenden Ausgabe, die den Pfad zu den beschädigten Knoten angibt:
code language-none 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:contentIn 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):
code language-none 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 mit dem folgenden Befehl:code language-none java -jar oak-run-*.jar console crx-quickstart/repository/segmentstoreLaden Sie das Skript „groovy“:
code language-none :load https://gist.githubusercontent.com/stillalex/43c49af065e3dd1fd5bf/raw/9e726a59f75b46e7b474f7ac763b0888d5a3f0c3/rmNode.groovyFühren Sie den Befehl rmNode aus, um den beschädigten Knoten zu entfernen, und ersetzen Sie "/path/to/corrupt/node“ durch den Pfad zum beschädigten Knoten, den Sie entfernen möchten.
code language-none 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 Sie oak-run.jar Version 1.6.13 und höher verwenden, legen Sie den JVM-Parameter —read-write fest, wenn Sie auf einen Fehler wie den folgenden stoßen:
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. Bei der nächsten Ausführung sollte false zurückgegeben werden.
Wenn Sie sehen, dass die gleichen Pfade noch im Repository vorhanden sind, verwenden Sie die gepatchte Version von oak-run jar, d. h. oak-run-1.2.18-NPR-17596. 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 resultierende komprimierte Repository sollte dann die Oak-Run-Prüfung und 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 diese:
code language-none nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-allnohup.out -
Führen Sie eine Offline-Komprimierung aus. Wenn Sie nicht wissen, wie Sie die Offline-Komprimierung ausführen, lesen Sie hier.
-
Starten Sie den Server und warten Sie, bis die Indizierung abgeschlossen ist.
Ursache
Eine SegmentNotFoundException im Fehlerprotokoll bedeutet, dass ein Segment nicht mehr vorhanden ist, obwohl anscheinend immer noch versucht wird, darauf zuzugreifen. Hierfür gibt es grob drei verschiedene Grundursachen: Das Segment wurde durch manuelles Eingreifen entfernt (z. B. rm -rf /), das Segment wurde durch die Revisionsbereinigung entfernt oder das Segment konnte aufgrund eines Fehlers im Code nicht gefunden werden.