SegmentNotFoundException e IllegalArgumentException
A execução de uma compactação offline pode falhar com SegmentNotFoundException ou IllegalArgumentException. Este artigo discute maneiras de resolver os erros e concluir a compactação offline com êxito. No entanto, antes de continuar, faça um backup completo do seu repositório.
Descrição description
Ambiente
Adobe Experience Manager (AEM)
Problema
Cenário 1
A execução de uma compactação offline poderá falhar com SegmentNotFoundException quando houver problemas de integridade do repositório.
Você observa SegmentNotFoundException em arquivos de log AEM e AEM não está funcionando como esperado.
Cenário 2
A execução de uma compactação offline poderá 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-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)
...
Cenário 3
A execução de uma compactação offline poderá falhar com a Exceção IllegalArgument quando houver 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)
Resolução resolution
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 a Opção B abaixo.
Para executar a verificação e restauração, siga estas etapas:
-
Baixe o arquivo jar
oak-run
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.)
-
Reverter o repositório para esta 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 na pasta
segmentstore
(substitua afdb922d-ba53-4a1b-aa1b-1cb044b535cf pela última boa revisão nojournal.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 AEM 6.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/.
-
Execute a 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 script groovy
childCount
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 é vinculado a propriedades binárias e o script groovy
childCount
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 ooak-run.jar
versão 1.6.13 e superior, configure o parâmetro JVM--read-write
se você encontrar um erro como: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)
-
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 (ex.: 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.
Se você não souber 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
Uma SegmentNotFoundException é retornada quando um segmento não está presente enquanto a compactação tenta ler o nó.
Pode haver diferentes causas raiz para isso:
- O segmento foi removido por intervenção manual (Por exemplo: rm -rf /).
- O segmento foi removido pela coleta de lixo de revisão.
- O segmento não pode ser encontrado devido a algum erro no código.
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.