Gli indici TOAST non possono essere eliminati in questo modo,
dovetti:
su postgres
psql
\connect discourse
drop index pg_toast.pg_toast_309322_index_ccnew;
drop index pg_toast.pg_toast_309322_index_ccnew1;
Quanto sopra si applica solo a pg_toast perché l’utente discourse non ha accesso a quell’indice. PG::InsufficientPrivilege: ERRORE: permesso negato per lo schema pg_toast
Si è scoperto che ne avevo ben 30, tutti sulla tabella incoming_referers. Quindi ho verificato che tutti gli indici ccnew fossero effettivamente duplicati tramite la colonna indexdef in questa query.
select indexname,indexdef from pg_indexes where tablename = 'incoming_referers';
DROP INDEX incoming_referers_pkey_ccnew;
DROP INDEX incoming_referers_pkey_ccnew_ccnew;
DROP INDEX incoming_referers_pkey_ccnew1;
...e così via per tutti i 30
A quel punto ho ricreato gli indici dell’intero schema, ma ancora una volta non è stato possibile ricostruire due degli stessi indici ccnew di incoming_referers, e ho trovato anche tre indici pg_toast. Li ho eliminati e ho ricreato gli indici dell’intero schema ancora una volta; di nuovo ci sono stati errori, ho trovato un altro gruppo di indici ccnew nello schema discourse, ho ricreato gli indici per la terza volta…
Non riesco a completare un reindicizzazione completa senza errori: continua a creare e poi a non riuscire a ricostruire nuovi indici ccnew ogni volta. Dopo 4 ricostruzioni complete ho eliminato gli indici ccnew e ho desistito. Immagino che potrei provare a ricostruirli in modalità non concorrente, ma ciò causerebbe un notevole tempo di inattività.
Comunque, il mio sospetto è che la maggior parte degli utenti che aggiornano da PG10 a PG12 e che hanno tentato di ricreare gli indici successivamente abbiano questi indici ccnew aggiuntivi, che dovrebbero tutti essere eliminati. Occupano solo spazio e moltiplicano le operazioni di scrittura su disco senza alcun beneficio.
Ho eseguito l’equivalente in Data-Explorer. È stato leggermente più facile da gestire.
Quello che ho fatto è stato prendere tutti gli indici ccnew/ccnew1/ccnew2…ccnewn, eliminarli e reindicizzare. Questo ha risolto il problema per me.
cctime è una funzionalità di PostgreSQL per contrassegnare gli indici e penso che sia un’inefficienza nel processo che causa il loro abbandono se l’indicizzazione fallisce per qualche motivo.
Posso solo suggerirti di lavorare prima sulla causa principale del problema. Avevo tag duplicati che ho dovuto eliminare prima di procedere all’eliminazione degli indici. Se mi fosse rimasto anche un solo tag duplicato, non sarebbe stato indicizzato correttamente e avrebbe creato un altro indice ccnew'n' fallendo.
Hai ragione, ho ancora dei duplicati: non posso ricostruire gli indici non-ccnew in modo non concorrente. Devo rimuovere queste righe duplicate.
discourse=# reindex index index_incoming_referers_on_path_and_incoming_domain_id;
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id"
DETAIL: Key (path, incoming_domain_id)=(/search/, 3433) is duplicated.
discourse=# reindex index index_incoming_referers_on_path_and_incoming_domain_id;
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id"
DETAIL: Key (path, incoming_domain_id)=(/search/, 1861) is duplicated.
La cosa davvero strana è che vedo solo una riga per ciascuno di quei valori di incoming_domain_id nella tabella incoming_referer. Allora perché sono considerati duplicati?
discourse=# select * from incoming_referers where path='/search/' AND incoming_domain_id IN (1861,3433);
id | path | incoming_domain_id
-------+----------+--------------------
42845 | /search/ | 1861
40763 | /search/ | 3433
(2 rows)
@sam o @riking, dovrei eliminare queste due righe nel modo seguente:
DELETE FROM incoming_referers WHERE path='/search/' AND incoming_domain_id IN (1861,3433);
… Immagino che dopo tutto sto imparando PostgreSQL, eh.
Credeteci o no, altri fallimenti. Nel primo tentativo, ho individuato un’altra chiave duplicata su /m/search che, per qualche motivo, non era stata rilevata dal wildcard %/search/ e l’ho eliminata. Ho rieseguito l’indicizzazione (ogni volta richiedeva quasi un’ora!) e sono emersi altri fallimenti che segnalavano una chiave duplicata su users(username_lower).
discourse=# reindex index index_users_on_username_lower;
ERROR: could not create unique index "index_users_on_username_lower"
DETAIL: Key (username_lower)=(john_smith) is duplicated.
Eppure, la cosa strana è che c’era una sola riga con username_lower=john_smith! È il momento di indossare il cappello da investigatore.
Osservando l’interfaccia di amministrazione del forum, abbiamo notato due utenti distinti chiamati rispettivamente “john_smith” e “John_Smith”-- notate la diversa capitalizzazione. Così ho eliminato quello tutto in minuscolo a livello di forum, dato che non era attivo da 4 anni, e l’indicizzazione è stata ricostruita correttamente.
Ho eseguito un’ulteriore ricostruzione completa, ciascuna delle quali richiedeva quasi un’ora, e FINALMENTE penso che siamo a posto: solo un errore, ma nessun duplicato, solo un pg_toast ccnew. L’ho eliminato.
È più probabile che la corruzione dell’indice di PostgreSQL si risolva in un futuro aggiornamento di PostgreSQL, se Peter ottiene una riproducibilità coerente.
Se un REINDEX concorrente fallisce perché la tabella contiene dati non validi, è necessario:
Correggere i dati non validi, come è stato fatto qui.
Elencare gli indici non validi utilizzando SELECT pg_class.relname FROM pg_class, pg_index WHERE pg_index.indisvalid = false AND pg_index.indexrelid = pg_class.oid;
Eliminare ciascun indice non valido elencato sopra con DROP INDEX <indexname>;
Dopo aver eseguito l’aggiornamento alla versione 2.5.0beta5 e seguito le indicazioni post-aggiornamento per reindicizzare il database, ottengo questo:
discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR: could not create unique index "index_plugin_store_rows_on_plugin_name_and_key_ccnew"
DETAIL: Key (plugin_name, key)=(discourse-data-explorer, q:-10) is duplicated.
Preferirei non fare esperimenti su questo… quindi, come posso eliminare in modo sicuro il duplicato?
No. L’aggiornamento non danneggia il tuo indice, ma segnala semplicemente che è già danneggiato. Puoi verificare provando a ripristinare il tuo backup su un altro server (anche uno che esegue pg10) oppure provando a ricostruire l’indice sulla tua installazione corrente. Non è chiaro cosa causi gli indici danneggiati, ma c’è la speranza che pg12 riduca la probabilità che ciò accada.
Ci sono alcuni vantaggi prestazionali nell’aggiornamento, ma rimandarlo non è una cattiva idea.