SegmentNotFoundException および IllegalArgumentException

説明

環境
Adobe 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

オフライン圧縮の実行は、 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)

原因

A SegmentNotFoundException コンパクションがノードを読み込もうとしている間にセグメントが存在しない場合、が返されます。
これには様々な根本原因があります。

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

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

解決策

ソリューション

この状況を解決し、オフライン圧縮を正常に完了するために、いくつかの手順を実行できます。

重要:​次の手順を実行する前に、リポジトリの完全バックアップを実行してください。

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-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. 破損しているノードを手動で削除する。

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 パラメーター

    / rmNode(session,"/path/to/corrupt/node")Removing node /path/to/corrupt/nodeERROR java.lang.UnsupportedOperationException:Cannot write to read-only storeat 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 が返されます。これは、コマンドによってパスが削除されたことを意味します。

    次のコマンドを再実行して、3 つの破損したパスが削除されたことを確認します。 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-allnohup.out &

  6. オフライン圧縮を実行します。

    オフライン圧縮の実行方法がわからない場合は、 Oak オフライン圧縮の手順 (GitHub Gist) を参照してください。

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

このページ