Exceptions SegmentNotFoundException et IllegalArgumentException

Dernière mise à jour : 2023-07-24

Description

Environnement
Experience Manager

Problème/Symptômes

Scénario 1
L’exécution d’un compactage hors ligne peut échouer avec SegmentNotFoundException en cas de problèmes d’intégrité du référentiel.

Vous observez SegmentNotFoundException dans AEM fichiers journaux et AEM ne fonctionne pas comme prévu.

Scénario 2

L’exécution d’un compactage hors ligne peut échouer avec SegmentNotFoundException en cas de problèmes d’intégrité du référentiel.

Une trace de pile similaire à celle ci-dessous apparaît 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)
...

Scénario 3

L’exécution d’un compactage hors ligne peut échouer avec IllegalArgument Exception en cas de problèmes d’intégrité du référentiel.

Une trace de pile similaire à celle ci-dessous apparaît 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)

Résolution

Solution

Il existe plusieurs procédures que nous pouvons suivre pour résoudre la situation et terminer correctement le compactage hors ligne.

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

A. Revenez à la dernière révision correcte connue du magasin de segments.

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

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

Pour effectuer la vérification et la restauration, procédez comme suit :

  1. Téléchargez la oak-run fichier jar d’ici https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/

  2. Arrêtez AEM.

  3. Exécutez cette commande :

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

    Cette commande effectue une recherche vers le haut dans les révisions jusqu’à ce qu’elle en trouve une 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

    (En cas d’échec de ConsistencyChecker, accédez à la section suivante)

  4. Rétablissez le référentiel à cette révision en le modifiant:

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

    Supprimez toutes les lignes après la ligne contenant la dernière bonne révision.

    Si vous souhaitez connaître la date et l’heure auxquelles vous rétablissez le référentiel, exécutez cette commande dans le segmentstore folder (remplacer) afdb922d-ba53-4a1b-aa1b-1cb044b535cf avec la dernière bonne révision de votre journal.log) :

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

    La sortie vous indiquerait une date et une heure approximatives de cette révision.

  5. Supprimez tous les fichiers ./crx-quickstart/repository/segmentstore/*.bak files..

  6. Si vous utilisez AEM6.0, téléchargez la version oak-run correspondant à ce qui est installé dans AEM pour les étapes restantes.

    Téléchargez-le ici https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/.

  7. Exécuter nettoyage du point de contrôle pour supprimer les points de contrôle orphelins :

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

  8. Enfin, compactez 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é 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.
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.) .
Ou s’il s’agit de nœuds système, vous devez vous assurer que vous pouvez les restaurer.
Si vous n’êtes pas sûr, veuillez consulter l’équipe d’assistance clientèle AEM pour obtenir de l’aide sur les étapes décrites ici.

  1. Arrêtez AEM.

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

    Chargez le shell de la console oak-run :

    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 :

    :load

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

    countNodes(session.workingNode)

    Cette action génère la sortie suivante indiquant le chemin d’accès aux nœuds corrompus :

    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é aux propriétés binaires et à la variable childCount le script groovy ne parvient pas à localiser les 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) :

    countNodes(session.workingNode,true)

  3. Supprimez tous les nœuds 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 :

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

    Chargez 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/to/corrupt/node par le chemin d’accès au nœud corrompu que vous devez supprimer.

    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, configuration --read-write Paramètre JVM si vous rencontrez une erreur telle que :

    /> 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 nœuds trouvés à l’étape 2.

    La commande rmNode ci-dessus doit renvoyer la valeur true pour le chemin d’accès corrompu, ce qui signifie qu’elle l’a supprimé.

    Assurez-vous que ces trois chemins d’accès corrompus sont supprimés en réexécutant la commande rmNode sur ces chemins d’accès.

    Pour la prochaine exécution, elle doit renvoyer la valeur false.

    Si vous constatez toujours que les mêmes chemins d’accès se trouvent dans le référentiel, utilisez la version corrigée de jar oak-run (c.-à-d. oak-run-1.2.18-NPR-17596).

    Que fait la version corrigée du jar exécuté par Oak ?

    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 ainsi compacté doit alors transmettre la vérification oak-run, le script node count et vous devriez également être en mesure de 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 :

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

  6. Exécutez un compactage hors ligne.

    Si vous ne savez pas exécuter le compactage hors ligne, reportez-vous à la section Instructions de compression hors ligne Oak sur GitHub Gist.

  7. Démarrez le serveur et attendez la fin de l’indexation.

Cause
A SegmentNotFoundException est renvoyé lorsqu’un segment n’est pas présent pendant que la compression tente de lire le noeud.

Les causes peuvent être différentes :

  1. Le segment a été supprimé par une intervention manuelle (par exemple : rm -rf /).
  2. Le segment a été supprimé par la récupération de l’espace mémoire de révision.
  3. Le segment est introuvable en raison d’un bug dans le code.

Si le problème est dû au nettoyage de la mémoire de révision (cause #2), assurez-vous que la compression en ligne est désactivée pour éviter que d’autres noeuds ne soient corrompus.

Sur cette page