SegmentNotFoundException e IllegalArgumentException

Descrizione

Ambiente
Adobe Experience Manager

Problema

Scenario 1
L'esecuzione di una compattazione offline può non riuscire con SegmentNotFoundException in caso di problemi di integrità dell’archivio.

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

Scenario 2

L'esecuzione di una compattazione offline può non riuscire con SegmentNotFoundException in caso di problemi di integrità dell’archivio.

Una traccia di stack simile a quella riportata di seguito viene mostrata nei registri:

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ò non riuscire con IllegalArgument Eccezione in caso di problemi di integrità dell’archivio.

Una traccia di stack simile a quella riportata di seguito viene mostrata nei registri:

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)

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 revisione della raccolta degli oggetti inattivi (Causa n. 2), assicurati che la compattazione online sia disabilitata per evitare che altri nodi vengano danneggiati.

Risoluzione

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

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

  1. Scarica la 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.

    Se desideri sapere in che data e ora stai ripristinando l'archivio, esegui questo comando nella segmentstore cartella (sostituire afdb922d-ba53-4a1b-aa1b-1cb044b535cf con l'ultima buona revisione 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 in AEM per i passaggi rimanenti.

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

  7. Esegui pulizia dei checkpoint per rimuovere i checkpoint 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.) .
Se si tratta di nodi di sistema, è necessario assicurarsi di poterli ripristinare.
In caso di dubbi, rivolgiti al team di assistenza clienti AEM per ricevere supporto in merito ai passaggi documentati in questa sezione.

  1. Interrompi AEM.

  2. Usa la console di esecuzione di Oak e carica il childCount script groovy per identificare i nodi corrotti 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 alla childCount impossibile individuare nodi danneggiati.

    In questi casi è possibile utilizzare il seguente comando che leggerà i primi 1024 byte per ogni binario rilevato durante l'attraversamento (Nota che questo comando sarà più lento e dovrebbe essere utilizzato solo quando quello sopra non restituisce i risultati previsti):

    countNodes(session.workingNode,true)

  3. Rimuovi tutti i nodi danneggiati identificati che sono 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 al passaggio 2, ad esempio: /content/dam/test.txt/jcr:content/renditions/original/jcr:content/. Nota: Quando utilizzi oak-run.jar versione 1.6.13 e successive, set --read-write Parametro JVM se si verifica un errore come:

    / 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. 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 di essi.

    Per la prossima esecuzione dovrebbe restituire false.

    Se vedi ancora che gli stessi percorsi sono presenti nell'archivio, utilizza la versione patched del jar oak-run (cioè oak-run-1.2.18-NPR-17596).

    Cosa fa la versione patched del jar oak-run?

    Questa versione di jar salta i binari illeggibili sulla compattazione, sostituendoli con binari a 0 byte e registrando l'eccezione e il percorso di syserr.

    L'archivio così compatto dovrebbe quindi passare oak-run check, lo script di conteggio dei nodi e dovresti anche essere in grado di compattarlo di nuovo utilizzando un oak-run non patched.

  5. Esegui una pulizia dei punti di controllo elencandoli tramite il comando seguente.

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

  6. Esegui una compattazione offline.

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

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

In questa pagina