Comment déboguer SegmentNotFoundException lorsque le problème est signalé dans AEM 6.x

Cet article vous aide à comprendre comment déboguer SegmentNotFoundException lorsque le problème est signalé dans AEM 6.x en revenant à la dernière bonne révision connue du magasin de segments.

Description description

Environnement

Experience Manager 6.x

Problème/Symptômes

Le journal des erreurs affiche une exception SegmentNotFound, comme dans l’exemple suivant :

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)

Résolution resolution

Étapes à résoudre

Il existe deux méthodes pour résoudre le problème et supprimer les incohérences dans le référentiel.

Revenir à la dernière révision connue de l’entrepôt de segments.

Tout d’abord,  utilisez l’outil oak run, qui est un jar exécutable [ 1] qui contient tout ce dont vous avez besoin pour une installation Oak simple et effectuer des opérations liées à oak.

Le mode d’exécution de la vérification de oak-run peut être utilisé pour déterminer la dernière bonne révision connue d’un magasin de segments.  Cela peut être utilisé pour rétablir manuellement un magasin de segments corrompu à sa dernière bonne révision.

Attention : ce processus restaurera les données du système à un point antérieur dans le temps.  Si vous souhaitez éviter de perdre des modifications dans votre système, vous pouvez essayer l'option B ci-dessous à la place.

Pour effectuer la vérification et la restauration :

  1. Téléchargez une version de oak-run correspondant à votre version oak principale depuis https://mvnrepository.com/artifact/org.apache.jackrabbit/oak-run.

  2. Pour rétablir le dernier bon état d’un magasin de segments corrompu, accédez au répertoire de travail de CQ (celui contenant le dossier crx-quickstart) et sauvegardez tous les fichiers dans ./crx-quickstart/repository/segmentstore/.

  3. Effectuez la vérification de cohérence.

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

    Cette vérification effectue une recherche vers le haut dans les révisions jusqu’à ce qu’elle en trouve une cohérente :

    Recherchez le message suivant :

    code language-none
    main INFO o.a.j.o.p.s.f.t.ConsistencyChecker - Found latest good revision afdb922d-ba53-4a1b-aa1b-1cb044b535cf:234880
    
  4. Rétablissez le référentiel à cette révision en modifiant ./crx-quickstart/repository/segmentstore/journal.log et supprimer toutes les lignes après la ligne contenant la dernière bonne révision.

  5. Tout supprimer ./crx-quickstart/repository/segmentstore/*.bak .

  6. Exécutez le nettoyage des points de contrôle pour supprimer les points de contrôle orphelins à l’aide de la commande suivante :

    code language-none
    java -Xmx6000m -jar oak-run-*.jar checkpoints /path/to/crx-quickstart/repository/segmentstore rm-unreferenced
    
  7. Enfin, compactez le référentiel :

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

Il peut arriver que la vérification d'exécution Oak ne trouve pas la bonne révision et que "ConsistencyChecker - No good revision found" soit obtenu lors de l'exécution de la commande de vérification.

Comment corriger la corruption lors de la rencontre de "ConsistencyChecker - Aucune bonne révision trouvée" sur la vérification de cohérence

Supprimer manuellement les noeuds corrompus.

Vous pouvez effectuer les opérations suivantes dans AEM configurations TarMK sans FileDatastore configuré et dans les situations où la corruption se trouve dans les fichiers binaires.

Attention : La procédure ci-dessous est destinée aux utilisateurs avancés.  Lors de la suppression des noeuds corrompus, vous devez vous assurer qu’ils ne sont pas des noeuds système (comme /home, /jcr:system, etc.).  S’il s’agit de noeuds système, vous devez vous assurer de pouvoir les restaurer.  Contactez l’équipe d’assistance AEM pour obtenir de l’aide sur les étapes décrites ici si vous n’êtes pas sûr de vous.

  1. Arrêtez AEM.

  2. Utilisez la console d’exécution Oak et chargez le script enfantCount groovy pour identifier les noeuds corrompus dans le magasin de segments :

    Chargez le shell de la console oak-run :

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

    Exécutez les deux commandes ci-dessous dans le shell pour charger le script et l’exécuter :

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

    Cela entraîne la sortie suivante indiquant le chemin d’accès au ou aux noeuds corrompus :

    code language-none
    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
    

    Dans certains cas, le problème est lié à des propriétés binaires et le script groovy childCount ne peut pas localiser de noeuds corrompus.  Dans ce cas, vous pouvez utiliser plutôt la commande suivante, qui lira les 1 024 premiers octets pour chaque binaire rencontré lors de la traversée (Notez que cette commande sera plus lente et ne doit être utilisée que lorsque celle ci-dessus ne renvoie pas les résultats attendus) :

    code language-none
    countNodes(session.workingNode,true)
    
  3. Supprimez tous les noeuds corrompus identifiés répertoriés dans la sortie de la dernière commande à l’aide de rmNodes.groovy.
    Chargez le shell de la console oak-run à l’aide de la commande suivante :

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

    Chargez le script groovy :

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

    Exécutez la commande rmNode pour supprimer le noeud corrompu, remplacez /path/to/corruption/node par le chemin d’accès au noeud corrompu que vous devez supprimer.

    code language-none
    rmNode(session, "/path/to/corrupt/node")
    

    où le chemin du noeud corrompu est le chemin obtenu à l’étape 2, par exemple : "/content/dam/test.txt/jcr:content/renditions/original/jcr:content/"

    Remarque : Lors de l’utilisation de oak-run.jar version 1.6.13 et ultérieure, définissez le paramètre JVM —read-write si vous rencontrez une erreur telle que :

    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. Répétez l’étape 3 pour tous les noeuds trouvés à l’étape 2.

    La commande rmNode ci-dessus doit renvoyer la valeur true pour le chemin corrompu, ce qui signifie qu’elle l’a supprimé. Assurez-vous que ces trois chemins corrompus sont supprimés en exécutant à nouveau la commande rmNode sur ces chemins. La prochaine exécution doit renvoyer la valeur false.
    Si vous constatez que les mêmes chemins d’accès sont toujours présents dans le référentiel, utilisez la version patched du jar oak-run, c’est-à-dire oak-run-1.2.18-NPR-17596. Cette version de jar ignore les fichiers binaires illisibles lors de la compression, les remplaçant par des fichiers binaires de 0 octet et enregistrant l’exception et le chemin d’accès au système. Le référentiel compacté obtenu doit ensuite passer la vérification oak-run et le script node count, et vous devez également pouvoir le compacter à nouveau à l’aide d’une exécution oak non corrigée.

  5. Effectuez un nettoyage de point de contrôle en répertoriant les points de contrôle à l’aide de la commande ci-dessous. S’il existe plusieurs points de contrôle, nettoyez-les :

    code language-none
    nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-allnohup.out
    
  6. Exécutez une compression hors ligne. Si vous ne savez pas comment exécuter le compactage hors ligne, reportez-vous à ici.

  7. Démarrez le serveur pour que l’indexation soit terminée.

Cause

Une exception SegmentNotFoundException dans le journal des erreurs signifie qu’un segment n’est plus présent même si quelqu’un tente apparemment d’y accéder. Il existe globalement trois causes profondes différentes pour cela : le segment a été supprimé par une intervention manuelle (par exemple, rm -rf /), le segment a été supprimé par le nettoyage de la mémoire de révision ou le segment est introuvable en raison d’un bogue dans le code.

recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f