Índices corrompidos no PG12, como corrigir?

Desculpe por trazer o tópico de volta mais uma vez. Estou recebendo um erro muito estranho:

discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR:  could not create unique index "index_tags_on_name_ccnew"
DETAIL:  Key (name)=(chronicillness) is duplicated.

Estou supondo que possa ser corrigido com a solução sugerida acima pelo @riking, mas não consigo descobrir como modificar a sintaxe para atender ao meu caso. :frowning:

Veja:

https://twitter.com/petervgeoghegan/status/1264325695997538304?s=20

https://twitter.com/petervgeoghegan/status/1264404749899534338?s=20

Portanto, se você encontrar esse erro, há duas opções:

  1. Você pode contornar o problema … neste caso, a tabela tags possui uma linha duplicada com o nome chronicillness.

    1. Execute uma consulta no Explorador de Dados procurando pelas linhas: select * from tags where name = 'chronicillness.

    2. Exclua a duplicata:

      ./launcher enter app
      rails c
      Tag.find_by(id: ID_YOU_FOUND_IN_DATA_EXPLORER).destroy   
      
  2. Se você tiver um backup do seu banco de dados e detalhes que gostaria de compartilhar com Peter… compartilhe com Peter, seja de forma privada ou na lista de e-mails do PG.

Então, tenho um backup gerado pelo Discourse do PostgreSQL 10. Isso será útil? Posso apenas extrair a parte do PostgreSQL do arquivo e enviá-la?

Não tenho certeza… O que o Peter provavelmente precisará é que você pare o banco de dados e copie todo o conteúdo da pasta que o contém.

A melhor maneira de descobrir é enviando um e-mail a ele.

Claro, vou enviar um e-mail para ele para resolver isso :slight_smile:

NB: Recebi isso ao executar o SQL no explorador de dados

id name topic_count created_at updated_at pm_topic_count target_tag
1710 chronicillness 2 2019-12-03T17:49:17.395Z 2019-12-03T17:49:17.395Z 0 NULL
Tag.find_by(id: 1710).destroy

isso vai resolver?

oh … o índice está em LOWER(name)

Execute a consulta assim:

select * from tags where name ilike 'chronicillness'

Você deve obter 2 linhas.

select * from tags where name ilike 'chronicillness'
id name topic_count created_at updated_at pm_topic_count target_tag
329 chronicillness 12 2017-08-22T00:17:38.824Z 2017-08-22T00:17:38.824Z 0 NULL
1710 chronicillness 2 2019-12-03T17:49:17.395Z 2019-12-03T17:49:17.395Z 0 NULL

Será que há um - entre os nomes das tags?
Vejo duas tags aqui: chronicillness e chronic-illness.

Bem, então esse é o problema… Acho que você deleta o 1710. Depois disso, dois tópicos ficarão sem essa tag.

#<Tag:0x00005607bb92cf48
 id: 1710,
 name: "chronicillness",
 topic_count: 0,
 created_at: Tue, 03 Dec 2019 17:49:17 UTC +00:00,
 updated_at: Tue, 03 Dec 2019 17:49:17 UTC +00:00,
 pm_topic_count: 0,
 target_tag_id: nil
>

Por que sinto que foi um anão que não estava associado a nada?

A exclusão da tag trouxe mais problemas!

discourse=# REINDEX SCHEMA CONCURRENTLY public;
AVISO:  não foi possível reindexar o índice inválido "public.tags_pkey_ccnew" concorrentemente, ignorando
AVISO:  não foi possível reindexar o índice inválido "public.index_tags_on_name_ccnew" concorrentemente, ignorando
AVISO:  não foi possível reindexar o índice inválido "public.index_tags_on_lower_name_ccnew" concorrentemente, ignorando
AVISO:  não foi possível reindexar o índice inválido "pg_toast.pg_toast_309322_index_ccnew" concorrentemente, ignorando
ERRO:  não foi possível criar o índice único "index_tags_on_name_ccnew1"
DETALHE:  A chave (name)=(time-management) está duplicada.

Mesma correção :slight_smile: Você precisa repetir o processo.

Foi isso que eu estava fazendo. Mas essas advertências estão ok? Não preciso me preocupar com elas, certo?

Sim, todos os avisos estão corretos. Você tem um índice corrompido, que precisa ser corrigido primeiro.

Então, todos os clones foram removidos e agora só restam esses avisos durante a reindexação:

discourse=# REINDEX SCHEMA CONCURRENTLY public;
AVISO:  não é possível reindexar o índice inválido "public.tags_pkey_ccnew" de forma concorrente, ignorando
AVISO:  não é possível reindexar o índice inválido "public.index_tags_on_name_ccnew" de forma concorrente, ignorando
AVISO:  não é possível reindexar o índice inválido "public.index_tags_on_lower_name_ccnew" de forma concorrente, ignorando
AVISO:  não é possível reindexar o índice inválido "public.tags_pkey_ccnew1" de forma concorrente, ignorando
AVISO:  não é possível reindexar o índice inválido "public.index_tags_on_name_ccnew1" de forma concorrente, ignorando
AVISO:  não é possível reindexar o índice inválido "public.index_tags_on_lower_name_ccnew1" de forma concorrente, ignorando
AVISO:  não é possível reindexar o índice inválido "pg_toast.pg_toast_309322_index_ccnew" de forma concorrente, ignorando
AVISO:  não é possível reindexar o índice inválido "pg_toast.pg_toast_309322_index_ccnew1" de forma concorrente, ignorando
REINDEX

Há algo que deva ser feito para eliminar esses avisos ou teremos que conviver com eles?

Isso está confuso para mim… não temos nomes de índices que terminem com ccnew… você os criou manualmente?

Acho que eles são usados durante a migração do PostgreSQL 10 para o 12, pois os vi em quase todos os usuários cujos índices apresentaram problemas. Por exemplo:
https://meta.discourse.org/t/postgresql-12-update/151236/208?u=itsbhanusharma

https://meta.discourse.org/t/postgresql-12-update/151236/237?u=itsbhanusharma

EDIT: vem do próprio PostgreSQL

O método de recuperação recomendado nesses casos é excluir o índice inválido e tentar novamente executar REINDEX CONCURRENTLY. O índice concorrente criado durante o processamento tem um nome que termina com o sufixo ccnew, ou ccold se for uma definição antiga de índice que não conseguimos excluir. Índices inválidos podem ser excluídos usando DROP INDEX, incluindo índices toast inválidos.

Ouch … os índices corretos já estão na tabela também?

Acho que você pode listar os índices na tabela usando o Data Explorer.

Se os corretos estiverem lá, você pode simplesmente descartar esses índices problemáticos.

Deixe-me verificar. Eu retorno com o resultado.

Então, parece que os índices existem

Índices duplicados também existem para índices problemáticos, com ccnew ou ccnew1 adicionados

Não sei de uma maneira de verificar se esses índices são válidos, mas se removê-los é uma opção, ficarei feliz em removê-los e reindexar.

EDIT: DROP INDEX funcionará como sugerido aqui?

Sim, solte todos… não tenho ideia de como eles chegaram lá… DROP INDEX é o que você deve usar.

./launcher enter app
rails c
DB.exec('drop index tags_pkey_ccnew1')