SegmentNotFoundException und IllegalArgumentException

Beschreibung

Umgebung
Adobe Experience Manager

Problem

Szenario 1
Das Ausführen einer Offline-Verdichtung kann mit SegmentNotFoundException wenn Integritätsprobleme des Repositorys auftreten.

Sie beobachten SegmentNotFoundException in AEM Protokolldateien und AEM funktioniert nicht erwartungsgemäß.

Szenario 2

Das Ausführen einer Offline-Verdichtung kann mit SegmentNotFoundException 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-40a4e519fe8a. Creation date delta is 4 ms.
org.apache.jackrabbit.oak.plugins.segment.SegmentNotFoundException: Segment 4d139bc4-150c-4f0a-b82a-40a4e519fe8a 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-40a4e519fe8a 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 IllegalArgument Ausnahme bei Integritätsproblemen des Repositorys.

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)

Ursache

A 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:

  1. Das Segment wurde durch manuelles Eingreifen entfernt (z. B.: rm -rf /).
  2. Das Segment wurde durch die Revisionsdatenbereinigung entfernt.
  3. 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-Verdichtung deaktiviert ist. um zu vermeiden, dass weitere Knoten beschädigt werden.

Lösung

Lösung

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.

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 Option B unten.

Gehen Sie wie folgt vor, um die Überprüfung und Wiederherstellung durchzuführen:

  1. Laden Sie die oak-run JAR-Datei von hier https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/

  2. Beenden Sie AEM.

  3. 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.)

  4. Stellen Sie das Repository auf diese Revision zurück, indem Sie es 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, zu welchem Datum und zu welcher Uhrzeit Sie das Repository wiederherstellen, führen Sie diesen Befehl im segmentstore folder (replace afdb922d-ba53-4a1b-aa1b-1cb044b535cf mit der neuesten guten Revision in Ihrer journal.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.

  5. Entfernen Sie alle ./crx-quickstart/repository/segmentstore/*.bak files..

  6. Wenn Sie AEM6.0 verwenden, laden Sie die Oak-Run-Version herunter, die mit dem übereinstimmt, was in AEM für die restlichen Schritte installiert ist.

    Herunterladen von hier https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/.

  7. Ausführen Checkpoint-Bereinigung um verwaiste Checkpoints zu entfernen:

    java -jar oak-run-*.jar checkpoints ./crx-quickstart/repository/segmentstore rm-unreferenced

  8. 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.
Beim Löschen der beschädigten Knoten müssen Sie sicherstellen, dass es sich nicht um Systemknoten handelt (z. B. /home, /jcr:systemusw.).
Oder wenn es sich um Systemknoten handelt, müssen Sie sicherstellen, dass Sie diese wiederherstellen können.
Wenden Sie sich an Ihr AEM-Kundenunterstützungs-Team, um Unterstützung bei den hier beschriebenen Schritten zu erhalten, wenn Sie sich nicht sicher sind.

  1. Beenden Sie AEM.

  2. Verwenden Sie die Oak-Ausführungskonsole und laden Sie die childCount Erstellen Sie ein Skript, 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 und der childCount groovy -Skript 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 liefert):

    countNodes(session.workingNode,true)

  3. Entfernen Sie alle identifizierten beschädigten Knoten, die in der Ausgabe des letzten Befehls mit rmNodes.groovy.

    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: Bei Verwendung von oak-run.jar Version 1.6.13 und höher, festlegen --read-write JVM-Parameter , wenn ein Fehler wie folgt auftritt:

    / rmNode(session,"/path/to/corrupt/node")Removing node /path/to/corrupt/nodeERROR java.lang.UnsupportedOperationException:Cannot write to read-only storeat 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)
    
  4. 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 Befehl rmNode für diese Pfade erneut ausführen.

    Für die nächste Ausführung sollte sie zurückgegeben werden false.

    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.

  5. 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-allnohup.out &

  6. Führen Sie eine Offline-Komprimierung aus.

    Wenn Sie nicht wissen, wie Sie die Offline-Verdichtung ausführen, lesen Sie Oak-Offline-Verdichtungsanweisungen auf GitHub Gist.

  7. Starten Sie den Server und warten Sie auf den Abschluss der Indizierung.

Auf dieser Seite