Ciao, il ripristino del backup fallisce con l’errore:
CREATE INDEX
ERROR: non è stato possibile creare l'indice unico "index_incoming_referers_on_path_and_incoming_domain_id"
DETTAGLIO: La chiave (path, incoming_domain_id)=(/m/search, 25) è duplicata.
ECCEZIONE: psql fallito: DETTAGLIO: La chiave (path, incoming_domain_id)=(/m/search, 25) è duplicata.
Questo problema con la tabella incoming_referers si è presentato diverse volte di recente. Non sono sicuro del motivo per cui quella tabella in particolare stia causando problemi, ma sembra probabile che le problematiche siano correlate. Forse qualcun altro del team di Discourse avrà idee su cosa potrebbe causare la creazione di record duplicati.
Hai ancora accesso al sito su cui hai creato il file di backup? Se sì, la soluzione è eliminare il record duplicato dal database e poi creare un nuovo file di backup. Per farlo, dovresti accedere via SSH al vecchio server e spostarti (cd) nella directory /var/discourse:
cd /var/discourse
Poi esegui
./launcher enter app
Quindi accedi alla console Rails con
rails c
Dovresti quindi vedere un prompt simile a questo:
[1] pry(main)>
Prova a eseguire il seguente comando dalla console Rails e facci sapere cosa restituisce:
IncomingReferer.where(path: "/m/search")
Dovrebbe restituire un array con due o più record.
Grazie per averlo verificato! Il risultato che hai ottenuto è effettivamente lo stesso che ho visto io su un altro sito più tardi oggi. È un problema risolvibile, ma cercherò di far controllare a uno dei nostri ingegneri cosa sta succedendo.
Il mio obiettivo principale nello spostare i server era dovuto al fatto che stavo utilizzando Debian 8, che sta per perdere il supporto.
Di fronte a questo problema di ripristino, ho optato per l’aggiornamento a Debian 9 sullo stesso server. L’operazione è andata a buon fine, quindi per il momento c’è un po’ di sollievo.
Grazie per il vostro supporto.
È necessario eseguire una ricerca fuzzy in modo che non dia per scontato che l’indice funzioni. Un solo segno di percentuale è probabilmente sufficiente se si trova all’inizio, credo.
Puoi semplicemente eliminare il record extra. Per farlo correttamente, però, devi aggiornare anche l’altra tabella che fa riferimento a questa. Devo cercarlo ogni volta, dato che ci sono diverse tabelle collegate che coinvolgono questo caso.
Questo problema viene attribuito alle estensioni di terze parti, il che non ha molto senso. Sembra che debba essere colpa di PostgreSQL, ma non ne sono sicuro. Mi capita di imbatterci in questo problema un paio di volte al mese (score) su diversi siti.
Ho anch’io un problema di chiave duplicata, esiste una soluzione documentata?
discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id_ccnew"
DETAIL: Key (path, incoming_domain_id)=(/search/, 1905) is duplicated.
Anche se ho appena aggiornato il mio server in-place e quindi non ripristinerò più su un nuovo server, l’ho provato per curiosità e non ho trovato alcun record con la ricerca fuzzy:
È una buona notizia. Ho aggiornato con fatica l’altra tabella che fa riferimento a queste. È un vero incubo, dato che non riesco mai a ricordarmi di cosa si tratti, quindi devo ripeterlo continuamente.
Rimuovere quei due duplicati è andato a buon fine, ma la successiva ricostruzione degli indici ha generato nuovi errori. Si tratta di un problema grave? Come possiamo risolvere, cancellando quella riga con search 3433?
postgres=# \connect discourse
Ora sei connesso al database "discourse" come utente "postgres".
discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING: impossibile reindicizzare l'indice non valido "public.incoming_referers_pkey_ccnew" in modo concorrente, salto
WARNING: impossibile reindicizzare l'indice non valido "public.index_incoming_referers_on_path_and_incoming_domain_id_ccnew" in modo concorrente, salto
WARNING: impossibile reindicizzare l'indice non valido "pg_toast.pg_toast_2782645_index_ccnew" in modo concorrente, salto
ERROR: impossibile creare l'indice univoco "index_incoming_referers_on_path_and_incoming_domain_id_ccnew1"
DETAIL: La chiave (path, incoming_domain_id)=(/search/, 3433) è duplicata.
CONTEXT: worker parallelo
Ho provato a ricostruire manualmente quei 4 indici. Due sono riusciti, due sono falliti. Dovrei eliminare quelle due righe duplicate?
discourse=# REINDEX INDEX CONCURRENTLY "public"."incoming_referers_pkey_ccnew";
REINDEX
discourse=# REINDEX INDEX CONCURRENTLY "public"."index_incoming_referers_on_path_and_incoming_domain_id_ccnew";
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id_cc_ccnew"
DETAIL: Key (path, incoming_domain_id)=(/search/, 1861) is duplicated.
discourse=# REINDEX INDEX CONCURRENTLY "pg_toast"."pg_toast_2782645_index_ccnew";
REINDEX
discourse=# REINDEX INDEX CONCURRENTLY "index_incoming_referers_on_path_and_incoming_domain_id_ccnew1";
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id_c_ccnew1"
DETAIL: Key (path, incoming_domain_id)=(/search/, 1905) is duplicated.
@riking la corruzione degli indici in PostgreSQL è un bug di PostgreSQL, non di Discourse. Possiamo certamente migliorare le prestazioni di quell’inserimento, ma il bug di PostgreSQL deve essere risolto in PostgreSQL stesso.
Il mio sospetto è che sia legato a una chiusura brusca del motore del database, forse dovuta a un’interruzione di corrente.
È un’ipotesi plausibile. Il comando ./launcher shutdown app (o rebuild) esegue una chiusura pulita di Postgres? Aspetta, ma scommetto che un aggiornamento automatico non sa come chiudere correttamente i container Docker, vero?