SegmentNotFoundException および IllegalArgumentException

オフライン コンパクションの実行は、SegmentNotFoundException​または​ IllegalArgumentException ​で失敗する可能性があります。 この記事では、エラーを解決し、オフラインコンパクションを正常に完了する方法について説明します。 ただし、続行する前に、リポジトリの完全バックアップを実行してください。

説明 description

環境

Adobe Experience Manager(AEM)

問題

シナリオ 1
オフラインコンパクションの実行は、リポジトリの整合性に問題がある場合、SegmentNotFoundException​で失敗する可能性があります。

AEM ログファイルに​ SegmentNotFoundException ​が記録されていますが、AEMは期待どおりに動作していません。

シナリオ 2

オフラインコンパクションの実行は、リポジトリの整合性に問題がある場合、SegmentNotFoundException​で失敗する可能性があります。

次のようなスタックトレースがログに表示されます。

13:51:21.523 [ main]  ERROR o.a.j.o.p.segment.SegmentTracker - Segment not found: 4d139bc4-150c-4f0a-b82a-4867593098a. Creation date delta is 4 ms.
org.apache.jackrabbit.oak.plugins.segment.SegmentNotFoundException: Segment 4d139bc4-150c-4f0a-b82a-4867593098a 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-4867593098a 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

オフラインコンパクションの実行は、リポジトリの整合性に問題がある場合、IllegalArgument Exceptionで失敗する可能性があります。

次のようなスタックトレースがログに表示されます。

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のcheck run-modeを使用すると、セグメントストアの最後の既知の正常なリビジョンを判断できます。
これにより、破損したセグメントストアを最新の適切なリビジョンに手動で戻すことができます。

*注意:*このプロセスは、システム内のデータを前の時点にロールバックします。
システムの変更を失わないようにするには、代わりに以下の オプション 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-aa1b1b-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. 破損しているノードを手動で削除する。

TarMK に FileDatastore が設定されていない場合や、バイナリが破損している場合、AEM で次の操作を実行できます。

  • 注意:*以下の手順は、パワーユーザーを対象としています。
    破損したノードを削除する場合は、それらがシステムノード(/home/jcr:systemなど)でないことを確認する必要があります .
    システムノードの場合は、復元する必要があります。
    不明な場合は、AEM カスタマーケアチームに問い合わせて、ここに記載されている手順を確認してください。
  1. AEM を停止します。

  2. Oak実行コンソールを使用し、childCount groovy スクリプトを読み込んで、セグメントストア内の破損したノードを特定します。

    oak-run コンソールシェルを読み込みます。

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

    次の 2 つのコマンドをシェルで実行してスクリプトを読み込み、実行します。

    :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 パラメーターを設定します。

    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 コマンドを再実行して、3つの破損したパスが見つかったことを確認します。

    次回の実行では、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. オフライン圧縮を実行します。

    オフラインコンパクションの実行方法がわからない場合は、GitHub GistのOak オフラインコンパクションの手順を参照してください。

  7. サーバーを起動し、インデックス作成の完了を待ちます。

原因
コンパクションがノードを読み取ろうとするときにセグメントが存在しない場合、SegmentNotFoundException​が返されます。

これには様々な根本原因があります。

  1. セグメントは手動の介入によって削除されました(例:rm -rf / )。
  2. セグメントがリビジョンガベージコレクションによって削除された。
  3. コードのバグが原因でセグメントが見つからない。

リビジョンガベージコレクション(原因#2)が原因で問題が発生した場合は、それ以上のノードが破損しないように、オンラインコンパクションが無効になっていることを確認してください。

recommendation-more-help
experience-cloud-kcs-help-kbarticles