SegmentNotFoundException e IllegalArgumentException

L'esecuzione di una compattazione offline può avere esito negativo con SegmentNotFoundException o IllegalArgumentException. Questo articolo illustra come risolvere gli errori e completare correttamente la compattazione offline. Tuttavia, prima di continuare, esegui un backup completo dell’archivio.

Descrizione description

Ambiente

Adobe Experience Manager (AEM)

Problema

Scenario 1
L'esecuzione di una compattazione offline può non riuscire con SegmentNotFoundException quando si verificano problemi di integrità dell'archivio.

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

Scenario 3

L'esecuzione di una compattazione offline può non riuscire con IllegalArgument Exception quando si verificano 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

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 l'opzione B di seguito.

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

  1. Scarica il file jar oak-run 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, eseguire questo comando nella cartella segmentstore (sostituire afdb922d-ba53-4a1b-aa1b-1cb044b535cf con l'ultima revisione valida in 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 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. Utilizzare la console di esecuzione di Oak e caricare lo script di Groovy childCount 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 lo script di Groovy childCount 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. Rimuovere tutti i nodi danneggiati identificati elencati nell'output dell'ultimo comando utilizzando 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 utilizzi oak-run.jar versione 1.6.13 e successive, imposta il parametro JVM --read-write se riscontri 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.

    Assicurarsi che i 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  (ovvero 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 le istruzioni di compattazione offline di Oak su GitHub Gist.

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

Causa
Viene restituita un'eccezione SegmentNotFoundException 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