SegmentNotFoundException und IllegalArgumentException
Das Ausführen einer Offline-Verdichtung kann mit SegmentNotFoundException oder IllegalArgumentException fehlschlagen. In diesem Artikel werden Möglichkeiten erläutert, die Fehler zu beheben und die Offline-Verdichtung erfolgreich abzuschließen. Bevor Sie jedoch fortfahren, führen Sie eine vollständige Sicherung Ihres Repositorys durch.
Beschreibung description
Umgebung
Adobe Experience Manager (AEM)
Problem
Szenario 1
Das Ausführen einer Offline-Verdichtung kann mit SegmentNotFoundException fehlschlagen, wenn Integritätsprobleme des Repositorys auftreten.
Sie stellen fest, dass SegmentNotFoundException in AEM Protokolldateien funktioniert und AEM nicht erwartungsgemäß funktioniert.
Szenario 2
Das Ausführen einer Offline-Verdichtung kann mit SegmentNotFoundException fehlschlagen, wenn Integritätsprobleme des Repositorys auftreten.
Eine Stapelablaufverfolgung, die der unten stehenden ähnelt, wird in den Protokollen angezeigt:
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-Verdichtung kann mit der Ausnahme IllegalArgument fehlschlagen, wenn Integritätsprobleme des Repositorys vorliegen.
Eine Stapelablaufverfolgung, die der unten stehenden ähnelt, wird in den Protokollen angezeigt:
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.
Der Ausführungsmodus "Überprüfen"von oak-run kann verwendet werden, um die letzte zweifelsfrei funktionierende Revision eines Segmentspeichers zu ermitteln.
Dies kann verwendet werden, um einen beschädigten Segmentspeicher manuell auf die letzte zweifelsfrei funktionierende Revision zurückzusetzen.
Vorsicht: Dieser Prozess setzt die Daten im System auf einen vorherigen Zeitpunkt zurück.
Wenn Sie vermeiden möchten, dass Änderungen in Ihrem System verloren gehen, können Sie stattdessen die Option Option B unten verwenden.
Gehen Sie wie folgt vor, um die Überprüfung und Wiederherstellung durchzuführen:
-
Laden Sie die Datei "
oak-run
jar"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, gehen Sie zum nächsten Abschnitt.)
-
Stellen 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 neueste gute Revision enthält.
Wenn Sie herausfinden möchten, zu welchem Datum und zu welcher Uhrzeit Sie das Repository wiederherstellen, führen Sie diesen Befehl im Ordner
segmentstore
aus (ersetzen Sie afdb922d-ba53-4a1b-aa1b-1cb044b535cf durch die neueste gute 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 der Installation in AEM übereinstimmt.
Laden Sie es 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.
*Vorsicht:*Die unten beschriebene Vorgehensweise ist für Power-User gedacht.
Beim Löschen der beschädigten Knoten müssen Sie sicherstellen, dass sie keine Systemknoten sind (z. B. /home
, /jcr:system
usw.).
Oder wenn es sich um Systemknoten handelt, müssen Sie sicherstellen, dass Sie diese wiederherstellen können.
Wenden Sie sich an 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 ist das Problem mit binären Eigenschaften verknüpft 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 alle identifizierten beschädigten Knoten, die in der Ausgabe des letzten Befehls mit
rmNodes.groovy
aufgeführt 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 beschädigte Knotenpfad der in Schritt 2 abgerufene Pfad ist, z. B.:
/content/dam/test.txt/jcr:content/renditions/original/jcr:content/
.
Hinweis: Legen Sie bei Verwendung vonoak-run.jar
Version 1.6.13 und höher den JVM-Parameter--read-write
fest, wenn ein Fehler wie folgt 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 diese drei gefundenen beschädigten Pfade gelöscht werden, indem Sie den Befehl
rmNode
auf diesen Pfaden erneut ausführen.Für die nächste Ausführung sollte
false
zurückgegeben werden.Wenn Sie immer noch sehen, dass dieselben Pfade im Repository vorhanden sind, 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 zum Server.
Das so komprimierte Repository sollte dann die oak-run-Prüfung, das Knotenzählungsskript, übergeben 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, finden Sie weitere Informationen unter Oak offline compaction instructions 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 Revisionsbereinigung verursacht wird (Ursache 2), stellen Sie sicher, dass die Online-Komprimierung deaktiviert ist, um zu verhindern, dass weitere Knoten beschädigt werden.