Das Ausführen einer Offline-Verdichtung kann mit SegmentNotFoundException fehlschlagen, wenn es Integritätsprobleme des Repositorys gibt.

Problem

Das Ausführen einer Offline-Verdichtung kann mit SegmentNotFoundException fehlschlagen, wenn es Integritätsprobleme des Repositorys gibt. Eine Stapel-Trace, die der folgenden ähnelt, kann in den Protokollen gefunden werden:

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

Oder das Ausführen einer Offline-Verdichtung kann mit IllegalArgumentException fehlschlagen, wenn es Integritätsprobleme des Repositorys gibt. Eine Stapel-Trace, die der folgenden ähnelt, kann in den Protokollen gefunden werden:

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)

Umgebung

AEM 6.x

Ursache

Ein SegmentNotFoundException wird zurückgegeben, wenn ein Segment nicht vorhanden ist, während die Verdichtung versucht, den Knoten zu lesen. Dafür kann es verschiedene Grundursachen geben:

  1. Das Segment wurde manuell entfernt (z. B. rm -rf /).
  2. Das Segment wurde durch die Revisionsspeicherbereinigung entfernt. 
  3. Das Segment kann aufgrund eines Problems im Code nicht gefunden werden.

Wenn der Fehler durch die Revisionsspeicherbereinigung verursacht wurde (Punkt 2), vergewissern Sie sich, dass die Online-Verdichtung deaktiviert ist, um weitere Knoten vor Beschädigungen zu schützen.

Lösung

 

Es gibt mehrere Vorgehensweisen, die wir befolgen können, um die Situation zu beheben und die Offline-Verdichtung erfolgreich abzuschließen.

Wichtig: Führen Sie eine vollständige Sicherung des Repositorys durch, bevor Sie wie folgt vorgehen.

A. Stellen Sie die letzte gute Revision des Segmentstores wieder her.

Sie können den Prüfungsmodus von Oak-Run verwenden, um die letzte bekannte gute Revision eines Segmentstores zu ermitteln. Dies kann verwendet werden, um einen beschädigten Segmentstore manuell auf die letzte gute Revision zurückzusetzen.

Vorsicht:

Dieser Vorgang setzt die Daten im System auf einen vorherigen Zeitpunkt zurück.  Wenn Sie den Verlust von Änderungen in Ihrem System vermeiden möchten, können Sie stattdessen die folgende Option B versuchen.

Ausführen der Prüfung und Wiederherstellung:

  1. Laden Sie die Oak-Run JAR-Datei herunter: http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/

    • AEM 6.0: Wenn Sie Oak 1.0.12 oder höher benutzen, verwenden Sie Oak-Run 1.1.8 - oak-run-1.1.8.jar.  Wenn die Oak-Version 1.0.11 oder älter ist, verwenden Sie Oak-Run 1.1.6.
    • AEM 6.1: Laden Sie die Oak-Run-Version 1.2.x herunter, die der installierten entspricht (prüfen Sie per /system/console/bundles UI)

    Hinweis:

    Wir verwenden eine verzweigte 1.1.x-Version von Oak-Run, weil die 1.0.x-Verzweigung den „check“-Befehl nicht implementiert hat.

  2. AEM stoppen.

  3. Führen Sie folgenden Befehl aus:

    java -jar oak-run-*.jar check -d1 --bin=-1 -p crx-quickstart/repository/segmentstore/

    Dieser Befehl durchsucht die Revisionen rückwärts, bis eine einheitliche gefunden wird:

    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

    (Wenn ConsistencyChecker fehlschlägt, gehen Sie zum nächsten Abschnitt)

  4. Setzen Sie das Repository auf diese Revision zurück, indem Sie.

    /crx-quickstart/repository/segmentstore/journal.log

    Löschen Sie alle Zeilen nach derjenigen, die die aktuellste guten Revision enthält. Wenn Sie herausfinden möchten, zu welchem Datum und Uhrzeit Sie die Repository zurücksetzen, führen Sie den folgenden Befehl im Segmentstore-Ordner aus (ersetzen Sie afdb922d-ba53-4a1b-aa1b-1cb044b535cf mit der letzten guten Revision in Ihrem journal.log):

    find . -type f -name "data*.tar" -exec sh -c "tar -tvf {} |grep afdb922d-ba53-4a1b-aa1b-1cb044b535cf" \; -print

    Die Ausgabe zeigt Ihnen das ungefähre Datum und die Uhrzeit dieser Revision an.

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

  6. Bei AEM 6.0 laden Sie die Oak-Run-Version herunter, die mit dem übereinstimmt, was in AEM für die restlichen Schritte installiert ist.  Laden Sie ihn hier herunter http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/.

  7. Führen Sie ein Clean-up für Checkpoints aus, um verwaiste Checkpoints zu entfernen:

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

  8. Komprimieren Sie zuletzt das Repository:

    java -jar oak-run-*.jar compact ./crx-quickstart/repository/segmentstore/

B. Manuelles Entfernen von beschädigten Knoten.

In AEM, TarMK-Einrichtungen ohne konfigurierten FileDatastore und in Situationen, bei denen eine Beschädigung in den Binärdateien auftritt, tun Sie Folgendes:

Vorsicht:

Das nachfolgende Verfahren ist für Hauptbenutzer vorgesehen.  Beim Löschen der beschädigten Knoten müssen Sie sicherstellen, dass sie keine Systemknoten sind (z. B. /home, /jcr:system usw.).  Oder wenn sie Systemknoten sind, müssen Sie sicherstellen, dass sie wiederhergestellt werden können.  Wenden Sie sich an das AEM Kundenbetreuungsteam, um Hilfe zu den hier beschriebenen Schritten zu erhalten, wenn Sie nicht sicher sind.

  1. AEM stoppen.

  2. Verwenden Sie die Konsole und laden Sie das childCount groovy-Skript, um die beschädigten Knoten im Segmentstore zu identifizieren:

    Laden Sie die Oak-Run Konsolen-Shell:

    java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore

    Führen Sie die folgenden beiden nachfolgenden 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 resultiert in folgender Ausgabe, die den Pfad zu 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 childCount groovy-Skript kann keine beschädigten Knoten finden.  In diesen Fällen können Sie den folgenden Befehl, der die ersten 1024 Byte für jede Binärdatei bei der Untersuchung liest, stattdessen verwenden (beachten Sie, dass dieser Befehl langsamer ist und nur verwendet werden sollte, wenn der oben angegebene nicht die erwarteten Ergebnisse zurückgibt):

    countNodes(session.workingNode,true)

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

    Laden Sie die Oak-Run Konsolen-Shell:

    java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore

    Laden Sie das Groovy-Skript:

    :load https://gist.githubusercontent.com/stillalex/43c49af065e3dd1fd5bf/raw/9e726a59f75b46e7b474f7ac763b0888d5a3f0c3/rmNode.groovy

    Führen Sie den rmNode-Befehl aus, um den beschädigten Knoten zu entfernen, ersetzen Sie /path/to/corrupt/node durch den Pfad zum beschädigten Knoten, den Sie entfernen sollen.

    rmNode(session, "/path/to/corrupt/node")

    Wobei der beschädigte Knotenpfad der Pfad ist, der in Schritt 2 abgerufen wurde, z. B.: „/content/dam/test.txt/jcr:content/renditions/original/jcr:content/“

  4. Wiederholen Sie Schritt 3 für alle Knoten, die in Schritt 2 gefunden wurden.

    Dieser oben angeführte rmNode-Befehl sollte für den beschädigten Pfad positiv zurückkommen, was bedeutet, dass er ihn gelöscht hat. Stellen Sie sicher, dass Sie diese drei gefundenen beschädigten Pfade löschen, indem Sie den rmNode-Befehl an ihnen wieder anwenden. Bei der nächsten Ausführung sollte er negativ zurückkommen.

    Wenn Sie weiterhin sehen, dass dieselben Pfade im Repository vorhanden sind, verwenden Sie die gepatchte Version der Oak-Run JAR-Datei, d. h. Oak-Run-1.2.18-NPR-17596

    Was tut die gepatchte Version der Oak-Run JAR-Datei?

    Diese Version der JAR-Datei überspringt unlesbare Binärdateien bei der Komprimierung, ersetzt sie mit 0-Byte-Binärdateien und protokolliert die Ausnahme und den Pfad zu Syserr. Das dadurch komprimierte Repository sollte dann die Oak-Run-Überprüfung und das Knotenzählungsskript bestehen, wonach Sie in der Lage sein sollten, es mithilfe eines nicht gepatchten Oak-Runs erneut zu komprimieren.

  5. Führen Sie eine Checkpoint-Bereinigung durch, indem Sie die Checkpoints mithilfe des Folgenden auflisten. Wenn mehr als ein Checkpoint vorhanden ist, bereinigen Sie sie:

    nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-all>>nohup.out &

  6. Entfernen Sie asynchrone Knoten [Dieser Schritt ist optional. Verwenden Sie ihn nur, wenn es notwendig ist, eine vollständige Neuindizierung auszuführen]:

    java -Xmx4096m -jar oak-run-1.2.18.jar console /app/AEM6/author/crx-quickstart/repository/segmentstore


    :load https://gist.githubusercontent.com/stillalex/43c49af065e3dd1fd5bf/raw/9e726a59f75b46e7b474f7ac763b0888d5a3f0c3/rmNode.groovy

    rmNode(session, "/:async")

  7. Starten Sie den Server und warten Sie auf die Fertigstellung der Indizierung.

  8. AEM stoppen.

  9. Führen Sie die Offline-Komprimierung aus.

Dieses Werk unterliegt den Bedingungen der Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.  Twitter™- und Facebook-Beiträge fallen nicht unter die Bedingungen der Creative Commons-Lizenz.

Rechtliche Hinweise   |   Online-Datenschutzrichtlinie