AEM日志和实例中的SegmentNotFoundException不起作用
了解如何使用以下步骤解决AEM日志和实例中的SegmentNotFoundException问题。
注意:在执行步骤之前,请对存储库执行完整备份。
描述 description
环境
Adobe Experience Manager (AEM) 6.x
问题/症状
AEM日志文件中的SegmentNotFoundException,并且AEM未按预期工作。
当存储库中存在完整性问题时,运行离线压缩可能会失败并出现SegmentNotFoundException。 可以在日志中找到类似于以下内容的栈栈跟踪:
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) ...
当存储库中存在完整性问题时,运行离线压缩可能会失败并出现IllegalArgument异常。 可以在日志中找到类似于以下内容的栈栈跟踪:
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)
解决方法 resolution
第一个方法
-
从 org/apache/jackrabbit/oak-run 下载oak-run jar文件。
-
停止 AEM。
-
运行此命令:
java -jar oak-run-*.jar check --bin=-1 crx-quickstart/repository/segmentstore/此命令向后搜索修订,直到找到一致的修订:
14:00:30.783 [ main] INFO o.a.j.o.p.s.f.t.ConsistencyChecker - Found latest good revision xxxx000x-ba53-4a1b-aa1b-0xx000x000xx:234880注意: 如果
ConsistencyChecker失败,请转到下一部分。 -
通过编辑下面给定的命令将存储库恢复到此版本。
/crx-quickstart/repository/segmentstore/journal.log.删除包含最新良好修订的行之后的所有行。 要了解需要还原到存储库的日期和时间,请在
segmentstore文件夹中运行此命令(在xxxx000x-ba53-4a1b-aa1b-0xx000x000xx中将journal.log替换为最新的良好修订):find . -type f -name "data*.tar" -exec sh -c "tar -tvf {} |grep xxxx000x-ba53-4a1b-aa1b-0xx000x000xx" \; -print输出将显示该修订的大致日期和时间。
-
移除所有
./crx-quickstart/repository/segmentstore/*.bak files。 -
如果使用AEM 6.0,则下载与AEM中已安装的版本匹配的oak-run版本以完成其余步骤。 从以下链接下载:org/apache/jackrabbit/oak-run。
-
运行检查点清理以删除孤立的检查点:
java -jar oak-run-*.jar checkpoints ./crx-quickstart/repository/segmentstore rm-unreferenced. -
最后,压缩存储库:
java -jar oak-run-*.jar compact ./crx-quickstart/repository/segmentstore/。
第二个方法
手动删除损坏的节点。
在AEM中,对于未配置FileDatastore的TarMK设置以及二进制文件中存在损坏的情况,请执行以下步骤:
注意:以下步骤适用于超级用户。 删除损坏的节点时,您需要确保它们不是系统节点(如/home、/jcr:system等)。 或者,如果它们是系统节点,那么您需要确保可以恢复它们。 如果您不确定,请咨询AEM客户关怀团队以获得此处记录的步骤的帮助。
-
停止 AEM。
-
使用Oak运行控制台并加载childCount groovy脚本来识别区段存储中的损坏节点:
-
加载 oak-run 控制台外壳:
java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore -
在外壳中运行以下两个命令来加载脚本并运行它:
: load https://gist.githubusercontent.com/stillalex/e7067bcb86c89bef66c8/raw/d7a5a9b839c3bb0ae5840252022f871fd38374d3/childCount.groovycountNodes(session.workingNode) -
这将导致以下输出指示损坏节点的路径:
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- 在某些情况下,该问题与二进制属性有关,并且
childCount groovy脚本无法找到任何损坏的节点。 在这些情况下,您可以使用以下命令代替,它将读取遍历期间遇到的每个二进制文件的前1024个字节。
(请注意,此命令会较慢,并且仅当上述解决方案未返回预期结果时才应使用此命令):
countNodes(session.workingNode,true) - 在某些情况下,该问题与二进制属性有关,并且
-
-
使用
rmNodes.groovy删除最后一个命令输出中列出的所有已识别损坏节点。-
加载 oak-run 控制台外壳:
java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore -
加载 groovy 脚本:
:load https://gist.githubusercontent.com/stillalex/43c49af065e3dd1fd5bf/raw/9e726a59f75b46e7b474f7ac763b0888d5a3f0c3/rmNode.groovy -
运行
rmNode命令移除损坏的节点,通过带有您需要移除的损坏节点的路径替换/path/to/corrupt/node。rmNode(session, "/path/to/corrupt/node")其中损坏的节点路径为步骤2中获得的路径,例如:
"/content/dam/test.txt/jcr:content/renditions/original/jcr:content/"
注意: 使用
oak-run.jar版本1.6.13及更高版本时,如果遇到以下错误,请设置--read-writeJVM参数: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. (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) -
-
对步骤2中找到的所有节点重复步骤3。 以上
rmNode命令应该为损坏路径返回true,这意味着该命令删除了此损坏路径。 通过在这些路径上重新运行rmNode命令,确保删除这些找到的三个损坏路径。 下次运行应该返回false。 如果存储库中存在相同的路径,则建议使用修补版本的oak-run jar,即oak-run-1.2.18-NPR-00000。Oak run Jar的修补版本有什么功能?
此版本的jar在压缩时跳过不可读的二进制文件,将它们替换为0字节二进制文件并记录异常和
syserr的路径(错误消息窗口)。 压缩的存储库应该会通过oak-run检查、节点计数脚本,并且还能够使用未打补丁的oak-run再次压缩。 -
通过使用以下列出检查点来执行检查点清理。 如果有多个检查点,请清理它:
nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-all >> nohup.out & -
运行离线压缩。 了解如何在此处运行离线压缩。
-
启动服务器并等待索引完成。
原因
如果在压缩尝试读取节点时区段不存在,则会返回SegmentNotFoundException。 这可能是由不同的根本原因造成的:
- 该区段已经人工干预移除(例如
rm -rf /)。 - 高渠段已通过修订垃圾收藏集移除。
- 由于代码中存在错误,无法找到该区段。
如果问题是由修订垃圾收藏集引起的(第2点),请确保禁用在线压缩以避免进一步的节点损坏。
在我们的Experience League Campaign社区中提问
如果您想了解有关此主题的解答或阅读之前的解答问题,我们邀请您查看包含本文的Experience League社区博客文章,向我们发送您的问题和评论,并加入我们的Experience League Campaign社区!