Falha na restauração do backup

Estou com o seguinte problema. Tenho um fórum Discourse em funcionamento há mais de 10 anos e, como não tenho conseguido instalar atualizações há algum tempo, decidi configurar um novo servidor:

Servidor antigo: 3.4.0.beta4-dev

Novo servidor: Versão mais recente

O backup já tem 673,2 MB como arquivo .gz, excluindo os uploads.

Infelizmente, a restauração está sendo abortada repetidamente. O arquivo de log contém este erro:

[2026-06-16 07:54:52] ERROR:  could not create unique index “index_incoming_referers_on_path_and_incoming_domain_id”
[2026-06-16 07:54:52] DETAIL:  Key (path, incoming_domain_id)=(//, 5) is duplicated.
[2026-06-16 07:54:52] EXCEPTION: psql failed: DETAIL:  Key (path, incoming_domain_id)=(//, 5) is duplicated.

[2026-06-16 07:54:52] /var/www/discourse/lib/backup_restore/database_restorer.rb:93:in 'BackupRestore::DatabaseRestorer#restore_dump'
/var/www/discourse/lib/backup_restore/database_restorer.rb:26:in ‘BackupRestore::DatabaseRestorer#restore’
/var/www/discourse/lib/backup_restore/restorer.rb:61:in 'BackupRestore::Restorer#run'
/var/www/discourse/script/spawn_backup_restore.rb:20:in ‘Object#restore’
/var/www/discourse/script/spawn_backup_restore.rb:33:in ‘block in ’
/var/www/discourse/script/spawn_backup_restore.rb:4:in 'Kernel#fork'
/var/www/discourse/script/spawn_backup_restore.rb:4:in ‘’
[2026-06-16 07:54:52] Trying to rollback...

O que posso fazer para resolver esse problema e não perder os últimos 10 anos de dados?

Agradeço antecipadamente qualquer ajuda!

Olá e, uau, bem-vindo de volta após 9 anos!

É bem legal ver um fórum que está no ar há tanto tempo.

Acho que este é o mesmo problema de índice mencionado aqui: Can't restore due to corrupt indexes (with some clues on how to deal with corrupt indexes)

É algo assim:

A tabela incoming_referers rastreia os caminhos de URL que referenciaram visitantes ao seu fórum. Ela possui um índice único, o que significa que não pode haver duas linhas com a mesma combinação de caminho + domínio.

Seu banco de dados possui duas linhas com path='//' e incoming_domain_id=5. Quando tenta reconstruir este índice único durante a restauração, ele encontra a duplicata e aborta toda a transação de restauração.

Então, você precisará encontrar e limpar essa duplicata em incoming_referers e, em seguida, criar um novo backup para restaurar no novo servidor.

Eu encontrei este tópico com instruções que pode te ajudar.

Muito obrigado pela resposta rápida; vou tentar isso!

(postagem apagada pelo autor)

Desculpe incomodar, mas acho que estou fazendo algo errado — após executar o comando “discourse=# select * from incoming_referers where path LIKE ‘%/search/’ ORDER BY incoming_domain_id;”, estou recebendo um erro de sintaxe.

Você digitou “discourse=#”? Se sim, tente novamente sem isso.

Então, recebo a mensagem de erro “bash: syntax error near unexpected token `from’”

Para referência, estou atualmente em: root@community-app:/var/www/discourse#

Ah, você ainda não está no banco de dados.

Primeiro, execute psql -U discourse discourse (acho que é isso)

E então, o prompt deve mudar para discourse=#

Ok, agora também instalei “apt install postgresql-client-common”. No entanto, ainda estou recebendo o erro “Erro: Você deve instalar pelo menos um pacote postgresql-client-.”

Isso eu não sei.

Talvez tente diretamente pelo console do Rails então: rails c

com

ActiveRecord::Base.connection.execute(<<~SQL)
  SELECT id, path, incoming_domain_id 
  FROM incoming_referers 
  WHERE path = '//' 
  AND incoming_domain_id = 5
SQL

Isso pode te dar o mesmo resultado sem passar pelo banco de dados.

Funciona?

Sinto muito, muito mesmo, por ter agido de forma tão boba.

Instalei o Rails agora e parece que funcionou. Também o executei com “rails c”. Parece funcionar também, mas quando eu digito o comando, fica assim:

“root@community:/var/discourse# ActiveRecord::Base.connection.execute(<<~SQL)
-bash: erro de sintaxe próximo do token inesperado `<<’
root@community:/var/discourse# SELECT id, path, incoming_domain_id
SELECT: comando não encontrado
root@community:/var/discourse# FROM incoming_referers
FROM: comando não encontrado
root@community:/var/discourse# WHERE path = ‘//’
WHERE: comando não encontrado
root@community:/var/discourse# AND incoming_domain_id = 5
AND: comando não encontrado
root@community:/var/discourse# SQL”

Não se preocupe, talvez minhas instruções não sejam tão boas assim :slight_smile:

Fico confuso quando você diz que acabou de instalar o Rails e não consegue acessar seu banco de dados. Talvez seja tudo diferente porque é uma versão mais antiga, mas acho que também estou fora da minha zona de conforto agora.

De qualquer forma, assim que você estiver no Rails, o prompt deve ser diferente, então, pela sua saída, parece que você ainda não está no console do Rails.

Acho que você nem está no container propriamente dito. Você já fez ./launcher enter app?

OK, sim, esse era o problema. A consulta foi executada com sucesso agora, e eu recebi esta resposta:

#<PG::Result:0x00007fbde9732ef0 status=PGRES_TUPLES_OK ntuples=1 nfields=3 cmd_tuples=1>

Então, ntuples=1 significa que apenas uma linha foi encontrada, mas, de acordo com o log de erros, deveria haver uma duplicata… :woman_shrugging:

Desculpe, não sei mais o que tentar. Recomendo dar uma olhada no fórum; parece haver muitos casos semelhantes (veja abaixo, na seção relacionada). Talvez você encontre a próxima dica lá.

(Ou espere até que alguém mais experiente passe por aqui ;))

Parece que seu servidor antigo não é uma instalação padrão. De qualquer forma,… em resumo: um índice no seu servidor antigo ficou corrompido ao longo dos anos (isso pode acontecer após atualizações do sistema operacional), então duas linhas idênticas acabaram entrando na tabela incoming_referers. O backup as copia exatamente como estão, e o novo servidor então as recusa. Portanto, primeiro corrigimos isso no servidor antigo e, em seguida, fazemos um novo backup.

No servidor ANTIGO, abra o console do Rails:

./launcher enter app
rails c

Em seguida, cole as seguintes linhas, uma após a outra:

db = ActiveRecord::Base.connection.current_database
DB.exec("DELETE FROM incoming_referers a USING incoming_referers b WHERE a.id > b.id AND a.path = b.path AND a.incoming_domain_id = b.incoming_domain_id")
DB.exec("REINDEX DATABASE #{ActiveRecord::Base.connection.quote_table_name(db)}")

Isso remove a duplicata e recria todos os índices (caso outras tabelas também tenham sido afetadas).

Se o REINDEX terminar sem erros, digite exit, faça um backup recente no servidor antigo e restaure esse novo arquivo. Se aparecer um erro sobre outra tabela, apenas cole-o aqui.

Muito obrigado. Infelizmente, estou recebendo uma mensagem de erro na última linha:

“PG::InsufficientPrivilege: ERRO: deve ser o proprietário do banco de dados discourse”

Na verdade, já deveria ser um “servidor padrão”. A instalação foi realizada pela equipe da “Discourse” na época, por uma taxa única.

Ah, certo. Vamos tentar isso.

Saia do console do Rails (digite exit) e, ainda dentro do contêiner (./launcher enter app), execute:

su postgres -c "reindexdb discourse"

Quando terminar sem erros, faça um novo backup no servidor antigo e restaure esse novo arquivo. Se aparecer um erro sobre uma tabela específica, basta colá-lo aqui.

Muito, muito obrigado! Tudo deu certo maravilhosamente, e sem a sua ajuda eu não teria nenhuma chance e certamente teria que começar o fórum do zero, de forma dolorosa, em breve! MUITO OBRIGADO!

Obrigado também ao @chapoi pelo ótimo suporte!