AEM 로그와 인스턴스의 SegmentNotFoundException이 작동하지 않음

리포지토리의 무결성 문제가 있는 경우 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이 반환됩니다. 이 경우 다른 근본 원인이 있을 수 있습니다.

  1. 세그먼트가 수동 개입(예: rm -rf /)으로 제거되었습니다.
  2. 세그먼트가 수정 가비지 컬렉션에 인해 제거되었습니다. 
  3. 코드에 있는 일부 버그로 인해 세그먼트를 찾을 수 없습니다.

수정 가비지 컬렉션(포인트 2)으로 인해 문제가 발생하는 경우 추가 노드가 손상되지 않도록 온라인 압축이 사용되지 않도록 설정하십시오.

해결 방법

 

상황을 해결하고 오프라인 압축을 성공적으로 완료하기 위해 수행할 수 있는 여러 절차가 있습니다.

중요: 아래 절차를 수행하기 전에 리포지토리를 전체적으로 백업하십시오.

A. 세그먼트 저장소의 양호한 것으로 알려진 마지막 수정된 버전으로 되돌립니다.

oak-run의 검사 실행 모드를 사용하여 세그먼트 저장소의 양호한 것으로 알려진 마지막 수정된 버전을 판별할 수 있습니다. 이 모드는 손상된 세그먼트 저장소를 수동으로 최근의 양호한 수정 버전으로 되돌리는 데 사용할 수 있습니다.

경고:

이 프로세스는 시스템의 데이터를 이전 시점으로 롤백합니다.  시스템의 변경 사항을 유실하지 않으려면 대신 아래의 옵션 B를 시도할 수 있습니다.

확인 및 복원을 수행하려면

  1. http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/에서 oak-run jar 파일을 다운로드합니다.

  2. AEM을 중지합니다.

  3. 다음 명령을 실행합니다.

    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가 실패하는 경우 다음 섹션으로 이동하십시오.)

  4. 편집으로 리포지토리를 다음 수정 버전으로 되돌립니다.

    /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

    출력은 해당 수정 버전의 대략적인 날짜와 시간을 보여줍니다.

  5. 모든 ./crx-quickstart/repository/segmentstore/*.bak 파일을 제거합니다.

  6. AEM6.0을 사용한다면 나머지 단계에 대해 AEM에 설치되어 있는 것과 일치하는 oak-run 버전을 다운로드하십시오.  http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/에서 다운로드합니다.

  7. 체크포인트 정리를 실행하여 고립된 체크포인트를 제거합니다.

    java -jar oak-run-*.jar checkpoints ./crx-quickstart/repository/segmentstore rm-unreferenced.

  8. 마지막으로 리포지토리를 압축합니다.

    java -jar oak-run-*.jar compact ./crx-quickstart/repository/segmentstore/

B. 손상된 노드를 수동으로 제거합니다.

AEM에서, FileDatastore가 구성되지 않은 TarMK 설정과, 바이너리에 손상이 있는 상황에서는 다음을 수행할 수 있습니다. 아래 절차는 고급 사용자를 위한 것입니다.

경고:

아래 절차는 고급 사용자를 위한 것입니다.  손상된 노드를 삭제할 때 시스템 노드가 아닌지 확인해야 합니다(예: /home, /jcr:system 등).  또는 시스템 노드라면 복원할 수 있는지 확인해야 합니다.  확실하지 않은 경우 여기에 설명된 절차에 대한 도움을 받으려면 AEM 고객 지원 팀에 문의하십시오.

  1. AEM을 중지합니다.

  2. 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)

  3. 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)

  4. 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을 사용하여 다시 압축할 수도 있어야 합니다.

  5. 아래를 사용하여 체크포인트를 나열하여 체크포인트를 정리를 수행합니다. 체크포인트가 둘 이상 있으면 정리하십시오.

    nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-all>>nohup.out &

  6. 오프라인 압축을 실행합니다.  오프라인 압축을 실행하는 방법을 모를 경우 여기를 참조하십시오.

  7. 서버를 시작하고 색인화가 완료될 때까지 기다립니다.

Adobe 로고

내 계정 로그인