AEM記錄檔中的SegmentNotFoundException和執行個體無法運作

瞭解如何使用下列步驟解決AEM記錄和執行個體中的SegmentNotFoundException問題。

注意:在執行步驟之前,請先對存放庫執行完整備份。

說明 description

環境

Adobe Experience Manager (AEM) 6.x

問題/症狀

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

當存放庫中有完整性問題時,執行離線壓縮可能會失敗並出現IllegalArgument例外狀況。 可以在記錄中找到類似以下的棧疊追蹤

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

第一個方法

  1. 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 xxxx000x-ba53-4a1b-aa1b-0xx000x000xx:234880

    注意: 如果ConsistencyChecker失敗,請移至下一節。

  4. 透過編輯以下給定的命令將存放庫恢復到此版本。
    /crx-quickstart/repository/segmentstore/journal.log.

    將包含最新良好修訂的行之後的所有行刪除。若要瞭解需要還原到存放庫的日期和時間,請在segmentstore資料夾中執行此命令(以xxxx000x-ba53-4a1b-aa1b-0xx000x000xx中的最新良好修訂取代journal.log):

    find . -type f -name "data*.tar" -exec sh -c "tar -tvf {} |grep xxxx000x-ba53-4a1b-aa1b-0xx000x000xx" \; -print

    輸出將顯示該修訂的大致日期和時間。

  5. 移除所有./crx-quickstart/repository/segmentstore/*.bak files

  6. 如果使用AEM 6.0,則下載與AEM中已安裝版本相符的Oak-run版本以完成其餘步驟。 從此連結下載: 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/

第二個方法

手動移除損壞的節點。

在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)

    • 這會導致以下輸出指示損壞節點的路徑:

      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指令碼無法找到任何損壞的節點。 在這些情況下,您可以改用以下命令,它將讀取周遊期間遇到的每個二進位檔案的前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引數:

    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. (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-00000

    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. 執行離線壓縮。 在瞭解如何執行離線壓縮

  7. 啟動伺服器並等待索引完成。

原因

如果在壓縮嘗試讀取節點時區段不存在,則會傳回SegmentNotFoundException。 對此可能有不同的根本原因:

  1. 該區段已被手動介入移除 (例如 rm -rf /)。
  2. 該區段已被修訂垃圾收藏集移除。
  3. 由於程式碼中的錯誤,無法找到該區段。

如果問題是由修訂垃圾收藏集(第2點)所造成,請確定已停用線上壓縮,以避免進一步的節點損毀。

在我們的Experience League Campaign社群中提問

若您有任何關於此主題的疑問或想閱讀之前的已回答問題,請檢視包含本文的Experience League社群部落格,傳送您的問題和意見給我們,並加入我們的Experience League Campaign社群!

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