Problema
Il registro degli errori mostra un'eccezione SegmentNotFound, ad esempio nell'esempio seguente:
org.apache.jackrabbit.oak.segment.SegmentNotFoundException: Segment d2c720c4-c146-4ab1-ac37-542aad93c33f not found at org.apache.jackrabbit.oak.segment.file.FileStore$8.call(FileStore.java:602) at org.apache.jackrabbit.oak.segment.file.FileStore$8.call(FileStore.java:542) at org.apache.jackrabbit.oak.segment.SegmentCache.getSegment(SegmentCache.java:95) at org.apache.jackrabbit.oak.segment.file.FileStore.readSegment(FileStore.java:542) at org.apache.jackrabbit.oak.segment.SegmentId.getSegment(SegmentId.java:125) at org.apache.jackrabbit.oak.segment.Record.getSegment(Record.java:70) at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:424) at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:433) at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:391) at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:608) at org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148) at org.apache.jackrabbit.oak.segment.MapRecord$3.childNodeChanged(MapRecord.java:442) at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:490) at org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:433) at org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:608) at org.apache.jackrabbit.oak.spi.commit.EditorDiff.process(EditorDiff.java:52) at org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.updateIndex(AsyncIndexUpdate.java:695) at org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.runWhenPermitted(AsyncIndexUpdate.java:543) at org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.run(AsyncIndexUpdate.java:402) at org.apache.sling.commons.scheduler.impl.QuartzJobExecutor.execute(QuartzJobExecutor.java:118) at org.quartz.core.JobRunShell.run(JobRunShell.java:202) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
Ambiente
Adobe Experience Manager 6.x
Causa
Un SegmentNotFoundException nel log degli errori significa che un segmento non è più presente anche se qualcuno sembra cercare di accedervi ancora. Le cause principali sono sostanzialmente tre: il segmento è stato rimosso con un intervento manuale (ad esempio rm -rf /), il segmento è stato rimosso con la revisione della raccolta degli oggetti inattivi o il segmento non può essere trovato a causa di qualche bug nel codice.
Passaggi per la risoluzione
Esistono due approcci per risolvere il problema e rimuovere le incongruenze nell’archivio
Ripristinare l’ultima revisione valida nota dell’archivio segmenti.
Innanzitutto, utilizza lo strumento oak run, che è un jar1 eseguibile che contiene tutto il necessario per una semplice installazione Oak e l'esecuzione di operazioni relative a oak.
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 riporta i dati nel sistema a un punto precedente. Se vuoi evitare di perdere le modifiche nel sistema, puoi provare l’opzione B riportata di seguito.
Per eseguire il controllo e il ripristino:
Scarica una versione di oak-run che corrisponde alla versione principale di oak attualmente in uso da https://mvnrepository.com/artifact/org.apache.jackrabbit/oak-run
Per ripristinare l’ultimo buono stato di un archivio di segmenti corrotto, passa alla directory di lavoro di CQ (quella contenente la cartella crx-quickstart) ed esegui il backup di tutti i file in ./crx-quickstart/repository/segmentstore/.
Esegui il controllo di coerenza, java -Xmx6000m -jar oak-run-*.jar check —bin=-1 /path/to/crx-quickstart/repository/segmentstore Questa ricerca indietro attraverso le revisioni fino a che non ne trova una coerente: Cerca un messaggio come quello che segue:
main INFO o.a.j.o.p.s.f.t.ConsistencyChecker - Found latest good revision afdb922d-ba53-4a1b-aa1b-1cb044b535cf:234880
Ripristina l’archivio a questa revisione modificando/crx-quickstart/repository/segmentstore/journal.log ed eliminazione di tutte le righe dopo la riga contenente l'ultima revisione valida.
Rimuovi tutto ./crx-quickstart/repository/segmentstore/*.bak file.
Esegui la pulizia dei checkpoint per rimuovere i checkpoint orfani utilizzando il seguente comando:
java -Xmx6000m -jar oak-run-*.jar checkpoints /path/to/crx-quickstart/repository/segmentstore rm-unreferenced
Infine, compatta l’archivio:
java -Xmx6000m -jar oak-run-*.jar compact /path/to/crx-quickstart/repository/segmentstore/
Ci possono essere casi in cui il controllo oak run non riesce a trovare la revisione buona, e otteniamo "ConsistencyChecker - Non è stata trovata una buona revisione" durante l'esecuzione del comando check.
Come correggere la corruzione quando si incontra "ConsistencyChecker - Non è stata trovata una buona revisione" sul controllo di coerenza
Rimuovere manualmente i nodi danneggiati.
È possibile effettuare le seguenti operazioni nelle impostazioni AEM, TarMK senza FileDatastore configurato e nelle situazioni in cui la corruzione si trova nei binari.
Attenzione: La procedura seguente è destinata agli utenti avanzati. Quando si eliminano i nodi corrotti, è necessario assicurarsi che non siano nodi di sistema (come /home, /jcr:system, ecc.) . Se si tratta di nodi di sistema, è necessario assicurarsi di poterli ripristinare. Se non sei sicuro, consulta il team di assistenza clienti AEM per assistenza sui passaggi qui documentati.
Interrompi AEM.
Utilizza la console di esecuzione Oak e carica lo script childCount 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)
Questo si traduce nel seguente output 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 groovy childCount non può 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)
Rimuovi tutti i nodi danneggiati identificati elencati nell'output dell'ultimo comando utilizzando rmNodes.groovy Carica la shell della console oak-run utilizzando il seguente comando:
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, sostituisci /path/to/corrotto/node con il percorso del nodo corrotto che devi 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, imposta il parametro JVM —read-write se si verifica un errore come:
/ 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)
Ripeti il passaggio 3 per tutti i nodi individuati nel passaggio 2
Questo comando rmNode di cui sopra deve restituire true per il percorso corrotto, il che significa che lo ha eliminato. Assicurati che questi tre percorsi corrotti trovati vengano eliminati eseguendo nuovamente il comando rmNode su quei percorsi. L’esecuzione successiva deve restituire false.
Se vedi che gli stessi percorsi sono ancora presenti nell’archivio, utilizza la versione patched del jar oak-run, cioè oak-run-1.2.18-NPR-17596. 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 compatto risultante dovrebbe quindi passare il controllo oak-run e lo script di conteggio dei nodi, e dovresti anche essere in grado di compattarlo di nuovo utilizzando un oak-run non patched.
Esegui una pulizia dei punti di controllo elencandoli tramite il comando seguente. Se sono presenti più punti di controllo, puliscili:
nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-allnohup.out &
Esegui una compattazione offline. Se non sai come eseguire la compattazione offline, vedi qui.
Avvia il server e attendi il completamento dell’indicizzazione.