http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/에서 oak-run jar 파일을 다운로드합니다.
리포지토리의 무결성 문제가 있는 경우 SegmentNotFoundException 발생
문제
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) ...
또는
리포지토리의 무결성 문제가 있는 경우 IllegalArgumentException 사용 시 오프라인 압축 실행이 실패할 수 있습니다. 아래와 유사한 스택 추적이 로그에 있을 수 있습니다.
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)
환경
AEM 6.x
원인
압축에서 노드를 읽으려고 시도하는 동안 세그먼트가 없으면 SegmentNotFoundException이 반환됩니다. 이 경우 다른 근본 원인이 있을 수 있습니다.
- 세그먼트가 수동 개입(예: rm -rf /)으로 제거되었습니다.
- 세그먼트가 수정 가비지 컬렉션에 인해 제거되었습니다.
- 코드에 있는 일부 버그로 인해 세그먼트를 찾을 수 없습니다.
수정 가비지 컬렉션(포인트 2)으로 인해 문제가 발생하는 경우 추가 노드가 손상되지 않도록 온라인 압축이 사용되지 않도록 설정하십시오.
해결 방법
상황을 해결하고 오프라인 압축을 성공적으로 완료하기 위해 수행할 수 있는 여러 절차가 있습니다.
중요: 아래 절차를 수행하기 전에 리포지토리를 전체적으로 백업하십시오.
A. 세그먼트 저장소의 양호한 것으로 알려진 마지막 수정된 버전으로 되돌립니다.
oak-run의 검사 실행 모드를 사용하여 세그먼트 저장소의 양호한 것으로 알려진 마지막 수정된 버전을 판별할 수 있습니다. 이 모드는 손상된 세그먼트 저장소를 수동으로 최근의 양호한 수정 버전으로 되돌리는 데 사용할 수 있습니다.
이 프로세스는 시스템의 데이터를 이전 시점으로 롤백합니다. 시스템의 변경 사항을 유실하지 않으려면 대신 아래의 옵션 B를 시도할 수 있습니다.
확인 및 복원을 수행하려면
-
-
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 파일을 제거합니다.
-
AEM6.0을 사용한다면 나머지 단계에 대해 AEM에 설치되어 있는 것과 일치하는 oak-run 버전을 다운로드하십시오. http://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-run 콘솔을 사용하고 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 스크립트가 손상된 노드를 찾을 수 없습니다.이 경우 다음 명령을 대신 사용할 수 있습니다. 이 명령은 순회 중에 마주치는 모든 바이너리 파일에 대해 처음 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-write JVM 매개 변수를 설정하십시오.
/> 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 명령을 다시 실행하여 손상된 3개의 경로가 삭제되었는지 확인하십시오. 다음에 실행하면 false를 반환해야 합니다.
그래도 리포지토리에 동일한 경로가 있다고 표시되면 패치가 적용된 oak-run jar 버전(예: oak-run-1.2.18-NPR-17596)을 사용하십시오.
패치가 적용된 Oak-run Jar 버전은 어떤 일을 수행합니까?
이 jar 버전은 압축 시 읽을 수 없는 바이너리를 건너뛰어 0바이트 바이너리로 바꾸고 예외 및 syserr 경로를 로깅합니다. 이렇게 압축된 리포지토리는 노드 수 스크립트인 oak-run check를 통과해야 하며 패치가 적용되지 않은 oak-run을 사용하여 다시 압축할 수도 있어야 합니다.
-
아래를 사용하여 체크포인트를 나열하여 체크포인트를 정리를 수행합니다. 체크포인트가 둘 이상 있으면 정리하십시오.
nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-all>>nohup.out &
-
오프라인 압축을 실행합니다. 오프라인 압축을 실행하는 방법을 모를 경우 여기를 참조하십시오.
-
서버를 시작하고 색인화가 완료될 때까지 기다립니다.
내 계정 로그인