Ambiente
Experience Manager
Problema/Sintomas
Cenário 1
A execução de uma compactação offline pode falhar com SegmentNotFoundException quando houver problemas de integridade do repositório.
Você observa SegmentNotFoundException nos arquivos de log do AEM e o AEM não está funcionando como esperado.
Cenário 2
A execução de uma compactação offline pode falhar com SegmentNotFoundException quando houver problemas de integridade do repositório.
Um rastreamento de pilha semelhante ao abaixo é exibido 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)
...
Cenário 3
A execução de uma compactação offline pode falhar com IllegalArgument Exceção quando há problemas de integridade do repositório.
Um rastreamento de pilha semelhante ao abaixo é exibido 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)
Solução
Existem vários procedimentos que podemos seguir para resolver a situação e concluir a compactação offline com êxito.
Importante: faça um backup completo do seu repositório antes de seguir as etapas abaixo.
A. Reverta para a última revisão válida do armazenamento de segmentos.
O modo de verificação de execução do oak-run pode ser usado para determinar a última revisão válida de um armazenamento de segmento.
Isso pode ser usado para reverter manualmente um armazenamento de segmento corrompido para sua última revisão válida.
Cuidado: esse processo reverterá os dados no sistema para um ponto no tempo anterior.
Se você quiser evitar a perda de alterações em seu sistema, tente Opção B abaixo em vez disso.
Para executar a verificação e restauração, siga estas etapas:
Baixe o oak-run
Arquivo jar de aqui https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/
Pare o AEM.
Execute este comando:
java -jar oak-run-*.jar check --bin=-1 crx-quickstart/repository/segmentstore/
Este comando faz uma pesquisa retroativa nas 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 essa revisão ao editar:
/crx-quickstart/repository/segmentstore/journal.log
Exclua todas as linhas após a linha que contém a última revisão válida.
Se quiser descobrir a data e a hora em que o repositório está sendo revertido, execute este comando no segmentstore
pasta (substituir afdb922d-ba53-4a1b-aa1b-1cb044b535cf com a última boa revisão 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.
Remover tudo ./crx-quickstart/repository/segmentstore/*.bak files.
Se estiver usando o AEM6.0, baixe a versão do oak-run que corresponde ao que está instalado no AEM para as etapas restantes.
Baixe aqui https://repo1.maven.org/maven2/org/apache/jackrabbit/oak-run/.
Executar limpeza de ponto 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, em configurações do TarMK sem o FileDatastore configurado e em situações em que a corrupção está nos binários, você pode fazer o seguinte.
Cuidado: o procedimento abaixo é destinado a usuários avançados.
Ao excluir os nós corrompidos, você precisa garantir que eles não sejam nós do sistema (como /home
, /jcr:system
, etc.).
Ou, se eles forem nós do sistema, você precisa garantir que possa restaurá-los.
Consulte a Equipe de atendimento ao cliente do AEM para obter assistência com as etapas documentadas aqui, caso não tenha certeza.
Pare o AEM.
Use o console de execução do Oak e carregue o childCount
script groovy para identificar os nós corrompidos no armazenamento de segmentos:
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 na seguinte saída 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:content
Em alguns casos, o problema está vinculado a propriedades binárias e à variável childCount
o script groovy não consegue localizar nenhum nó corrompido.
Nesses casos, você pode 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 comando 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 para o 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 oak-run.jar
versão 1.6.13 e superior, definir --read-write
Parâmetro JVM se você 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 a etapa 3 para todos os nós encontrados na etapa 2.
O comando rmNode
acima deve retornar verdadeiro para o caminho corrompido, o que significa que ele o excluiu.
Verifique se esses três caminhos corrompidos foram excluídos executando novamente o comando rmNode
nesses caminhos.
Para a próxima execução, ele deve retornar false
.
Se você ainda vir que os mesmos caminhos estão no repositório, use a versão corrigida do jar de execução do oak (ou seja, oak-run-1.2.18-NPR-17596).
O que a versão corrigida do jar de execução do oak faz?
Esta versão do jar ignora binários ilegíveis na compactação, substituindo-os por binários de 0 bytes e registrando a exceção e o caminho para o servidor.
O repositório assim compactado deve passar na verificação oak-run e no script de contagem de nós, e você também deve ser capaz de compactá-lo novamente usando uma oak-run não corrigida.
Execute uma limpeza de ponto de verificação listando pontos de verificação seguindo as etapas 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.
Caso não saiba como executar a compactação offline, consulte Instruções de compactação offline do Oak no GitHub Gist.
Inicie o servidor e aguarde a conclusão da indexação.
Causa
A SegmentNotFoundException é retornado quando um segmento não está presente enquanto a compactação tenta ler o nó.
Pode haver diferentes causas raiz para isso:
Caso o problema seja causado pela coleção de lixo de revisão (Causa #2), verifique se a compactação online está desativada para evitar que outros nós sejam corrompidos.