Indici corrotti in PG12, come li risolvo?

Scusa per aver rimesso questo argomento, ho ricevuto un messaggio molto strano:

discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR:  could not create unique index "index_tags_on_name_ccnew"
DETAIL:  Key (name)=(chronicillness) is duplicated.

Immagino che possa essere risolto dalla soluzione suggerita sopra da @riking, ma non riesco a capire come modificare la sintassi per adattarla al mio caso. :frowning:

Vedi:

https://twitter.com/petervgeoghegan/status/1264325695997538304?s=20

https://twitter.com/petervgeoghegan/status/1264404749899534338?s=20

Quindi, se vedi questo errore, hai due opzioni:

  1. Puoi aggirare il problema … in questo caso la tabella tags contiene una riga duplicata con il nome chronicillness

    1. Esegui una query nell’Esploratore Dati cercando le righe: select * from tags where name = 'chronicillness'

    2. Elimina il duplicato:

      ./launcher enter app
      rails c
      Tag.find_by(id: ID_TROVATA_NEL_ESPLORATORE_DATI).destroy   
      
  2. Se hai un backup del tuo database e dettagli che desideri condividere con Peter… condividili con Peter, sia in privato che sulla mailing list PG.

Quindi ho un backup generato da Discourse di PostgreSQL 10. Sarà utile? Posso semplicemente estrarre la parte di PostgreSQL dall’archivio e inviarla?

Non sono sicuro… ciò di cui Peter avrebbe probabilmente bisogno è che tu arresti il database e copi l’intero contenuto della cartella che contiene il database.

Il modo migliore per scoprirlo è scrivergli una email.

Certo, gli manderò una email per chiarire la questione :slight_smile:

NB: Questo è il risultato ottenuto eseguendo la query SQL nell’esploratore dati

id name topic_count created_at updated_at pm_topic_count target_tag
1710 chronicillness 2 2019-12-03T17:49:17.395Z 2019-12-03T17:49:17.395Z 0 NULL

farà il suo dovere?

Tag.find_by(id: 1710).destroy

Oh… l’indice è su LOWER(name)

Esegui la query in questo modo:

select * from tags where name ilike 'chronicillness'

Dovresti ottenere 2 righe.

select * from tags where name ilike 'chronicillness'
id name topic_count created_at updated_at pm_topic_count target_tag
329 chronicillness 12 2017-08-22T00:17:38.824Z 2017-08-22T00:17:38.824Z 0 NULL
1710 chronicillness 2 2019-12-03T17:49:17.395Z 2019-12-03T17:49:17.395Z 0 NULL

Potrebbe esserci un - tra i nomi dei tag?
Vedo due tag: chronicillness e chronic-illness qui.

Beh, allora questo è il problema… Immagino che tu abbia cancellato 1710. Dopo di ciò, mancheranno due argomenti con quel tag.

#<Tag:0x00005607bb92cf48
 id: 1710,
 name: "chronicillness",
 topic_count: 0,
 created_at: mar, 03 dic 2019 17:49:17 UTC +00:00,
 updated_at: mar, 03 dic 2019 17:49:17 UTC +00:00,
 pm_topic_count: 0,
 target_tag_id: nil>

Perché ho la sensazione che fosse un nano non associato a nulla?

L’eliminazione del tag ha portato più problemi!

discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING:  cannot reindex invalid index "public.tags_pkey_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_name_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_lower_name_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "pg_toast.pg_toast_309322_index_ccnew" concurrently, skipping
ERROR:  could not create unique index "index_tags_on_name_ccnew1"
DETAIL:  Key (name)=(time-management) is duplicated.

Stessa correzione :slight_smile: devi ripetere il processo.

Ecco cosa stavo facendo. Ma questi avvisi vanno bene? Non devo preoccuparmene, giusto?

Sì, tutti gli avvisi sono corretti: hai un indice danneggiato che deve essere riparato prima.

Quindi tutti i cloni sono stati rimossi e ora rimangono solo questi avvisi durante la reindicizzazione:

discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING:  cannot reindex invalid index "public.tags_pkey_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_name_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_lower_name_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.tags_pkey_ccnew1" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_name_ccnew1" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_tags_on_lower_name_ccnew1" concurrently, skipping
WARNING:  cannot reindex invalid index "pg_toast.pg_toast_309322_index_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "pg_toast.pg_toast_309322_index_ccnew1" concurrently, skipping
REINDEX

C’è qualcosa che si dovrebbe fare per eliminare questi avvisi o dobbiamo conviverci?

Questo è confuso per me… non abbiamo nomi di indici che terminano con ccnew… li hai creati tu a mano?

Penso che vengano utilizzati durante la migrazione da PostgreSQL 10 a 12, poiché li ho visti in quasi tutti gli utenti che hanno riscontrato problemi con gli indici. Ad esempio:
https://meta.discourse.org/t/postgresql-12-update/151236/208?u=itsbhanusharma

https://meta.discourse.org/t/postgresql-12-update/151236/237?u=itsbhanusharma

EDIT: proviene direttamente da PostgreSQL

Il metodo di ripristino consigliato in questi casi è eliminare l’indice non valido e riprovare a eseguire REINDEX CONCURRENTLY. L’indice concorrente creato durante l’elaborazione ha un nome che termina con il suffisso ccnew, o ccold se si tratta di una definizione di indice vecchio che non siamo riusciti a eliminare. Gli indici non validi possono essere eliminati usando DROP INDEX, inclusi gli indici toast non validi.

ouch … gli indici corretti sono già sulla tabella?

Credo che tu possa elencare gli indici sulla tabella usando l’esploratore di dati.

Se quelli corretti sono presenti, puoi semplicemente eliminare questi indici problematici.

Faccio un controllo. Ti farò sapere.

Quindi gli indici sembrano esistere

Esistono anche indici duplicati per gli indici problematici, con l’aggiunta di ccnew o ccnew1

Non so come verificare se questi indici siano validi, ma se eliminarli è un’opzione, sarò felice di eliminarli e ricreare gli indici.

EDIT: funzionerà DROP INDEX come suggerito qui?

Sì, eliminane tutti… non ho idea di come siano finiti lì… DROP INDEX è quello che devi usare.

./launcher enter app
rails c
DB.exec('drop index tags_pkey_ccnew1')