Cómo depurar SegmentNotFoundException cuando se informa de un problema en AEM 6.x

Descripción


Problema


El registro de errores muestra una excepción SegmentNotFound como en el siguiente ejemplo:

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)



Entorno


Adobe Experience Manager 6.x

Resolución

Causa

Un SegmentNotFoundException en el registro de errores significa que un segmento ya no está presente aunque alguien aparentemente intente acceder a él. Existen tres causas básicas para esto: el segmento se ha eliminado mediante una intervención manual (por ejemplo, rm -rf /), el segmento se ha eliminado mediante la colección de residuos de revisión o el segmento no se puede encontrar debido a algún error en el código.

Pasos que se deben resolver

Existen dos métodos para solucionar el problema y eliminar las incoherencias en el repositorio

Vuelva a la última revisión buena conocida del almacén de segmentos.

En primer lugar, utilice la herramienta oak run, que es un jar1 que se puede ejecutar y que contiene todo lo necesario para una instalación simple de Oak y para realizar operaciones relacionadas con Oak.

El modo de ejecución de la comprobación de oak-run puede utilizarse para determinar la última corrección correcta conocida de un almacén de segmentos.  Eso puede usarse para revertir manualmente un almacén de segmentos corrupto a su última revisión buena.

Precaución: Este proceso restaurará los datos del sistema a un punto anterior en el tiempo.  Si desea evitar la pérdida de cambios en su sistema, puede probar la opción B que aparece a continuación.

Para realizar la comprobación y restauración:

  1. Descargue una versión de oak-run que coincida con su versión del núcleo de Oak desde https://mvnrepository.com/artifact/org.apache.jackrabbit/oak-run

  2. Para revertir un almacén de segmentos dañado a su estado correcto más reciente, cambie al directorio de trabajo de CQ (el que contiene la carpeta crx-quickstartfolder) y haga una copia de seguridad de todos los archivos en ./crx-quickstart/repository/segmentstore/.

  3. Ejecute la comprobación de consistencia, java -Xmx6000m -jar oak-run-*.jar check —bin=-1 /path/to/crx-quickstart/repository/segmentstore Esto busca hacia atrás en las revisiones hasta encontrar una consistente: Busque un mensaje como el siguiente:

    main INFO o.a.j.o.p.s.f.t.ConsistencyChecker - Found latest good revision afdb922d-ba53-4a1b-aa1b-1cb044b535cf:234880
    
  4. Revierta el repositorio a esta revisión editándolo ./crx-quickstart/repository/segmentstore/journal.log y borrar todas las líneas después de la línea que contiene la última corrección correcta.

  5. Eliminar todo .archivos /crx-quickstart/repository/segmentstore/*.bak.

  6. Ejecute la limpieza de los puntos de comprobación para eliminar los puntos de comprobación huérfanos mediante el siguiente comando:

    java -Xmx6000m -jar oak-run-*.jar checkpoints /path/to/crx-quickstart/repository/segmentstore rm-unreferenced
    
  7. Finalmente, compacte el repositorio:

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

Puede haber casos en los que la comprobación de ejecución de oak no encuentra la corrección correcta y obtenemos "ConsistencyChecker - No se encontró una corrección correcta" mientras se ejecuta el comando check.
Corregir la corrupción al encontrar "ConsistencyChecker - No se encontró una corrección correcta" en la verificación de consistencia
Elimine manualmente los nodos dañados.

Puede hacer lo siguiente en AEM, configuraciones de TarMK sin FileDatastore configurado y situaciones en las que la corrupción está en los binarios.

Precaución: El siguiente procedimiento está pensado para usuarios avanzados.  Al eliminar los nodos dañados, debe asegurarse de que no sean nodos del sistema (como /home, /jcr:system, etc.).  Si son nodos del sistema, debe asegurarse de que puede restaurarlos.  Consulte con el equipo de atención al cliente de AEM para obtener ayuda con los pasos documentados aquí si no está seguro.

  1. Detenga AEM.

  2. Utilice la consola Oak run y cargue el script groovy childCount para identificar los nodos dañados en el almacén de segmentos:

    Cargue el shell de la consola oak-run:

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

    Ejecute los dos comandos siguientes en el shell para cargar el script y ejecutarlo:

    :load https://gist.githubusercontent.com/stillalex/e7067bcb86c89bef66c8/raw/d7a5a9b839c3bb0ae5840252022f871fd38374d3/childCount.groovy
    
    countNodes(session.workingNode)
    

    Esto resulta en la siguiente salida que indica la ruta a los nodos dañados:

    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
    

    En algunos casos, el problema está vinculado a propiedades binarias y el script groovy childCount no puede localizar ningún nodo dañado.  En estos casos, puede utilizar el siguiente comando, que leerá los primeros 1024 bytes de cada binario encontrado durante la travesía (tenga en cuenta que este comando será más lento y solo debe utilizarse cuando el anterior no devuelva los resultados esperados):

    countNodes(session.workingNode,true)
    
  3. Elimine todos los nodos dañados identificados que aparecen en la salida del último comando utilizando rmNodes.groovy Cargue el shell de la consola oak-run utilizando el siguiente comando:

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

    Cargue el script groovy:

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

    Ejecute el comando rmNode para eliminar el nodo dañado, reemplace /path/to/corruptor/node por la ruta al nodo dañado que debe eliminar.

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

    donde la ruta del nodo dañado es la ruta obtenida en el paso 2, por ejemplo: "/content/dam/test.txt/jcr:content/renditions/original/jcr:content/"

    Nota: Cuando utilice oak-run.jar versión 1.6.13 y superiores, establezca el parámetro —read-write JVM si se encuentra con un error como:

    / 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. Repita el paso 3 para todos los nodos encontrados en el paso 2

    Este comando rmNode de arriba debería devolver true para la ruta dañada, lo que significa que la eliminó. Asegúrese de que estas tres rutas dañadas se eliminen ejecutando de nuevo el comando rmNode en esas rutas. La siguiente ejecución debería devolver "false".
    Si ve que las mismas rutas aún están allí en el repositorio, use la variable versión parcheada de oak-run jar, es decir, oak-run-1.2.18-NPR-17596. Esta versión de jar omite binarios ilegibles en la compactación, reemplazándolos por binarios de 0 bytes y registrando la excepción y la ruta al syserr. El repositorio compactado resultante debería pasar la comprobación oak-run, y el script de recuento de nodos, y también debería ser capaz de compactarlo de nuevo usando un oak-run no parcheado.

  5. Realice una limpieza de puntos de comprobación enumerando los siguientes puntos. Si hay más de un punto de comprobación, límpielos:

    nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-allnohup.out &
    
  6. Ejecute una compactación fuera de línea.  Si no sabe cómo ejecutar la compactación sin conexión, consulte here.

  7. Inicie el servidor y espere a que se complete la indexación.

En esta página