Exceptions SegmentNotFoundException et IllegalArgumentException
L’exécution d’un compactage hors ligne peut échouer avec SegmentNotFoundException ou IllegalArgumentException. Cet article explique comment résoudre les erreurs et terminer correctement le compactage hors ligne. Toutefois, avant de continuer, effectuez une sauvegarde complète de votre référentiel.
Description description
Environnement
Adobe Experience Manager (AEM)
Problème
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 les fichiers journaux AEM 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 s’affiche dans les journaux :
13:51:21.523 [ main] ERROR o.a.j.o.p.segment.SegmentTracker - Segment not found: 4d139bc4-150c-4f0a-b82a-4867593098a. Creation date delta is 4 ms.
org.apache.jackrabbit.oak.plugins.segment.SegmentNotFoundException: Segment 4d139bc4-150c-4f0a-b82a-4867593098a 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-4867593098a 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 l’exception IllegalArgument en cas de problèmes d’intégrité du référentiel.
Une trace de pile similaire à celle ci-dessous s’affiche 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 resolution
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.
Attention : ce processus restaurera les données du système à un point dans le temps antérieur.
Si vous souhaitez éviter de perdre des modifications dans votre système, essayez plutôt l’option B ci-dessous.
Pour effectuer la vérification et la restauration, procédez comme suit :
-
Téléchargez le fichier jar
oak-runici https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/. -
Arrêtez AEM.
-
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.)
-
Rétablissez le référentiel à cette révision en modifiant :
/crx-quickstart/repository/segmentstore/journal.logSupprimez 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 dossier
segmentstore(remplacez afdb922d-ba53-4a1b-aa1b-1cb044b535cf par la dernière bonne révision de votrejournal.log) :find . -type f -name "data*.tar" -exec sh -c "tar -tvf {} |grep afdb922d-ba53-4a1b-aa1b-1cb044b535cf" \; -printLa sortie vous indiquerait une date et une heure approximatives de cette révision.
-
Supprimez tous les fichiers
./crx-quickstart/repository/segmentstore/*.bak files.. -
Si vous utilisez AEM 6.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/.
-
Exécutez le nettoyage des points de contrôle pour supprimer les points de contrôle orphelins :
java -jar oak-run-*.jar checkpoints ./crx-quickstart/repository/segmentstore rm-unreferenced -
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 nœuds corrompus, vous devez vous assurer qu’il ne s’agit pas de nœuds système (tels que /home, /jcr:system, etc.) .
Ou s’il s’agit de nœuds système, vous devez vous assurer que vous pouvez les restaurer.
En cas de doute, veuillez consulter l’équipe d’assistance clientèle d’AEM pour obtenir de l’aide sur les étapes documentées ici.
-
Arrêtez AEM.
-
Utilisez la console d’exécution Oak et chargez le script groovy
childCountpour identifier les nœuds corrompus dans le magasin de segments :Chargez le shell de la console oak-run :
java -jar oak-run-*.jar console crx-quickstart/repository/segmentstoreExécutez les deux commandes ci-dessous dans le shell pour charger le script et l’exécuter :
:loadhttps:/gist.githubusercontent.com/Shivam-Agg/dc1add0033b2765e25e714bb11faf0ae/raw/2f85c1023c9eb693211e55ddc3a245f16aff8d7d/childCount.groovycountNodes(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:contentDans certains cas, le problème est lié à des propriétés binaires et le script groovy
childCountne parvient pas à localiser les nœuds corrompus.Dans ces cas, vous pouvez utiliser la commande suivante à la place, qui lira les 1 024 premiers octets pour chaque fichier binaire rencontré lors du parcours (notez que cette commande sera plus lente et ne doit être utilisée que lorsque la commande ci-dessus ne renvoie pas les résultats attendus) :
countNodes(session.workingNode,true) -
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/segmentstoreChargez le script groovy :
:loadhttps://gist.githubusercontent.com/Shivam-Agg/9471ca705bc500d139fe1dbd2907f018/raw/ae8d7ad8887be5237e77f1bbeda88a806f1ba182/rmNode.groovyExécutez la commande
rmNodepour supprimer le nœud corrompu, remplacez/path/to/corrupt/nodepar le chemin d’accès au nœud corrompu que vous devez supprimer.rmNode(session, "/path/to/corrupt/node")Où le chemin d’accès au nœud 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 deoak-run.jarversion 1.6.13 et ultérieure, définissez le paramètre JVM--read-writesi 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) -
Répétez l’étape 3 pour tous les nœuds trouvés à l’étape 2.
La commande
rmNodeci-dessus doit renvoyer la valeur true pour le chemin d’accès corrompu, ce qui signifie qu’elle l’a supprimé.Vérifiez que ces trois chemins d’accès corrompus sont supprimés en réexécutant la commande
rmNodesur ces chemins d’accès.Pour la prochaine exécution, il doit renvoyer
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 du fichier oak-run jar (par exemple, oak-run-1.2.18-NPR-17596).
À quoi sert la version corrigée du fichier oak-run jar ?
Cette version de jar ignore les fichiers binaires illisibles lors de la compression, les remplaçant par des fichiers binaires de 0 octet et consignant l’exception et le chemin d’accès dans syserr.
Le référentiel ainsi compacté doit alors transmettre la vérification oak-run, le script du nombre de nœuds et vous devez également pouvoir le compacter à nouveau à l’aide d’un oak-run non corrigé.
-
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 & -
Exécutez un compactage hors ligne.
Si vous ne savez pas exécuter le compactage hors ligne, consultez les instructions de compactage hors ligne d’Oak sur GitHub Gist.
-
Démarrez le serveur et attendez la fin de l’indexation.
Cause
Une exception SegmentNotFoundException est renvoyée lorsqu’un segment n’est pas présent alors que le compactage tente de lire le nœud.
Les causes peuvent être différentes :
- Le segment a été supprimé par une intervention manuelle (par exemple : rm -rf /).
- Le segment a été supprimé par la récupération de l’espace mémoire de révision.
- 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 le compactage en ligne est désactivé pour éviter que d’autres nœuds ne soient corrompus.