Errore di importazione backup: "could not create unique index"

Ciao,

Sto tentando di migrare un forum su un nuovo server. Entrambi i server eseguono l’ultima versione di discourse docker. Quando importo il backup tramite riga di comando, ricevo il seguente errore:

ERRORE:  impossibile creare indice univoco "index_incoming_referers_on_path_and_incoming_domain_id"
DETTAGLIO:  La chiave (path, incoming_domain_id)=(/search/, 418) è duplicata.
ECCEZIONE: psql fallito: DETTAGLIO:  La chiave (path, incoming_domain_id)=(/search/, 418) è duplicata.

Questo sembra lo stesso errore o simile a:

Tuttavia, nel mio caso i record duplicati si trovano nel percorso /search/ anziché /m/search come nel thread collegato sopra.

Mi sono connesso al container sul vecchio server (./launcher enter app) e nella console Rails (rails c) ho provato a cercare i record duplicati usando:

IncomingReferer.where(path: "/search")
e
IncomingReferer.where("path LIKE '%/search%'")

Tuttavia, questo risulta in centinaia di record visualizzati. Come posso capire quali record sono duplicati e come posso eliminarli in modo sicuro e ricostruire? Il forum funziona correttamente sul vecchio server, dobbiamo solo spostarci su nuovo hardware.

1 Mi Piace

Hai già provato a usare l’interfaccia grafica di amministrazione (Admin GUI)?

1 Mi Piace

No, ho dato per scontato che l’importazione tramite GUI attivasse lo stesso processo di importazione? Proverò ora.

1 Mi Piace

Sospetto che questo significhi che hai un indice corrotto. Quale versione di Postgres stai eseguendo?

Qualcosa come:

cd /var/discourse
cat shared/standalone/postgres_data/PG*

(Non ricordo esattamente il nome del file di postgres).

Puoi cercare qui “postgres corrupt index” e trovare un argomento che ho scritto in passato su come individuare quei record errati ed eliminarli.

In pratica, provi a ricreare quell’indice ed eliminare i record di cui lamenta, poi provi a ricreare l’indice di nuovo finché non viene ricostruito correttamente.

Ho appena provato a importare tramite l’interfaccia grafica, ottenendo esattamente lo stesso risultato:

Il vecchio server non ha un file chiamato PG_VERSION; come posso capire quale versione sta eseguendo? Oggi ho aggiornato l’installazione di Docker alla versione più recente.

Il nuovo server (appena avviato) esegue Postgres V13

cat shared/standalone/postgres_data/PG_VERSION
13

Esiste una procedura consigliata su come eseguire questa operazione?

Avevo un argomento con alcuni suggerimenti, ma non lo vedo più. È passato quasi un anno dall’aggiornamento a PostgreSQL 12.

  reindex index index_incoming_referers_on_path_and_incoming_domain_id;

E

 ActiveRecord::Base.connection.execute('reindex index index_incoming_referers_on_path_and_incoming_domain_id;')

Sono modi per tentare di ricostruire l’indice. Restituirà un errore e potrai quindi procedere a eliminare i record problematici. Dovrai includere sia il percorso che l’ID.

Ok, l’ho sistemato. Ho fatto quanto segue:

Entra nel container

./launcher enter app

Connettiti al database

su postgres -c 'psql discourse'

Prova a trovare i duplicati

discourse=# select * from incoming_referers where path LIKE '%/search/' ORDER BY incoming_domain_id;

  id  |    path    | incoming_domain_id
------+------------+--------------------
 3339 | /search/   |                 33
 6257 | /search/   |                 91
 1567 | /search/   |                298
 1777 | /search/   |                341
 3010 | /search/   |                418
 6247 | /search/   |                418
 4293 | /search/   |                644
 2899 | /search/   |                653
 3447 | /search/   |                793
 3696 | /search/   |                852
 4395 | /a/search/ |               1050
 6968 | /search/   |               1305
 5634 | /search/   |               1387
 5834 | /search/   |               1437
 6519 | /search/   |               1637
 7127 | /search/   |               1787
 7280 | /search/   |               1827
(17 righe)

Elimina il duplicato

DELETE FROM incoming_referers WHERE path LIKE '%/search/' AND id IN (6247);

Poi ricostruisci

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

Successivamente ho creato un altro backup, l’ho copiato sul nuovo server e l’importazione è andata a buon fine :smiley:

Sarebbe utile se il processo di backup potesse rilevare i duplicati per evitare problemi. Sono stato fortunato ad avere accesso al server originale, che era ancora in esecuzione. Se avessi dovuto ripristinare un backup “freddo”, probabilmente sarebbe stato un problema maggiore.

Grazie mille per il tuo aiuto.

3 Mi Piace

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.