SegmentNotFoundException e IllegalArgumentException

Descrizione description

Ambiente
Experience Manager

Problema/Sintomi

Scenario 1
L’esecuzione di una compattazione offline può avere esito negativo con  SegmentNotFoundException quando si verificano problemi di integrità dell’archivio.

Osserva  SegmentNotFoundException nei file di registro dell’AEM e l’AEM non funziona come previsto.

Scenario 2

L’esecuzione di una compattazione offline può avere esito negativo con  SegmentNotFoundException quando si verificano problemi di integrità dell’archivio.

Nei registri viene visualizzata una traccia dello stack simile a quella riportata di seguito:

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

Scenario 3

L’esecuzione di una compattazione offline può avere esito negativo con  IllegalArgument Eccezione in caso di problemi di integrità dell’archivio.

Nei registri viene visualizzata una traccia dello stack simile a quella riportata di seguito:

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)

Risoluzione resolution

Soluzione

Per risolvere questo problema e completare con successo la compattazione offline puoi seguire diverse procedure.

Importante:  esegui un backup completo dell’archivio prima di seguire questi passaggi.

A. Ripristinare l’ultima revisione valida nota dell’archivio segmenti.

La modalità di esecuzione del controllo di oak-run può essere utilizzata per determinare l’ultima revisione valida nota di un archivio segmenti.
Questa procedura può essere utilizzata per ripristinare manualmente un archivio segmenti corrotto alla sua ultima revisione valida.

Attenzione: Questo processo consente di eseguire il rollback dei dati del sistema a un momento precedente.
Se desideri evitare di perdere le modifiche nel sistema, puoi provare Opzione B di seguito.

Per eseguire il controllo e il ripristino, effettuare le seguenti operazioni:

  1. Scarica il file oak-run file jar da qui https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/

  2. Interrompi AEM.

  3. Esegui questo comando:

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

    Questo comando esegue una ricerca all’indietro attraverso le revisioni fino a trovarne una coerente:

    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

    In caso di errore di ConsistencyChecker, passa alla sezione successiva.

  4. Ripristina l’archivio a questa revisione modificando:

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

    Elimina tutte le righe successive a quella contenente l’ultima revisione valida.

    Per conoscere la data e l’ora del ripristino dell’archivio, esegui questo comando in segmentstore cartella (replace afdb922d-ba53-4a1b-aa1b-1cb044b535cf  con l’ultima revisione valida nel tuo journal.log):

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

    L’output mostra la data e l’ora approssimativa della revisione.

  5. Rimuovi tutto ./crx-quickstart/repository/segmentstore/*.bak files.

  6. Se utilizzi AEM 6.0, scarica la versione oak-run corrispondente a quella installata nell’AEM per i passaggi rimanenti.

    Scaricala da qui https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/.

  7. Esegui pulizia del punto di controllo per rimuovere i punti di controllo orfani:

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

  8. Infine, compatta l’archivio:

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

B. Rimuovere manualmente i nodi danneggiati.

In AEM, quando FileDatastore non è configurato nelle impostazioni di TarMK e quando i file binari sono danneggiati, puoi effettuare le seguenti operazioni.

*Attenzione:*La procedura seguente è destinata agli utenti esperti.
Quando si eliminano i nodi corrotti è necessario assicurarsi che non siano nodi di sistema (ad esempio /home, /jcr:system, ecc.).
In alternativa, se si tratta di nodi di sistema, è necessario assicurarsi di poterli ripristinare.
In caso di dubbi, rivolgiti al team di assistenza clienti dell’AEM per ricevere assistenza sui passaggi documentati in questa sezione.

  1. Interrompi AEM.

  2. Utilizza la console Oak run e carica il childCount script di groovy per identificare i nodi danneggiati nell’archivio segmenti:

    Carica la shell della console Oak run:

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

    Esegui i due comandi seguenti nella shell per caricare lo script ed eseguirlo:

    :load

    https://gist.githubusercontent.com/stillalex/e7067bcb86c89bef66c8/raw/d7a5a9b839c3bb0ae5840252022f871fd38374d3/childCount.groovy

    countNodes(session.workingNode)

    Viene restituito l’output seguente che indica il percorso dei nodi danneggiati:

    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 alcuni casi il problema è collegato a proprietà binarie e childCount lo script di groovy non è in grado di individuare nodi danneggiati.

    In questi casi è possibile utilizzare il comando seguente che consente di leggere i primi 1024 byte per ogni file binario rilevato durante l'attraversamento. Si noti che questo comando sarà più lento e deve essere utilizzato solo quando il comando precedente non restituisce i risultati previsti:

    countNodes(session.workingNode,true)

  3. Rimuovi tutti i nodi danneggiati identificati elencati nell’output dell’ultimo comando tramite rmNodes.groovy.

    Carica la shell della console Oak run:

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

    Carica lo script di Groovy:

    :load

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

    Esegui il comando rmNode per rimuovere il nodo corrotto e sostituisci /path/to/corrupt/node con il percorso del nodo corrotto da rimuovere.

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

    Dove il percorso del nodo corrotto è il percorso ottenuto nel passaggio 2, ad esempio: /content/dam/test.txt/jcr:content/renditions/original/jcr:content/.
    Nota: quando si utilizza oak-run.jar versione 1.6.13 e successive, set --read-write Parametro JVM se si verifica un errore, ad esempio:

    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)
    
  4. Ripeti il passaggio 3 per tutti i nodi individuati nel passaggio 2.

    Il comando rmNode di cui sopra deve restituire true per il percorso corrotto, che indica la corretta eliminazione.

    Assicurati che questi tre percorsi danneggiati vengano eliminati eseguendo nuovamente il comando rmNode su tali percorsi.

    Per l’esecuzione successiva dovrebbe restituire false.

    Se questi percorsi sono ancora presenti nell’archivio, utilizza la versione aggiornata del file jar oak-run (ad esempio  oak-run-1.2.18-NPR-17596).

    Quali operazioni esegue la versione aggiornata del file jar oak-run?

    Questa versione del file jar ignora i file binari illeggibili durante la compattazione, sostituendoli con binari a 0 byte e registrando l’eccezione e il percorso di syserr.

    L’archivio così compattato dovrebbe quindi passare il controllo oak-run, lo script di conteggio dei nodi e dovresti anche essere in grado di compattarlo di nuovo utilizzando un oak-run non aggiornato.

  5. Esegui una pulizia dei punti di controllo elencandoli utilizzando quanto riportato di seguito.

    Se sono presenti più punti di controllo, effettua la pulizia:

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

  6. Esegui una compattazione offline.

    Se non sai come eseguire la compattazione offline, consulta Istruzioni per la compattazione offline Oak su GitHub Gist.

  7. Avvia il server e attendi il completamento dell’indicizzazione.

Causa
A SegmentNotFoundException viene restituito quando un segmento non è presente mentre la compattazione tenta di leggere il nodo.

Le cause principali possono essere diverse:

  1. Il segmento è stato rimosso con un intervento manuale (ad esempio: rm -rf /).
  2. Il segmento è stato rimosso mediante la raccolta di oggetti inattivi di revisione.
  3. Non è possibile trovare il segmento a causa di un bug nel codice.

Nel caso in cui il problema sia causato dalla raccolta di oggetti inattivi di revisione (Causa #2), assicurarsi che la compattazione online sia disabilitata per evitare il danneggiamento di altri nodi.

recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f