PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Aggiornamento del database a PostgreSQL versione 10 - Cosa dovresti sapere

Man mano che sul Web compaiono sempre più post su PostgreSQL 11, più ti sentirai obsoleto quando usi Postgres 9. Sebbene il rilascio della versione di PostgreSQL 10 sia avvenuto solo pochi mesi fa, le persone stanno già parlando della prossima versione. Le cose si stanno muovendo, quindi non vuoi essere lasciato indietro. In questo blog discuteremo di ciò che devi sapere per eseguire l'aggiornamento all'ultima versione, Postgres 10.

Opzioni di aggiornamento

La prima cosa di cui dovresti essere a conoscenza prima di iniziare è che ci sono diversi modi per eseguire l'aggiornamento:

  1. Tradizionale pg_dumpall(pg_dump) / pg_restore(psql)
  2. Pg_upgrade tradizionale
  3. Replica basata su trigger (Slony, auto-scritta)
  4. Utilizzo della replica pglogica

Perché esiste una tale varietà? Perché ognuno ha una storia diversa, che richiede sforzi diversi per essere impostato e offre servizi diversi. Diamo un'occhiata più da vicino a ciascuno di essi.

Discarica/Ripristino tradizionale

pg_dump t > /tmp/f
psql -p 5433 -f /tmp/f

Il tradizionale dump/ripristino richiede il tempo più lungo per essere completato, eppure è spesso una scelta popolare per coloro che possono permettersi i tempi di fermo. Innanzitutto, è facile come eseguire un backup logico e ripristinarlo in una nuova versione superiore del database. Potresti dire che non è un aggiornamento, in realtà, poiché "importi" i tuoi dati in una "nuova struttura". Di conseguenza ti ritroverai con due configurazioni:una vecchia (versione inferiore) e quella appena aggiornata. Se il processo di ripristino termina senza errori, sei praticamente lì. In caso contrario, devi modificare il vecchio cluster esistente per eliminare eventuali errori e ricominciare il processo.

Se usi psql per l'importazione, potresti anche dover creare tu stesso alcuni script di precaricamento da eseguire sulla nuova configurazione prima della migrazione. Ad esempio, potresti voler pg_dumpall -g per ottenere un elenco di ruoli necessari da preparare nella nuova configurazione, o eseguire l'opposto pg_dump -x per saltare le autorizzazioni da quella precedente. Questo processo è piuttosto semplice su database di piccole dimensioni, la complessità cresce con la dimensione e la complessità della struttura del tuo db e dipende dalle funzionalità che hai impostato. Fondamentalmente, affinché questo metodo abbia successo, devi continuare a provare e correggere fino a quando l'aggiornamento non ha esito positivo.

I vantaggi dell'utilizzo di questo metodo includono...

  • Anche se potresti dedicare molto tempo a un backup che hai eseguito, il carico sul vecchio server è piccolo quanto un backup.
  • Questo metodo è principalmente solo una sequenza di backup-ripristino (potenzialmente con alcuni incantesimi, canzoni e percussioni)
  • L'utilizzo di questo metodo è il modo più antico per eseguire l'upgrade ed è stato verificato da MOLTE persone

Quando alla fine completi l'aggiornamento, devi spegnere il vecchio server o accettare una perdita di dati (o in alternativa riprodurre il DML che si è verificato sul vecchio server mentre si ripristina un backup sul nuovo server). E il tempo impiegato per farlo è relativo alle dimensioni del tuo database.

Ovviamente puoi iniziare a "usare" un nuovo database prima che il ripristino sia terminato (soprattutto prima che tutti gli indici siano compilati - spesso la maggior parte del tempo necessario è per gli indici). Tuttavia, tali tempi di inattività sono spesso inaccettabili.

Tradizionale pg_upgrade

MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/initdb -D tl0 >/tmp/suppressing_to_save_screen_space_read_it

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/pg_upgrade -b /usr/local/Cellar/postgresql/9.5.3/bin -B /usr/local/Cellar/postgresql/10.2/bin -d t -D tl0 | tail
Creating script to delete old cluster                        ok

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

Il tradizionale pg_upgrade è stato creato per ridurre il tempo necessario per l'aggiornamento a una versione principale. A seconda della quantità di relazioni che hai, può essere veloce come minuti (secondi in casi ridicoli, come un database di tabelle e ore nei "casi opposti") specialmente con l'argomento --link.

La sequenza di preparazione differisce leggermente dal metodo di primo aggiornamento. Per simulare l'aggiornamento e quindi per verificare se è possibile, è necessario creare una replica in streaming o ripristinare un server di standby dai WAL. Perché è così complicato? Vuoi essere sicuro di testare l'aggiornamento sul database più vicino allo stato come avevi originariamente. La replica "binaria" o PITR ci aiuterà qui. Dopo aver terminato il ripristino e recovery_target_action =promuovi (PITR) o promosso lo slave appena creato (pg_ctl promuovi o posiziona un file trigger) (streaming replica), puoi quindi provare a eseguire pg_upgrade. Controllare pg_upgrade_internal.log ti darà un'idea se il processo è andato a buon fine o meno. Inoltre, hai lo stesso approccio di prova e correzione del metodo precedente. Si salvano le azioni eseguite sul database di prova in uno script, finché non lo si esegue correttamente pg_upgrade. Inoltre, puoi distruggere i test non più necessari database aggiornato, eseguire lo script quindi salvato per preparare il database originale per eseguire l'aggiornamento.

I vantaggi dell'utilizzo di questo metodo includono...

  • Tempi di inattività più brevi rispetto al backup/ripristino logico
  • Un processo accurato:pg_upgrade aggiorna il database originale con i dati e la struttura esistenti
  • È stato usato molto in passato e sarebbe ancora la preferenza per la maggior parte dei DBA con versioni inferiori alla 9.4 (che consente l'utilizzo di pglogical)

Gli svantaggi dell'utilizzo di questo metodo includono...

  • Richiede tempi di inattività

Replica basata su trigger

Supponendo che la versione 10 sia sulla porta 5433 e abbia la stessa tabella preparata:

db=# create server upgrade_to_10 foreign data wrapper postgres_fdw options (port '5433', dbname 'dbl0');
CREATE SERVER
Time: 9.135 ms
db=# create user mapping for vao SERVER upgrade_to_10 options (user 'vao');
CREATE USER MAPPING
Time: 8.741 ms
db=# create foreign table rl0 (pk int, t text) server upgrade_to_10 options (table_name 'r');
CREATE FOREIGN TABLE
Time: 9.358 ms

Questo è un fn() estremamente semplicistico e un trigger per una replica logica molto semplice. Tale approccio è così primitivo che non funzionerà con chiavi esterne, ma il codice è breve:

db=# create or replace function tf() returns trigger as $$
begin
 if TG_0P = 'INSERT' then
   insert into r10 select NEW.*;
 elseif TG_0P = 'UPDATE' then
   delete from rl0 where pk = NEW.pk;
   insert into rl0 select NEW.*;
 elseif TG_0P = 'DELETE' then
   delete from rl0 where pk = OLD.pk;
 end if;
return case when TG_0P in ('INSERT','UPDATE') then NEW else OLD end;
end;
SS language plpgsql;
CREATE FUNCTION
Time: 8.531 ms
db=# create trigger t before insert or update or delete on r for each row execute procedure tf(); CREATE TRIGGER
Time: 8.813 ms

Esempio:

db=# insert into r(t) select chr(g) from generate_series(70,75) g;
INSERT 0 6
Time: 12.621 ms
db=# update r set t = 'updated' where pk=2;
UPDATE 1
Time: 10.398 ms
db=# delete from r where pk=1;
DELETE 1
Time: 9.634 ms
db=# select * from r;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 9.026 ms
db=# select * from rl0;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 1.201 ms

Infine, verificando di replicare su un database diverso:

db=# select *,current_setting('port') from dblink('upgrade.to.lO','select setting from pg_settings where name=$$port$$') as t(setting_10 text);
 setting_10 | currerrt.setting
------------+------------------
 5433       | 5432
(l row)

Time: 23.633 ms

Definirei questo metodo il più esotico. Sia per il fatto che con la replica in streaming e successivamente con pglogical, l'uso della replica basata su trigger diventa meno popolare. Ha un carico maggiore sul master, una maggiore complessità durante l'installazione e una mancanza di documentazione ben strutturata. Non c'è alcuna preparazione (in quanto tale) del processo qui, poiché vuoi solo configurare Slony su diverse versioni principali.

I vantaggi dell'utilizzo di questo metodo includono...

  • Non è necessario eseguire backup e non sono richiesti tempi di inattività (soprattutto se sei dietro qualche pgbouncer o haproxy).

Gli svantaggi dell'utilizzo di questo metodo includono...

  • Elevata complessità di configurazione
  • Mancanza di documentazione strutturata
  • Non molto popolare - meno casi di utenti da studiare (e condividere)

Sulla stessa linea, la replica del trigger autoscritta è un altro modo possibile per eseguire l'aggiornamento. Sebbene l'idea sia la stessa (fai girare un nuovo database di versione superiore e imposti i trigger su una versione inferiore per inviargli i dati modificati), la configurazione auto scritta ti sarà chiara. Non avrai bisogno di supporto e quindi potenzialmente utilizzerai meno risorse durante l'esecuzione. Ovviamente, per lo stesso motivo probabilmente ti ritroverai con alcune funzionalità mancanti o non funzionanti come previsto. Se hai diverse tabelle da spostare a nuove versioni, tale opzione probabilmente richiederà meno tempo e, se eseguita correttamente, potrebbe consumare meno risorse. Come bonus puoi combinare alcune trasformazioni ETL con l'aggiornamento, passando a una nuova versione senza tempi di fermo.

Scarica il whitepaper oggi Gestione e automazione di PostgreSQL con ClusterControlScopri cosa devi sapere per distribuire, monitorare, gestire e ridimensionare PostgreSQLScarica il whitepaper

Replica logica con pglogical

Questo è un nuovo modo molto promettente per aggiornare Postgres. L'idea è di impostare la replica logica tra diverse versioni principali e avere letteralmente un database di versione parallela, superiore (o inferiore) che esegue gli stessi dati. Quando sei pronto, devi semplicemente cambiare le connessioni con la tua applicazione dalla vecchia alla nuova.

I vantaggi dell'utilizzo di questo metodo includono...

  • Sostanzialmente nessun tempo di inattività
  • Funzione estremamente promettente, molto meno sforzo della replica basata su trigger

Gli svantaggi dell'utilizzo di questo metodo includono...

  • Ancora molto complesso da configurare (soprattutto per le versioni precedenti)
  • Mancanza di documentazione strutturata
  • Non molto popolare - meno casi di utenti da studiare (e condividere)

Sia la migrazione della versione principale della replica basata su trigger che quella di pglogical possono essere utilizzate per eseguire il downgrade della versione (ovviamente fino a un valore ragionevole, ad esempio, pglogical è disponibile solo dalla versione 9.4 e la replica del trigger diventa sempre più difficile da configurare come versione desiderata eseguire il downgrade per invecchiare).

Azioni da intraprendere prima dell'aggiornamento

  • Fai un backup
  • Assicurati che lo spazio su disco sia sufficiente
  • Controlla le tue estensioni (importante che tutti i moduli esterni siano anche binari compatibili, anche se questo non può essere verificato da pg_upgrade)
  • Assicurati di utilizzare lo stesso datcollate e datctype e così via (controlla pg_database) sul nuovo database
  • Controlla (DDL + Drop) visualizzazioni, funzioni, estensioni, tipi che potrebbero interrompere l'aggiornamento
  • Usa --check prima di veramente pg_upgrade

Azioni da intraprendere dopo l'aggiornamento

  • Consulta pg_upgrade_server.log (se hai utilizzato pg_upgrade)
  • Esegui analisi su database aggiornati (opzionale, come sarebbe fatto da autovacuum, ma puoi scegliere quali relazioni analizzare prima se lo fai tu stesso)
  • Preriscaldare le pagine popolari (facoltativo, ma potrebbe aumentare le prestazioni all'inizio)

Conclusione

Ecco alcune note generali che è bene sapere prima di decidere di passare a PostgreSQL versione 10...

  • Sono state introdotte le sequenze_pg, modificando il comportamento del popolare SELECT * FROM nome_sequenza - ora solo valore_ultimo | log_cnt | is_call vengono restituiti, nascondendoti le "proprietà iniziali" (regola qualsiasi codice che si basa sul comportamento modificato)
  • pg_basebackup esegue i flussi WAL per impostazione predefinita. Dopo l'aggiornamento potresti dover modificare i tuoi script (opzione -x rimossa)
  • Tutte le azioni pg_ctl sono in attesa di completamento. In precedenza era necessario aggiungere -w per evitare di tentare di connettersi al database subito dopo l'avvio di pg_ctl. Quindi, se vuoi ancora usare "async" start o stop, devi contrassegnarlo esplicitamente con -W. Potrebbe essere necessario modificare gli script in modo che si comportino come previsto.
  • Tutti gli script per l'archiviazione di WAL o per il monitoraggio/controllo della replica in streaming o PITR devono essere rivisti, per adattarli ai nomi xlog modificati. Per esempio. select * from pg_is_xlog_replay_paused() non ti mostrerà più lo stato del replay dei WAL slave - devi invece usare select * from pg_is_wal_replay_paused(). Anche cp /blah/pg_xlog/* deve essere cambiato in /blah/pg_wal/* e così via fondamentalmente per tutte le occorrenze di pg_xlog. Il motivo alla base di un cambiamento così massiccio e non compatibile con le versioni precedenti è quello di affrontare il caso in cui un novellino rimuove i log write-ahead per "ripulire un po' di spazio" rimuovendo i log e perde il database.
  • Regola gli script utilizzando pg_stat_replication per i nuovi nomi (posizione modificata in lsn)
  • Regola le query con funzioni di ritorno impostate, se necessario
  • Se hai usato pglogical come estensione prima della versione 10, potresti dover modificare pg_hba.conf cambiando il valore tra le "colonne"
  • Regola gli script per un nuovo nome di pg_log che è log, quindi qualcosa come find /pg_data/pg_log/postgresql-*  -mmin +$((60*48)) -type f -exec bash /blah/moveto.s3 .sh {} \; funzionerebbe. Ovviamente puoi invece creare un collegamento simbolico, ma sarebbe necessario intraprendere un'azione per trovare i registri nella posizione predefinita. Un'altra piccola modifica alle impostazioni predefinite è log_line_prefix:se la tua espressione regolare dipende da un determinato formato, devi modificarlo.
  • Se stavi ancora utilizzando password non crittografate nei tuoi database Postgres, questa versione completa le rimuove. Quindi è tempo di sistemare le cose per coloro che si affidavano a --unencrypted...
  • Il resto delle modifiche incompatibili con le versioni precedenti o sono troppo recenti per essere referenziate in molto codice (min_parallel_relation_size) o troppo antiche (tsearch2 esterno) o sono troppo esotiche (rimozione del supporto dei timestamp in virgola mobile nella build), quindi li salteremo. Ovviamente sono elencati nella pagina di rilascio.
  • Come per le versioni da 9.5 a 9.6, potrebbe essere necessario modificare gli script per eseguire query su pg_stat_activity (una nuova colonna e nuovi possibili valori)
  • Se stavi salvando/analizzando l'output dettagliato del vuoto, potresti dover modificare il tuo codice
  • Potresti anche dare un'occhiata alla nuova implementazione del partizionamento:potresti voler rifattorizzare il tuo "set" esistente per conformarsi ai nuovi "standard"
  • controlla la sequenza temporale (verrà reimpostata per il nuovo database se esegui pg_upgrade)

A parte questi passaggi che devi sapere per eseguire l'aggiornamento a 10, ci sono molte cose che rendono questa versione molto attesa. Si prega di leggere la sezione sulle modifiche nelle note di rilascio o nel blog depesz.