ATTENZIONE! Se il tuo database è molto grande, avrai bisogno di molto spazio su disco aggiuntivo (2x la dimensione del database) e dovrai prestare molta attenzione durante questo aggiornamento!
Abbiamo appena implementato le modifiche per aggiornare la nostra immagine Docker a PostgreSQL 13. Qualsiasi amministratore di sito che ricostruisce Discourse da riga di comando verrà aggiornato a PostgreSQL 13 dalla precedente versione PostgreSQL 12. Nota che se hai rinviato l’aggiornamento quando è stato rilasciato l’aggiornamento a PostgreSQL 12 lo scorso maggio, puoi saltare quell’aggiornamento e passare direttamente a PostgreSQL 13.
Se avevi precedentemente rinviato l’aggiornamento, modifica il template di PostgreSQL in app.yml da templates/postgres.10.template.yml a templates/postgres.template.yml.
Come per qualsiasi aggiornamento, è fortemente consigliato eseguire un backup prima di procedere.
Aggiornamento
Guida all’installazione ufficiale (singolo contenitore)
Al prossimo rebuild, vedrai questo messaggio alla fine:
-------------------------------------------------------------------------------------
AGGIORNAMENTO DI POSTGRES COMPLETATO
Il vecchio database 12 è salvato in /shared/postgres_data_old
Per completare l'aggiornamento, esegui nuovamente il rebuild usando:
./launcher rebuild app
-------------------------------------------------------------------------------------
Ciò significa che l’aggiornamento è andato a buon fine! Devi solo eseguire un nuovo rebuild per riavviare il tuo sito.
Installazione con contenitore dati dedicato
Se stai utilizzando una configurazione con un contenitore dati dedicato basato sul campione fornito nel nostro repository discourse_docker, assicurati di spegnere PostgreSQL in modo sicuro e pulito.
Oggi, abbiamo processi in background che eseguono query della durata di diversi minuti, quindi spegnere il contenitore web aiuterà a garantire lo spegnimento sicuro del contenitore dati.
./launcher stop web_only
./launcher stop data
./launcher rebuild data
./launcher rebuild data
./launcher rebuild web_only
Prima di eseguire il primo rebuild sul contenitore dati, puoi seguire il log di PostgreSQL per verificare se è stato spento correttamente.
Eseguire tail -f shared/data/log/var-log/postgres/current dovrebbe mostrare il seguente log se lo spegnimento è stato pulito:
2020-05-13 18:33:33.457 UTC [36] LOG: received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG: worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG: shutting down
2020-05-13 18:33:33.479 UTC [36] LOG: database system is shut down
Esecuzione di un aggiornamento manuale / ambienti con spazio limitato
DEVI ESEGUIRE UN BACKUP DI POSTGRES_DATA PRIMA DI PROVARE QUESTO
Se ti trovi in un ambiente con spazio limitato e non hai modo di ottenere più spazio, puoi provare quanto segue:
./launcher stop app #(o entrambi web_only e data se è il tuo caso)
mkdir -p /var/discourse/shared/standalone/postgres_data_new
docker run --rm \
-v /var/discourse/shared/standalone/postgres_data:/var/lib/postgresql/12/data \
-v /var/discourse/shared/standalone/postgres_data_new:/var/lib/postgresql/13/data \
tianon/postgres-upgrade:12-to-13
mv /var/discourse/shared/standalone/postgres_data /var/discourse/shared/standalone/postgres_data_old
mv /var/discourse/shared/standalone/postgres_data_new /var/discourse/shared/standalone/postgres_data
./launcher rebuild app #(o prima data e poi web_only se è il tuo caso)
Nei miei test, questa procedura richiede meno di 1x la dimensione attuale del tuo database in spazio libero.
Posticipare l’aggiornamento
Se hai bisogno di posticipare l’aggiornamento durante il prossimo rebuild, puoi sostituire il template di PostgreSQL nel tuo file app.yml modificando \"templates/postgres.template.yml\" in \"templates/postgres.12.template.yml\".
Questo non è raccomandato, poiché alcuni amministratori di sito potrebbero dimenticare di annullare la modifica successivamente.
Attività opzionali post-aggiornamento
Ottimizzazione delle statistiche di PostgreSQL
Dopo l’aggiornamento, il nuovo PostgreSQL non avrà a disposizione le statistiche delle tabelle. Puoi generarle utilizzando:
cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
VACUUM VERBOSE ANALYZE;
\q
exit
exit
O questa versione in una riga della precedente:
/var/discourse/launcher run app "echo 'vacuum verbose analyze;' | su postgres -c 'psql discourse'"
Ricreazione degli indici
La principale caratteristica di questo aggiornamento è il notevole risparmio di spazio nella nostra tabella più grande in ogni istanza, la tabella post_timings e i suoi indici. Dopo aver completato un aggiornamento riuscito, dovrai eseguire un comando per ricostruire gli indici e sfruttare i vantaggi.
cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
REINDEX SCHEMA CONCURRENTLY public;
\q
exit
exit
Se puoi verificare le dimensioni di post_timings prima e dopo il REINDEX, sarebbe una statistica interessante da condividere qui!
Puoi utilizzare la query sottostante per verificare i 20 oggetti dati più grandi; eseguila prima e dopo il reindex:
WITH RECURSIVE pg_inherit(inhrelid, inhparent) AS
(select inhrelid, inhparent
FROM pg_inherits
UNION
SELECT child.inhrelid, parent.inhparent
FROM pg_inherit child, pg_inherits parent
WHERE child.inhparent = parent.inhrelid),
pg_inherit_short AS (SELECT * FROM pg_inherit WHERE inhparent NOT IN (SELECT inhrelid FROM pg_inherit))
SELECT table_schema
, TABLE_NAME
, row_estimate
, pg_size_pretty(total_bytes) AS total
, pg_size_pretty(index_bytes) AS INDEX
, pg_size_pretty(toast_bytes) AS toast
, pg_size_pretty(table_bytes) AS TABLE
FROM (
SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes
FROM (
SELECT c.oid
, nspname AS table_schema
, relname AS TABLE_NAME
, SUM(c.reltuples) OVER (partition BY parent) AS row_estimate
, SUM(pg_total_relation_size(c.oid)) OVER (partition BY parent) AS total_bytes
, SUM(pg_indexes_size(c.oid)) OVER (partition BY parent) AS index_bytes
, SUM(pg_total_relation_size(reltoastrelid)) OVER (partition BY parent) AS toast_bytes
, parent
FROM (
SELECT pg_class.oid
, reltuples
, relname
, relnamespace
, pg_class.reltoastrelid
, COALESCE(inhparent, pg_class.oid) parent
FROM pg_class
LEFT JOIN pg_inherit_short ON inhrelid = oid
WHERE relkind IN ('r', 'p')
) c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
) a
WHERE oid = parent
) a
ORDER BY total_bytes DESC LIMIT 20;
Pulizia dei vecchi dati
Per un’installazione standard, puoi eliminare i vecchi dati nel formato PG12 con il seguente comando:
cd /var/discourse
./launcher cleanup
Se hai un contenitore dati separato, dovrai rimuovere la copia di backup in questo modo:
rm -fr /var/discourse/shared/data/postgres_data_old/
FAQ
Il cluster sorgente non è stato spento correttamente
Se ricevi un errore di aggiornamento con il messaggio sopra, puoi provare un approccio più semplice per riportarlo in uno stato migliore.
Riavvia il vecchio contenitore con ./launcher start app. Attendi qualche minuto fino al suo riavvio.
Ora spegnilo nuovamente con ./launcher stop app. Dopo di che, segui i log per verificare se è stato uno spegnimento pulito:
tail -f shared/data/log/var-log/postgres/current
2020-05-13 18:33:33.457 UTC [36] LOG: received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG: worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG: shutting down
2020-05-13 18:33:33.479 UTC [36] LOG: database system is shut down
Se i log sono come quelli sopra, ora puoi provare a eseguire nuovamente l’aggiornamento usando ./launcher rebuild app.
I valori lc_collate per il database “postgres” non corrispondono
Questo errore si verifica se stai utilizzando localizzazioni non predefinite per il tuo database. È stato segnalato che sono necessarie 3 variabili per il successo dell’operazione. Assicurati che la sezione env: del tuo file app.yml contenga le 3 righe:
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
LANGUAGE: en_US.UTF-8
Sostituendo en_US.UTF-8 con la tua localizzazione.
Ogni rebuild esegue nuovamente l’aggiornamento, ovvero ciclo di aggiornamento
Quando ciò accade, i log di aggiornamento conterranno:
mv: cannot move '/shared/postgres_data' to '/shared/postgres_data_old/postgres_data': Directory not empty
mv: cannot move '/shared/postgres_data_new' to '/shared/postgres_data/postgres_data_new': Directory not empty
Ciò significa che ci sono ancora file residui dall’ultimo aggiornamento. Spostali altrove prima di continuare.
Suggerimenti sugli script completi dell’aggiornamento - devo fare qualcosa?
Una volta completato l’aggiornamento, vedrai un output dal messaggio pg_upgrade che dice:
Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
./analyze_new_cluster.sh
Running this script will delete the old cluster's data files:
./delete_old_cluster.sh
Puoi ignorare tranquillamente questo messaggio.
Ho saltato l’aggiornamento a PostgreSQL 12, cosa devo fare ora?
Puoi seguire le istruzioni standard nella parte superiore di questa guida; esse aggiorneranno dalla tua versione alla 13 senza problemi.
Se stai seguendo le istruzioni per ambienti con spazio limitato, adatta i numeri di versione di conseguenza.