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 le compactage hors ligne avec succès. 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.
SegmentNotFoundException s’affiche 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-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 lorsque le référentiel présente des problèmes d’intégrité.
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 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 antérieur dans le temps.
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 :
-
Téléchargez le fichier jar
oak-run
à partir d'ici 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
(Si le vérificateur de cohérence échoue, accédez à la section suivante.)
-
Rétablissez le référentiel à cette révision en modifiant les éléments suivants :
/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 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" \; -print
La 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 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
-
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 (tels que /home
, /jcr:system
, etc.) .
Ou s’il s’agit de noeuds système, vous devez vous assurer que vous pouvez les restaurer.
Si vous n’êtes pas sûr, veuillez consulter AEM équipe d’assistance clientèle pour obtenir de l’aide sur les étapes décrites ici.
-
Arrêtez AEM.
-
Utilisez la console d’exécution Oak et chargez le script groovy
childCount
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é à des propriétés binaires et le script groovy
childCount
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)
-
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 :
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 deoak-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)
-
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 corrompus ont été supprimés en exécutant à nouveau la commande
rmNode
sur ces chemins.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 jar oak-run. (par exemple, 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.
-
Effectuez un nettoyage de point de contrôle en répertoriant les points de contrôle à l’aide de 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 comment exécuter le compactage hors ligne, reportez-vous aux instructions de compactage hors ligne Oak sur GitHub Gist.
-
Démarrez le serveur et attendez la fin de l’indexation.
Cause
Un 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 :
- 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 la compression en ligne est désactivée pour éviter que d’autres noeuds ne soient corrompus.