Baixe o arquivo jar do oak-run a partir daqui http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/
Executando SegmentNotFoundException quando há problemas de integridade do repositório.
Problema
Você observa o SegmentNotFoundException nos arquivos de log do AEM e o AEM não está funcionando conforme o esperado
OU
A execução de uma compactação offline poderá falhar com SegmentNotFoundException quando houver problemas de integridade do repositório. Um encadeamento de pilha similar ao abaixo poderá ser encontrado nos logs:
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) ...
OU
A execução de uma compactação offline poderá falhar com IllegalArgumentException quando houver problemas de integridade do repositório. Um encadeamento de pilha similar ao abaixo poderá ser encontrado nos logs:
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)
Ambiente
AEM 6.x
Causa
Um SegmentNotFoundException é retornado quando um segmento não está presente enquanto a compactação tenta ler o nó. Pode haver diferentes causas-raiz para isso:
- O segmento é removido por intervenção manual (por exemplo, rm -rf/).
- O segmento foi removido pela coleção de lixo de revisão.
- O segmento não pode ser encontrado devido a um erro no código.
No caso, o problema é causado pela coleção de lixo de revisão (Ponto 2). Certifique-se de que a compactação online esteja desabilitada para evitar que outros nós sejam corrompidos.
Solução
Existem vários procedimentos que podemos seguir para resolver a situação e concluir a compactação offline com êxito.
Importante: execute um back-up completo do seu repositório antes de seguir as etapas abaixo.
A. Reverta para a última revisão válida do armazenamento de segmento.
O modo de verificação run-mode do oak-run poderá ser usado para determinar a última revisão válida de um armazenamento de segmentos. Isso poderá ser usado para reverter manualmente um armazenamento de segmento corrompido para a última revisão válida.
Este processo irá reverter os dados no sistema para um ponto anterior no tempo. Caso deseje evitar a perda de alterações no seu sistema, então você poderá tentar a opção B abaixo.
Para executar a verificação e restauração:
-
-
Pare o AEM.
-
Execute o comando:
java -jar oak-run-*.jar check --bin=-1 crx-quickstart/repository/segmentstore/
Este comando procura para trás através das revisões até encontrar uma consistente:
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
(Caso o ConsistencyChecker falhe, vá para a próxima seção)
-
Reverta o repositório para esta revisão por meio de edição.
/crx-quickstart/repository/segmentstore/journal.log.
Exclua todas as linhas após a linha que contém a última revisão válida. Se você quiser descobrir a data e a hora para as quais você está revertendo o repositório, execute este comando na pasta do repositório de segmentos (substitua afdb922d-ba53-4a1b-aa1b-1cb044b535cf pela última revisão válida em seu journal.log):
find . -type f -name "data*.tar" -exec sh -c "tar -tvf {} |grep afdb922d-ba53-4a1b-aa1b-1cb044b535cf" \; -print
A saída mostraria uma data e hora aproximadas dessa revisão.
-
Remova tudo ./crx-quickstart/repository/segmentstore/*.bak.
-
Se estiver usando o AEM 6.0, baixe a versão do oak-run que corresponde ao que está instalado no AEM para as etapas restantes. Baixe aqui http://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/.
-
Execute a limpeza de pontos de verificação para remover pontos de verificação órfãos:
java -jar oak-run-*.jar checkpoints ./crx-quickstart/repository/segmentstore rm-unreferenced.
-
Por fim, compacte o repositório:
java -jar oak-run-*.jar compact ./crx-quickstart/repository/segmentstore/
B. Remova os nós corrompidos manualmente.
No AEM, as configurações do TarMK sem o FileDatastore configurado e nas situações em que a corrupção está nos binários, você poderá fazer o seguinte.
O procedimento abaixo destina-se a usuários avançados. Ao excluir os nós corrompidos, você precisa ter certeza de que eles não são nós do sistema (como /home, /jcr: system, etc). Ou se eles são nós do sistema, então você precisa ter certeza de que pode restaurá-los. Consulte a equipe de Atendimento ao Cliente da AEM para obter ajuda com as etapas documentadas aqui se você estiver inseguro.
-
Pare o AEM.
-
Use o console do Oak-run e carregue o script groovy childCount para identificar os nós corrompidos no armazenamento de segmento:
Carregue o shell do console do oak-run:
java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore
Execute os dois comandos abaixo no shell para carregar o script e executá-lo:
:load https://gist.githubusercontent.com/stillalex/e7067bcb86c89bef66c8/raw/d7a5a9b839c3bb0ae5840252022f871fd38374d3/childCount.groovy
countNodes(session.workingNode)
Isso resulta no seguinte resultado indicando o caminho para o(s) nó(s) corrompido(s):
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:contentEm alguns casos, o problema está vinculado a propriedades binárias e o script groovy childCount não consegue localizar nenhum nó corrompido. Nesses casos, você poderá usar o seguinte comando, que lerá os primeiros 1024 bytes para cada binário encontrado durante a travessia (observe que este comando será mais lento e só deverá ser usado quando o acima não retornar os resultados esperados):
countNodes(session.workingNode,true)
-
Remova todos os nós corrompidos identificados listados na saída do último comando usando rmNodes.groovy
Carregue o shell do console do oak-run:
java -jar oak-run-*.jar console crx-quickstart/repository/segmentstore
Carregue o script groovy:
:load https://gist.githubusercontent.com/stillalex/43c49af065e3dd1fd5bf/raw/9e726a59f75b46e7b474f7ac763b0888d5a3f0c3/rmNode.groovy
Execute o comando rmNode para remover o nó corrompido, substitua /path/to/corrupt/node pelo caminho do nó corrompido que você precisa remover.
rmNode(session, "/path/to/corrupt/node")
Onde o caminho do nó corrompido é o caminho obtido na etapa 2, por exemplo: "/content/dam/test.txt/jcr:content/renditions/original/jcr:content/"
Observação:Ao usar o oak-run.jar versão 1.6.13 e superior, defina o parâmetro da JVM --read-write se encontrar um erro como:
/> 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) -
Repita o passo 3 para todos os nós encontrados no passo 2.
Esse comando rmNode acima deverá retornar true para o caminho corrompido, o que significa que ele foi excluído. Certifique-se de que esses três caminhos corrompidos foram excluídos, executando novamente o comando rmNode nesses caminhos. A próxima execução deverá retornar false.
Caso ainda veja que os mesmos caminhos estão no repositório, então use a versão corrigida do jar do oak-run, ou seja, oak-run-1.2.18-NPR-17596
O que a versão corrigida do Oak run Jar faz?
Esta versão do jar pula os binários ilegíveis na compactação substituindo-os por binários de 0 bytes e registrando a exceção e o caminho no syserr. O repositório assim compactado deverá então passar a verificação oak-run, o script de contagem de nós e você também deverá ser capaz de compactá-lo novamente usando uma oak-run não corrigida.
-
Realize uma limpeza de pontos de verificação listando os pontos de verificação usados abaixo. Se houver mais de um ponto de verificação, limpe-os:
nohup java -Xmx4096m -jar oak-run-1.2.18.jar checkpoints /app/AEM6/author/crx-quickstart/repository/segmentstore rm-all>>nohup.out &
-
Execute uma compactação offline. Se você não souber como executar a compactação offline, consulte aqui.
-
Inicie o servidor e aguarde a conclusão da indexação.