L’exécution d’un compactage hors ligne peut échouer avec SegmentNotFoundException lorsqu’il existe des problèmes d’intégrité du référentiel.

Problème

L’exécution d’un compactage hors ligne peut échouer avec SegmentNotFoundException lorsqu’il existe des problèmes d’intégrité du référentiel. Une trace d'appels similaire à celle ci-dessous est disponible dans les journaux :

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

OU l’exécution d’un compactage hors ligne peut échouer avec IllegalArgumentException lorsqu'il existe des problèmes d’intégrité du référentiel. Une trace d'appels similaire à celle ci-dessous est disponible dans les journaux :

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)

Environnement

AEM 6.x

Cause

Un événement SegmentNotFoundException est renvoyé lorsqu’un segment n’est pas présent alors que le système de fichiers tente de lire le nœud. Il peut y avoir différentes origines à cela :

  1. Le segment a été supprimé par une intervention manuelle (par exemple, rm -rf /).
  2. Le segment a été supprimé par le nettoyage de la mémoire de révision. 
  3. Le segment est introuvable en raison d'un bogue dans le code.

Dans le cas où le problème est causé par la collecte des objets inutilisés (Point 2), assurez-vous que le compactage en ligne est désactivé pour éviter que d'autres nœuds ne deviennent corrompus.

Résolution

 

Plusieurs procédures permettent de résoudre la situation et d’exécuter correctement le compactage hors ligne.

Important: Effectuez une sauvegarde complète de votre référentiel avant de suivre les étapes ci-dessous.

A. Rétablissement de la dernière révision correcte du stockeur de segment.

La vérification run-mode de oak-run peut être utilisé pour déterminer la dernière révision connue d’un magasin de segments. Cela peut être utilisé pour rétablir manuellement la dernière version de segment endommagée.

Attention :

Ce processus restaurera les données du système en un point antérieur dans le temps.  Si vous souhaitez éviter de perdre les modifications de votre système puis pouvez-vous essayer l'option B ci-dessous.

Pour effectuer la vérification et la restauration:

  1. Téléchargez le fichier JAR oak-run ici : http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/

    • AEM 6.0 : si vous utilisez Oak 1.0.12 ou version ultérieure, utilisez Oak 1.1.8 - oak-run-1.1.8.jar.  Si la version Oak est 1.0.11 ou antérieure, choisissez l'oak-run 1.1.6.
    • AEM 6.1 : téléchargez la version 1.2.x de oak-run qui correspond à ce qui est installé (vérification par l'intermédiaire de système/console/regroupement d'IU).

    Remarque :

    Nous utilisons une version de la branche 1.1.x d'oak-run car la branche 1.0.x n'a pas la commande appliquée « vérification ».

  2. Arrêtez AEM.

  3. Exécuter cette commande:

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

    Cette commande effectue une recherche des révisions passées jusqu’à ce qu’elle détecte une révision cohérente :

    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

    (Si le vérificateur de cohérence échoue, accédez à la section suivante).

  4. Rétablissez le référentiel à partir de cette révision en modifiant le fichier.

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

    Supprimez toutes les lignes après la ligne contenant la dernière modification correcte. Si vous souhaitez savoir à quelle date et heure vous rétablissez le référentiel, exécutez cette commande dans le dossier segmentstore (remplacez afdb922d-ba53-4a1b-aa1b-1cb044b535cf avec la dernière bonne modification dans votre journal.log) :

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

    La sortie affiche une date et une heure approximative de cette modification.

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

  6. Si vous utilisez AEM 6.0, téléchargez la version oak-run adéquate qui est installée dans le AEM pour les étapes restantes.  Téléchargez-le à partir d'ici http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/

  7. Lancez le nettoyage de point de reprise pour supprimer les points isolés :

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

  8. Enfin, compressez le référentiel :

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

B. Supprimez manuellement les nœuds corrompus.

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

Attention :

La procédure ci-dessous est destinée aux utilisateurs expérimentés.  Lorsque vous supprimez les nœuds corrompus dont vous avez besoin pour vous assurer qu’ils ne sont pas des nœuds système (par exemple, /home, /jcr:system, etc.)  Ou, s'il y a des nœuds système, vous devez être certain de les restaurer.  Consultez l'équipe d'assistance clientèle AEM pour obtenir de l'aide concernant les étapes documentées ici si vous n'êtes pas sûr.

  1. Arrêtez AEM.

  2. Utilisez la console d’exécution Oak et chargez le script childCount groovy pour identifier les nœuds corrompus dans le stockeur de segments :

    Chargement du shell de la console oak-run

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

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

    :load https://gist.githubusercontent.com/stillalex/e7067bcb86c89bef66c8/raw/d7a5a9b839c3bb0ae5840252022f871fd38374d3/childCount.groovy

    countNodes(session.workingNode)

    En conséquent, la sortie suivante indique le chemin vers le ou les nœuds corrompus :

    21:21:42.029 [main] ERROR o.a.j.o.p.segment.SegmentTracker - Segment not found: 63ae05a4-b506-445c-baa2-cfa1b13b6e2f. La date de création de delta est de 3 ms.
    Avertissement illisible du nœud /content/dam/test.txt/jcr:content/renditions/original/jcr:content

    Dans certains cas, le problème est lié aux propriétés binaires et le script groovy de childCount ne parvient pas à localiser tous les nœuds corrompus.  Dans ce cas, vous pouvez utiliser à sa place la commande suivante, qui lit les 1024 premiers octets pour chaque bitmap rencontré lors de la traversée (cette commande sera plus lente et ne doit être utilisée que lorsque celle ci-dessus ne donne pas les résultats escomptés) :

    countNodes(session.workingNode,true)

  3. Supprimez tous les nœuds corrompus identifiés et répertoriés dans la sortie de la dernière commande avec rmNodes.groovy.

    Chargement de la coque de la console oak-run :

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

    Charger le script groovy :

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

    Exécutez la commande rmNode pour supprimer le nœud corrompu, remplacez /path/en/corrupt/node par le chemin d’accès au nœud corrompu à supprimer.

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

    Où le chemin du nœud endommagé est le chemin obtenu à l'étape 2, par exemple: "/content/dam/test.txt/jcr:content/renditions/original/jcr:content/"

  4. Répétez l'étape 3 pour tous les nœuds trouvés à l'étape 2.

    Cette commande rmNode ci-dessus devrait renvoyer une valeur vraie pour le chemin corrompu, ce qui signifie qu’elle l’a supprimé. Assurez-vous que ces trois chemins corrompus ont été supprimés par la commande de réexécution rmNode sur ces tracés. La prochaine exécution devrait renvoyer une valeur fausse.

    Si vous voyez toujours que les mêmes chemins sont disponibles dans le référentiel, alors utilisez la version rapiécée de Oak, c.-à-d. oak-run-1.2.18-NPR-17596

    Qu'est -ce que la version corrigée du Oak run Jar Do?

    Cette version de jar ignore les binaires illisibles sur la compression remplaçant sont des fichiers binaires de 0 octets et enregistrement efficace de l'exception et le tracé au syserr. Le référentiel récursif doit alors transmettre le code oak-run, le script du nombre de nœuds et vous devriez également l’utiliser de nouveau en utilisant un non- patched oak-run.

  5. Effectuez un nettoyage de point de contrôle en suivant les points de contrôle ci-dessous. S’il existe plusieurs points de contrôle, effacez-les:

    nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-all>>nohup.out &

  6. Supprimez les nœuds asynchrones [Cette étape est facultative. Ne l'utilisez que si nécessaire pour effectuer un reindex complet.]:

    java -Xmx4096m -jar oak-run-1.2.18.jar console /app/AEM6/author/crx-quickstart/repository/segmentstore


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

    rmNode(session, "/:async")

  7. Démarrez le serveur pour terminer l’indexation.

  8. Arrêtez AEM.

  9. Exécutez le compactage hors ligne.

Ce produit est distribué sous licence Creative Commons Attribution - Pas d’utilisation commerciale - Partage à l’identique 3.0 non transposé  Les publications Twitter™ et Facebook ne sont pas couvertes par les dispositions Creative Commons.

Mentions légales   |   Politique de confidentialité en ligne