Estoy intentando migrar un foro a un nuevo servidor. Ambos servidores ejecutan la última versión de discourse docker. Al importar la copia de seguridad a través de la línea de comandos, obtengo el siguiente error:
ERROR: no se pudo crear el índice único «index_incoming_referers_on_path_and_incoming_domain_id»
DETAIL: La clave (path, incoming_domain_id)=(«/search/», 418) está duplicada.
EXCEPTION: psql falló: DETAIL: La clave (path, incoming_domain_id)=(«/search/», 418) está duplicada.
Esto parece ser el mismo error o uno similar a:
Sin embargo, en mi caso, los registros duplicados están en la ruta /search/ en lugar de /m/search, como ocurre en el hilo enlazado anteriormente.
Me he conectado al contenedor en el servidor antiguo (./launcher enter app) y en la consola de Rails (rails c) he intentado buscar los registros duplicados usando:
IncomingReferer.where(path: "/search")
y IncomingReferer.where("path LIKE '%/search%'")
Sin embargo, esto resulta en que se muestren cientos de registros. ¿Cómo puedo averiguar qué registros están duplicados y cómo puedo eliminarlos de forma segura y reconstruirlos? El foro está funcionando correctamente en el servidor antiguo, solo necesitamos movernos a hardware nuevo.
Sospecho que esto significa que tienes un índice corrupto. ¿Qué versión de Postgres estás ejecutando?
Algo como:
cd /var/discourse
cat shared/standalone/postgres_data/PG*
(No recuerdo exactamente el nombre del archivo de Postgres).
Puedes buscar aquí “postgres corrupt index” y encontrar un tema que escribí una vez sobre cómo rastrear esos registros erróneos y eliminarlos.
Básicamente, intentas reconstruir ese índice y eliminar los registros de los que se queja, luego intentas reconstruir el índice nuevamente hasta que se reconstruya.
El servidor antiguo no tiene un archivo llamado PG_VERSION, ¿cómo puedo saber qué versión está ejecutando? He actualizado la instalación de Docker a la versión más reciente hoy.
El nuevo servidor (recién inicializado) está ejecutando Postgres V13
cat shared/standalone/postgres_data/PG_VERSION
13
¿Existe un procedimiento recomendado para hacer esto?
Tuve un tema que tenía algunas pistas, pero ya no lo veo. Ha pasado casi un año desde la actualización a PostgreSQL 12.
reindex index index_incoming_referers_on_path_and_incoming_domain_id;
Y
ActiveRecord::Base.connection.execute('reindex index index_incoming_referers_on_path_and_incoming_domain_id;')
Son formas de intentar reconstruir el índice. Te dará un error y luego podrás ir y eliminar los registros erróneos. Necesitarás incluir tanto la ruta como el ID.
DELETE FROM incoming_referers WHERE path LIKE '%/search/' AND id IN (6247);
Luego reconstruir
discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING: cannot reindex invalid index "public.incoming_referers_pkey_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "public.index_incoming_referers_on_path_and_incoming_domain_id_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "pg_toast.pg_toast_20732_index_ccnew" concurrently, skipping
REINDEX
Después tomé otra copia de seguridad, la copié al nuevo servidor y se importó correctamente
Sería ideal que el proceso de copia de seguridad pudiera detectar duplicados para evitar cualquier problema; tuve la suerte de tener acceso al servidor original que aún estaba en funcionamiento. Si hubiera estado restaurando una copia de seguridad inactiva, esto probablemente habría sido un problema mayor.