La restauración de la copia de seguridad falla

Tengo el siguiente problema. Llevo más de 10 años administrando un foro de Discourse y, como no he podido instalar actualizaciones desde hace algún tiempo, quería configurar un nuevo servidor:

El servidor antiguo está ejecutando: 3.4.0.beta4-dev

El nuevo servidor: Última versión

La copia de seguridad ya tiene un tamaño de 673,2 MB como archivo .gz, sin incluir las subidas.

Desafortunadamente, la restauración sigue fallando. El archivo de registro contiene este error:

[2026-06-16 07:54:52] ERROR:  no se pudo crear el índice único "index_incoming_referers_on_path_and_incoming_domain_id"
[2026-06-16 07:54:52] DETALLE:  La clave (path, incoming_domain_id)=(//, 5) está duplicada.
[2026-06-16 07:54:52] EXCEPCIÓN: psql falló: DETALLE:  La clave (path, incoming_domain_id)=(//, 5) está duplicada.

[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 'bloque en '
/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] Intentando revertir...

¿Qué puedo hacer para solucionar este problema y no perder los últimos 10 años de datos?

¡Gracias de antemano por cualquier ayuda!

¡Hola y bienvenido de nuevo después de 9 años!

Es bastante impresionante ver un foro que lleva tanto tiempo activo.

Creo que este es el mismo problema de índice del que se habló aquí: Can't restore due to corrupt indexes (with some clues on how to deal with corrupt indexes)

Es algo como esto:

La tabla incoming_referers rastrea las rutas de URL que derivaron a los visitantes en tu foro. Tiene un índice único, lo que significa que no pueden haber dos filas con la misma combinación de ruta + dominio.

Tu base de datos tiene dos filas con path='//' e incoming_domain_id=5. Cuando intenta reconstruir este índice único durante la restauración, encuentra el duplicado y cancela toda la transacción de restauración.

Así que necesitarás encontrar y limpiar ese incoming_referers duplicado y luego hacer una nueva copia de seguridad para restaurar en el nuevo servidor.

Encontré este tema con instrucciones que podría ayudarte.

Muchas gracias por la rápida respuesta; ¡lo probaré!

(publicación eliminada por el autor)

Lo siento por molestarte, pero creo que estoy haciendo algo mal. Después de ejecutar el comando “discourse=# select * from incoming_referers where path LIKE ‘%/search/’ ORDER BY incoming_domain_id;”, obtengo un error de sintaxis.

¿Escribiste “discourse=#”? Si es así, inténtalo de nuevo sin eso.

Entonces obtengo el mensaje de error “bash: error de sintaxis cerca del token inesperado `from’”

Para referencia, actualmente estoy en: root@community-app:/var/www/discourse#

Ah, aún no estás en la base de datos.

Primero ejecuta psql -U discourse discourse (creo)

Y luego el indicador debería cambiar a discourse=#

Vale, ahora también he instalado “apt install postgresql-client-common”. Sin embargo, sigo obteniendo el error “Error: Debe instalar al menos un paquete postgresql-client-.”

Eso no lo sé.

Quizás intentes directamente desde la consola de Rails: rails c

con

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

Eso podría darte lo mismo sin pasar por la base de datos.

¿Funciona?

Lo siento muchísimo por haber actuado de forma tan tonta.

Ya he instalado Rails y parece que ha funcionado. También lo ejecuté con «rails c». Eso también parece funcionar, pero cuando introduzco el comando, aparece así:

“root@community:/var/discourse# ActiveRecord::Base.connection.execute(<<~SQL)
-bash: error de sintaxis cerca del token inesperado «<<’
root@community:/var/discourse# SELECT id, path, incoming_domain_id
SELECT: comando no encontrado
root@community:/var/discourse# FROM incoming_referers
FROM: comando no encontrado
root@community:/var/discourse# WHERE path = ‘//’
WHERE: comando no encontrado
root@community:/var/discourse# AND incoming_domain_id = 5
AND: comando no encontrado
root@community:/var/discourse# SQL”

No te preocupes, quizás mis instrucciones no sean tan buenas :slight_smile:

Digo que me confundo cuando dices que acabas de instalar Rails y no puedes acceder a tu base de datos. Quizás sea todo diferente porque es una versión más antigua, pero creo que yo también me he quedado sin ideas.

En cualquier caso, una vez que estés en Rails, el indicador debería ser diferente, así que por tu salida, parece que aún no estás en la consola de Rails.

Ni siquiera creo que estés dentro del contenedor real. ¿Has ejecutado ./launcher enter app?

De acuerdo, sí, ese era el problema. La consulta se ejecutó correctamente ahora, y obtuve esta respuesta:

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

Entonces, ntuples=1 significa que solo se encontró una fila, pero según el registro de errores debería haber un duplicado… :mujer_encogiéndose_de_hombros:

Lo siento, no sé qué probar a continuación. Recomiendo navegar por el foro; parece que hay muchos casos similares (ver más abajo en la sección relacionada), quizás encuentres ahí la siguiente pista.

(O esperar a que pase alguien más conocedor ;))

Parece que tu servidor antiguo no es una instalación estándar. De todos modos,… en resumen: un índice en tu servidor antiguo se dañó con los años (esto puede ocurrir tras actualizaciones del sistema operativo), por lo que dos filas idénticas se colaron en la tabla incoming_referers. La copia de seguridad las copia tal cual, y el nuevo servidor las rechaza. Así que primero lo arreglamos en el servidor antiguo, y luego hacemos una nueva copia de seguridad.

En el servidor ANTIGUO, abre la consola de Rails:

./launcher enter app
rails c

Luego pega estas líneas, una tras otra:

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)}")

Esto elimina los duplicados y reconstruye todos los índices (por si otras tablas también se ven afectadas).

Si REINDEX finaliza sin errores, escribe exit, haz una nueva copia de seguridad en el servidor antiguo y restaura ese nuevo archivo. Si muestra un error relacionado con otra tabla, simplemente pégalo aquí.

Muchas gracias. Por desgracia, obtengo un mensaje de error en la última línea:

«PG::InsufficientPrivilege: ERROR: debe ser el propietario de la base de datos discourse»

En realidad, ya debería ser un «servidor estándar». La instalación fue realizada por el equipo de «Discourse» en su momento, por una tarifa única.

Ah, vale. Probemos esto.

Sal de la consola de Rails (escribe exit) y, mientras sigues dentro del contenedor (./launcher enter app), ejecuta:

su postgres -c "reindexdb discourse"

Cuando termine sin errores, haz una copia de seguridad nueva en el servidor antiguo y restaura ese nuevo archivo. Si aparece un error sobre una tabla específica, pégalo aquí.

¡Muchísimas gracias! Todo salió maravillosamente bien y, sin tu ayuda, no habría tenido ninguna oportunidad y seguro que habría tenido que empezar el foro de nuevo desde cero, con mucho dolor de cabeza. ¡GRACIAS!

También gracias a @chapoi por el gran apoyo.