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 대신 를 클릭합니다.

확인 및 복원을 수행하려면 다음 단계를 수행합니다.

  1. 다운로드 oak-run jar 파일 위치 https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/

  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 files. 파일을 제거합니다.

  6. AEM 6.0을 사용하는 경우 나머지 단계에 대해 AEM에 설치된 버전과 일치하는 oak-run 버전을 다운로드합니다.

    여기에서 다운로드하십시오. https://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 실행 콘솔을 사용하고 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)

  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 매개변수:

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

  5. 아래 체크포인트를 나열하여 체크포인트 정리를 수행합니다.

    체크포인트가 한 개 이상인 경우 정리합니다.

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

  6. 오프라인 압축을 실행합니다.

    오프라인 압축을 실행하는 방법을 모를 경우 다음을 참조하십시오. Oak 오프라인 압축 지침 GitHub Gist에서

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

원인
A SegmentNotFoundException 압축이 노드 읽기를 시도하는 동안 세그먼트가 없는 경우 가 반환됩니다.

이에 대한 근본 원인은 다음과 같이 다양할 수 있습니다.

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

수정 가비지 수집으로 인해 문제가 발생하는 경우(원인 #2) 추가 노드가 손상되지 않도록 온라인 압축을 비활성화해야 합니다.

recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f