AEM 6.x에서 문제가 보고될 때 SegmentNotFoundException을 디버깅하는 방법

이 문서는 마지막으로 알려진 세그먼트 스토어 수정 버전으로 되돌려 AEM 6.x에서 문제가 보고될 때 SegmentNotFoundException을 디버깅하는 방법을 이해하는 데 도움이 됩니다.

설명 description

환경

Experience Manager 6.x

문제/증상

오류 로그는 다음 예제와 같이 SegmentNotFound 예외를 표시합니다.

org.apache.jackrabbit.oak.segment.SegmentNotFoundException: Segment d2c720c4-c146-4ab1-ac37-542aad93c33f not found at

org.apache.jackrabbit.oak.segment.file.FileStore$8.call(FileStore.java:602) at

org.apache.jackrabbit.oak.segment.file.FileStore$8.call(FileStore.java:542) at

org.apache.jackrabbit.oak.segment.SegmentCache.getSegment(SegmentCache.java:95) at

org.apache.jackrabbit.oak.segment.file.FileStore.readSegment(FileStore.java:542) at

org.apache.jackrabbit.oak.segment.SegmentId.getSegment(SegmentId.java:125) at

org.apache.jackrabbit.oak.segment.Record.getSegment(Record.java:70) at

org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:424) at

org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:433) at

org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:391) at

org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:608) at

org.apache.jackrabbit.oak.spi.commit.EditorDiff.childNodeChanged(EditorDiff.java:148) at

org.apache.jackrabbit.oak.segment.MapRecord$3.childNodeChanged(MapRecord.java:442) at

org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:490) at

org.apache.jackrabbit.oak.segment.MapRecord.compare(MapRecord.java:433) at

org.apache.jackrabbit.oak.segment.SegmentNodeState.compareAgainstBaseState(SegmentNodeState.java:608) at

org.apache.jackrabbit.oak.spi.commit.EditorDiff.process(EditorDiff.java:52) at

org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.updateIndex(AsyncIndexUpdate.java:695) at

org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.runWhenPermitted(AsyncIndexUpdate.java:543) at

org.apache.jackrabbit.oak.plugins.index.AsyncIndexUpdate.run(AsyncIndexUpdate.java:402) at

org.apache.sling.commons.scheduler.impl.QuartzJobExecutor.execute(QuartzJobExecutor.java:118) at

org.quartz.core.JobRunShell.run(JobRunShell.java:202) at

java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at

java.lang.Thread.run(Thread.java:745)

해결 방법 resolution

해결 단계

두 가지 방법으로 문제를 해결하고 저장소에서 불일치를 제거할 수 있습니다

마지막으로 알려진 세그먼트 저장소 수정 버전으로 되돌리기.

첫 번째,  oak 실행 도구를 사용하십시오. 이 도구는 간단한 Oak 설치 및 oak 관련 작업 수행에 필요한 모든 것을 포함하는 실행 가능한 jar [ 1]입니다.

oak-run의 점검 실행 모드를 사용하여 마지막으로 알려진 세그먼트 스토어 수정을 확인할 수 있습니다.  수동으로 손상된 세그먼트 스토어를 최신 버전으로 되돌리는 데 사용할 수 있습니다.

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

확인 및 복원하려면

  1. https://mvnrepository.com/artifact/org.apache.jackrabbit/oak-run에서 Oak 코어 버전과 일치하는 oak-run 버전을 다운로드합니다.

  2. 손상된 세그먼트 저장소를 양호한 최신 상태로 되돌리려면 CQ의 작업 디렉터리(crx-quickstartfolder가 포함된 디렉터리)로 변경하고 의 모든 파일을 백업합니다./crx-quickstart/repository/segmentstore/

  3. 일관성 검사를 실행하고

    java -Xmx6000m -jar oak-run-*.jar check —bin=-1 /path/to/crx-quickstart/repository/segmentstore

    일관된 버전을 찾을 때까지 수정 버전을 뒤로 검색합니다.

    다음과 같이 메시지를 검색합니다.

    code language-none
    main INFO o.a.j.o.p.s.f.t.ConsistencyChecker - Found latest good revision afdb922d-ba53-4a1b-aa1b-1cb044b535cf:234880
    
  4. 를 편집하여 저장소를 이 수정 버전으로 되돌립니다./crx-quickstart/repository/segmentstore/journal.log 및 최신 수정 버전이 포함된 줄 다음의 모든 줄을 삭제합니다.

  5. 모두 제거 ./crx-quickstart/repository/segmentstore/*.bak 파일.

  6. 다음 명령을 사용하여 체크포인트 정리를 실행하여 고립된 체크포인트를 제거합니다.

    code language-none
    java -Xmx6000m -jar oak-run-*.jar checkpoints /path/to/crx-quickstart/repository/segmentstore rm-unreferenced
    
  7. 마지막으로 저장소 압축:

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

Check 명령을 실행하는 동안 oak 실행 검사에서 올바른 수정 버전을 찾을 수 없고 "ConsistencyChecker - 올바른 수정 버전이 없습니다"가 표시되는 경우가 있습니다.

일관성 검사에서 "ConsistencyChecker - 좋은 수정 버전을 찾을 수 없음"이 발생할 때 손상을 해결하는 방법

수동으로 손상된 노드 제거.

AEM, FileDatastore가 구성되지 않은 TarMK 설정 및 바이너리에 손상이 있는 상황에서 다음 작업을 수행할 수 있습니다.

주의: 아래 절차는 고급 사용자를 위한 것입니다.  손상된 노드를 삭제할 때 시스템 노드가 아닌지 확인해야 합니다(예: /home, /jcr:system 등).  시스템 노드인 경우 복원할 수 있는지 확인해야 합니다.  잘 모르는 경우 여기에 설명된 단계에 도움이 필요하면 AEM 고객 지원 센터에 문의하십시오.

  1. AEM을 중지합니다.

  2. Oak 실행 콘솔을 사용하고 childCount groovy 스크립트를 로드하여 세그먼트 스토어에서 손상된 노드를 식별합니다.

    oak-run 콘솔 셸 로드:

    code language-none
    java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore
    

    셸에서 아래 두 명령을 실행하여 스크립트를 로드하고 실행합니다.

    code language-none
    :load https://gist.githubusercontent.com/stillalex/e7067bcb86c89bef66c8/raw/d7a5a9b839c3bb0ae5840252022f871fd38374d3/childCount.groovy
    countNodes(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 스크립트가 손상된 노드를 찾을 수 없는 경우가 있습니다.  이러한 경우 대신 다음 명령을 사용할 수 있습니다. 이 명령은 순회 중에 발견된 모든 바이너리의 처음 1,024바이트를 읽습니다(이 명령은 속도가 느려지고 위의 명령이 예상 결과를 반환하지 않을 때만 사용해야 함).

    code language-none
    countNodes(session.workingNode,true)
    
  3. rmNodes.groovy를 사용하여 마지막 명령의 출력에 나열된 식별된 손상 노드를 모두 제거합니다.
    아래 명령을 사용하여 oak-run 콘솔 셸을 로드합니다.

    code language-none
    java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore
    

    Groovy 스크립트 로드:

    code language-none
    :load
    https://gist.githubusercontent.com/stillalex/43c49af065e3dd1fd5bf/raw/9e726a59f75b46e7b474f7ac763b0888d5a3f0c3/rmNode.groovy
    

    rmNode 명령을 실행하여 손상된 노드를 제거하고 /path/to/corrupt/node 를 제거해야 하는 손상된 노드에 대한 경로로 바꿉니다.

    code language-none
    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 의 패치 버전을 사용하십시오. 이 버전의 jar는 압축 시 읽을 수 없는 바이너리를 건너뛰고 0바이트 바이너리로 바꾸고 예외 및 syserr 경로를 기록합니다. 압축한 결과 저장소는 oak-run 점검 및 노드 수 스크립트를 통과하고, 패치되지 않은 oak-run을 사용하여 다시 압축할 수도 있어야 합니다.

  5. 아래 체크포인트를 나열하여 체크포인트 정리를 수행합니다. 체크포인트가 두 개 이상인 경우 정리합니다.

    code language-none
    nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-allnohup.out
    
  6. 오프라인 압축을 실행합니다. 오프라인 압축을 실행하는 방법을 모를 경우 여기를 참조하십시오.

  7. 인덱싱이 완료될 때까지 서버를 시작합니다.

원인

오류 로그에 있는 SegmentNotFoundException은 다른 사용자가 해당 세그먼트에 계속 액세스하려고 하지만 해당 세그먼트가 더 이상 존재하지 않음을 의미합니다. 여기에는 크게 세 가지 다른 근본 원인이 있습니다. 수동 개입으로 세그먼트가 제거되었거나(예: rm -rf /), 수정 가비지 수집으로 세그먼트가 제거되었거나, 코드의 일부 버그로 인해 세그먼트를 찾을 수 없습니다.

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