SegmentNotFoundException and IllegalArgumentException
설명 description
환경
Experience Manager
문제/증상
시나리오 1
오프라인 압축 실행은 실패하고 SegmentNotFoundException 저장소의 무결성 문제가 있는 경우.
다음을 관찰합니다. SegmentNotFoundException AEM 로그 파일에서 AEM이 예상대로 작동하지 않습니다.
시나리오 2
오프라인 압축 실행은 실패하고 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)
...
시나리오 3
오프라인 압축 실행은 실패하고 잘못된 인수 저장소의 무결성 문제가 있는 경우 예외.
아래 추적과 유사한 스택 추적은 로그에 표시됩니다.
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
솔루션
여러 절차에 따라 상황을 해결하고 오프라인 압축을 성공적으로 완료할 수 있습니다.
중요 사항: 아래 단계를 따라 저장소의 전체 백업을 수행하십시오.
A. 마지막으로 알려진 세그먼트 스토어 수정 버전으로 되돌리기.
oak-run의 점검 실행 모드를 사용하여 마지막으로 알려진 세그먼트 스토어 수정을 확인할 수 있습니다.
수동으로 손상된 세그먼트 스토어를 최신 버전으로 되돌리는 데 사용할 수 있습니다.
주의: 이 프로세스는 시스템의 데이터를 이전 시점으로 롤백합니다.
시스템에서 변경 사항의 손실을 방지하려면 다음을 시도해 보십시오. 옵션 B 대신 를 클릭합니다.
확인 및 복원을 수행하려면 다음 단계를 수행합니다.
-
다운로드
oak-run
jar 파일 위치 https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/ -
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 afdb922d-ba53-4a1b-aa1b-1cb044b535cf:234880
(ConsistencyChecker가 실패할 경우 다음 섹션으로 이동)
-
편집하여 저장소를 이 수정 버전으로 되돌리기:
/crx-quickstart/repository/segmentstore/journal.log
최신 수정 버전이 포함된 줄 다음의 모든 줄을 삭제합니다.
저장소를 되돌리는 날짜 및 시간을 확인하려면
segmentstore
폴더(바꾸기) afdb922d-ba53-4a1b-aa1b-1cb044b535cf 최신 수정 버전 포함journal.log
):find . -type f -name "data*.tar" -exec sh -c "tar -tvf {} |grep afdb922d-ba53-4a1b-aa1b-1cb044b535cf" \; -print
출력에는 해당 수정 버전의 근사 날짜 및 시간이 표시됩니다.
-
모든
./crx-quickstart/repository/segmentstore/*.bak files.
파일을 제거합니다. -
AEM 6.0을 사용하는 경우 나머지 단계에 대해 AEM에 설치된 버전과 일치하는 oak-run 버전을 다운로드합니다.
여기에서 다운로드하십시오. https://repo1.maven.org/maven2/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/
B. 수동으로 손상된 노드 제거.
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.groovy
countNodes(session.workingNode)
이렇게 되면 손상된 노드의 경로를 나타내는 다음과 같은 출력이 나타납니다.
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 스크립트가 손상된 노드를 찾을 수 없습니다.이 경우 순회 중에 발견된 모든 바이너리의 첫 1,024바이트를 판독하는 다음 명령을 대신 사용할 수 있습니다(이 명령은 속도가 느려지고 위의 명령이 예상 결과를 반환하지 않는 경우에만 사용해야 함).
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-write
다음과 같은 오류가 발생하는 경우 JVM 매개변수: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)
-
2단계에 발견된 모든 노드에 대해 3단계를 반복합니다.
위
rmNode
명령은 삭제된 손상 경로에 대해 true를 반환해야 합니다.발견된 세 개의 손상 경로는 다시 실행하여 삭제해야 합니다.
rmNode
명령입니다.다음 실행을 위해 이 항목이 반환됩니다
false
.동일한 경로가 저장소에 계속 존재하는 경우 oak-run jar, 즉 의 패치 버전을 사용하십시오. oak-run-1.2.18-NPR-17596).
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 &
-
오프라인 압축을 실행합니다.
오프라인 압축을 실행하는 방법을 모를 경우 다음을 참조하십시오. Oak 오프라인 압축 지침 GitHub Gist에서
-
서버를 시작하고 색인화가 완료될 때까지 기다립니다.
원인
A SegmentNotFoundException 압축이 노드 읽기를 시도하는 동안 세그먼트가 없는 경우 가 반환됩니다.
이에 대한 근본 원인은 다음과 같이 다양할 수 있습니다.
- 수동 개입으로 세그먼트가 제거되었습니다(예: rm -rf /).
- 수정 가비지 수집으로 세그먼트가 제거되었습니다.
- 코드의 일부 버그로 인해 세그먼트를 찾을 수 없습니다.
수정 가비지 수집으로 인해 문제가 발생하는 경우(원인 #2) 추가 노드가 손상되지 않도록 온라인 압축을 비활성화해야 합니다.