SegmentNotFoundException y IllegalArgumentException

Descripción

Entorno
Adobe Experience Manager

Problema

Escenario 1
La ejecución de una compactación sin conexión puede fallar con SegmentNotFoundException cuando hay problemas de integridad del repositorio.

Usted observa SegmentNotFoundException en AEM archivos de registro y AEM no funciona como se espera.

Escenario 2

La ejecución de una compactación sin conexión puede fallar con SegmentNotFoundException cuando hay problemas de integridad del repositorio.

En los registros se muestra un seguimiento de pila similar al que se muestra a continuación:

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

Escenario 3

La ejecución de una compactación sin conexión puede fallar con IllegalArgument Excepción cuando hay problemas de integridad del repositorio.

En los registros se muestra un seguimiento de pila similar al que se muestra a continuación:

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 cuando un segmento no está presente mientras la compactación intenta leer el nodo.
Puede haber diferentes causas básicas para esto:

  1. El segmento se ha eliminado mediante una intervención manual (por ejemplo: rm -rf /).
  2. El segmento se ha eliminado por la recolección de basura de revisiones.
  3. El segmento no se puede encontrar debido a algún error en el código.

En caso de que el problema sea causado por la colección de residuos de revisión (Causa #2), asegúrese de que la compactación en línea esté deshabilitada para evitar que otros nodos se dañen.

Resolución

Solución

Hay múltiples procedimientos que podemos seguir para resolver la situación y completar la compactación fuera de línea con éxito.

Importante: realice una copia de seguridad completa del repositorio antes de seguir estos pasos.

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

Puede usarse el modo de ejecución de comprobación de oak-run para determinar la última revisión buena 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 hará retroceder los datos del sistema a un momento anterior.
Si desea evitar perder los cambios en su sistema, puede intentar Opción B debajo en su lugar.

Para realizar la comprobación y restauración, siga estos pasos:

  1. Descargue el oak-run Archivo jar desde aquí https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/

  2. Detenga AEM.

  3. Ejecute este comando:

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

    Este comando busca hacia atrás en las revisiones hasta encontrar una consistente:

    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

    (En caso de que el ConsistencyChecker falle, vaya a la siguiente sección)

  4. Revierta el repositorio a esta revisión editándolo:

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

    Borre todas las líneas después de la línea que contiene la última revisión buena.

    Si desea saber a qué fecha y hora está revertiendo el repositorio, ejecute este comando en la segmentstore carpeta (reemplazar afdb922d-ba53-4a1b-aa1b-1cb044b535cf con la última corrección correcta en su journal.log):

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

    La salida le mostrará una fecha y hora aproximada de esa revisión.

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

  6. Si usa AEM6.0, descargue la versión oak-run que coincida con la instalada en AEM para los pasos restantes.

    Descárguelo desde aquí https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/.

  7. Ejecutar limpieza de los puntos de comprobación para eliminar los puntos de comprobación huérfanos:

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

  8. Finalmente, compacte el repositorio:

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

B. Elimine manualmente los nodos corruptos.

En las configuraciones de AEM, TarMK sin FileDatastore configurado y en situaciones en las que los binarios están dañados, puede hacer lo siguiente.

Precaución: el procedimiento que se describe a continuación está destinado a usuarios avanzados.
Al eliminar los nodos dañados, debe asegurarse de que no sean nodos del sistema (como /home, /jcr:system, etc.) .
O si son nodos del sistema, debe asegurarse de que pueda restaurarlos.
Consulte con el equipo de atención al cliente de AEM para que le ayuden con los pasos documentados aquí si no está seguro.

  1. Detenga AEM.

  2. Utilice la consola Oak run y cargue el childCount groovy script 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 da como resultado la siguiente salida que indica la ruta hacia el o los nodos corruptos:

    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 la variable childCount el script groovy no puede localizar ningún nodo dañado.

    En estos casos puede usar el siguiente comando en su lugar, que leerá los primeros 1024 bytes de cada binario encontrado durante el recorrido (tenga en cuenta que este comando será más lento y sólo debe usarse cuando el anterior no devuelva los resultados esperados):

    countNodes(session.workingNode,true)

  3. Elimine todos los nodos corruptos identificados en la lista de salida del último comando utilizando rmNodes.groovy.

    Cargue el shell de la consola oak-run:

    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 corrupto y sustituya /path/to/corrupt/node por la ruta del nodo corrupto que necesita 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: Al usar oak-run.jar versión 1.6.13 y posteriores, establezca --read-write Parámetro JVM si se encuentra con un error como:

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

    Este comando rmNode anterior debería devolver "true" para la ruta corrupta, lo que significa que la ha eliminado.

    Asegúrese de que estas tres rutas corruptas encontradas se hayan eliminado volviendo a ejecutar el comando rmNode en esas rutas.

    Para la siguiente ejecución debe devolver false.

    Si todavía ve que las mismas rutas están en el repositorio, entonces use la versión parcheada de oak-run jar (es decir, oak-run-1.2.18-NPR-17596).

    ¿Qué hace la versión parcheada de oak-run jar?

    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 así compactado debería pasar la comprobación oak-run, 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 Instrucciones de compactación sin conexión de Oak en GitHub Gist.

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

En esta página