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

Progressi nell'aggiornamento online

Negli ultimi due mesi ho lavorato all'aggiornamento online di database molto grandi nell'ambito del progetto AXLE e vorrei condividere le mie opinioni sull'argomento e sui progressi che abbiamo fatto di recente.

Prima di entrare in 2ndQuadrant lavoravo in Skype dove l'azienda non permetteva una finestra di manutenzione per i nostri database. Ciò significava che non erano consentiti tempi di inattività per implementazioni, aggiornamenti, ecc. Questo tipo di regola ti fa cambiare il modo in cui fai le cose. La maggior parte delle modifiche sono piccole, non si eseguono blocchi pesanti, si dispone di repliche per consentire un rapido failover. Ma mentre puoi rendere le tue versioni piccole e non bloccanti, cosa succede quando devi eseguire un aggiornamento della versione principale del database PostgreSQL?

Potresti trovarti in una situazione diversa, poiché la maggior parte delle aziende ha una finestra di aggiornamento e quindi potresti permetterti dei tempi di inattività durante l'aggiornamento. Questo però porta due problemi. Per prima cosa, a nessuna azienda piacciono i tempi di inattività anche se sono consentiti. E, cosa ancora più importante, una volta che le dimensioni del database superano i gigabyte nell'intervallo di terabyte o centinaia di terabyte, i tempi di inattività possono richiedere giorni o addirittura settimane e nessuno può permettersi di interrompere le proprie operazioni per così tanto tempo. Il risultato è che molte aziende spesso saltano aggiornamenti importanti, rendendo il prossimo ancora più doloroso. E agli sviluppatori mancano nuove funzionalità, miglioramenti delle prestazioni. Loro (le aziende) a volte rischiano persino di eseguire una versione di PostgreSQL che non è più supportata e presenta danni noti o problemi di sicurezza. Nei paragrafi seguenti parlerò un po' del mio lavoro per rendere gli aggiornamenti meno dispendiosi in termini di tempo e di conseguenza meno dolorosi e, si spera, più frequenti.

Vorrei iniziare con un po' di storia prima. Prima di PostgreSQL 9.0 l'unico modo per eseguire un aggiornamento della versione principale era eseguire pg_dump e ripristinare il dump in un'istanza che eseguiva una versione più recente di PostgreSQL. Questo metodo richiedeva che la struttura e tutti i dati venissero letti dal database e scritti in un file. Quindi leggere dal file e inserito in un nuovo database, gli indici devono essere ricostruiti, ecc.

Come puoi immaginare, questo processo può richiedere del tempo. Sono stati apportati miglioramenti alle prestazioni in 8.4 per pg_restore con l'opzione -j aggiunta in cui è possibile specificare quanti lavori paralleli devono essere eseguiti. Ciò consente di ripristinare più tabelle (indici, ecc.) in parallelo, rendendo il processo di ripristino più rapido per i dump di formato personalizzato. La versione 9.3 ha aggiunto un'opzione simile a pg_dump, migliorando ulteriormente le prestazioni. Ma data la velocità con cui crescono i volumi di dati, la parallelizzazione in sé non è sufficiente per ottenere un serio guadagno nel tempo necessario per l'aggiornamento.

Quindi in PostgreSQL 9.0 è arrivata un'utilità chiamata pg_upgrade. Pg_upgrade esegue il dump solo delle strutture e le ripristina nel nuovo cluster. Ma copia i file di dati così come sono su disco, il che è molto più veloce che scaricarli in formato logico e quindi reinserirli. Questo è abbastanza buono per i database di piccole dimensioni perché significa un tempo di inattività nell'intervallo di minuti o ore, un tempo accettabile per molti scenari. C'è anche la modalità collegamento che crea solo collegamenti reali (punti di giunzione su Windows) che rende questo processo ancora più veloce. Ma dal mio punto di vista personale è troppo pericoloso eseguire tale configurazione su un server master di produzione. Spiegherò brevemente perché. Se qualcosa va storto, una volta avviato il nuovo server che è stato aggiornato utilizzando la modalità collegamento, si è improvvisamente senza database di produzione e si deve eseguire il failover o, peggio, è necessario eseguire il ripristino dal backup. Ciò significa che non solo non sei riuscito a eseguire l'aggiornamento, ma hai solo causato ulteriori tempi di inattività! Buona fortuna per ottenere l'approvazione la prossima volta.

Ora molte persone che non possono permettersi lunghi tempi di inattività per gli aggiornamenti utilizzano le soluzioni di replica basate su trigger come Slony o Londiste per eseguire l'aggiornamento. Questa è una buona soluzione perché puoi replicare i tuoi dati mentre il server originale è in esecuzione e quindi passare con tempi di inattività minimi. In pratica ci sono però diversi problemi. Uno di questi è che le soluzioni basate su trigger sono spesso difficili da configurare, soprattutto se lo fai solo una volta ogni due anni e solo per eseguire l'aggiornamento. È anche facile perdere un tavolo o aggiungere tavoli nell'ordine sbagliato e quindi non ottenere la copia completa. Ho assistito a questo nella pratica e le persone che eseguivano l'aggiornamento stavano lavorando con la replica basata su trigger su base giornaliera . Un altro problema è che le soluzioni basate su trigger aggiungono un carico considerevole sul database di origine, rendendo talvolta impossibile l'aggiornamento a causa del sovraccarico del server del database una volta attivata la replica. E, ultimo ma spesso non meno importante, può essere necessario molto tempo prima che la replica basata su trigger sposti effettivamente i dati sul nuovo server. L'ultima volta che sono stato coinvolto in un progetto di aggiornamento, la soluzione basata su trigger ha impiegato circa un mese per copiare il database e recuperare il ritardo con le modifiche. Sì, un mese.

Con PostgreSQL 9.4 arriva la funzione di decodifica logica che offre un nuovo inizio per la progettazione di una nuova e migliore soluzione ai problemi di aggiornamento online. Quello che abbiamo fatto, nell'ambito del progetto AXLE, è creare uno strumento che combini la decodifica logica con le tecniche sopra descritte. La soluzione risolve la maggior parte dei problemi degli approcci precedenti. L'estensione Uni-Directional Replication PostgreSQL (abbreviato UDR) esegue la replica logica utilizzando la decodifica logica del WAL (write ahead log). Grazie a ciò, l'impatto sul server master è quasi pari alla replica fisica dello streaming, quindi il carico aggiuntivo causato dall'aggiornamento in corso è minimo sul sistema in esecuzione. Fornisce inoltre strumenti per inizializzare nuovi nodi, sia utilizzando il backup fisico che logico. Puoi persino trasformare lo standby fisico esistente in standby UDR. E poiché si tratta di un sistema di replica logica, è possibile progettarlo in modo da supportare la replica tra versioni incrociate.

Tutto ciò significa che ora possiamo utilizzare UDR in combinazione con pg_upgrade per eseguire un aggiornamento online della versione principale di PostgreSQL con tempi di inattività minimi, in un breve lasso di tempo assoluto e con un impatto minimo sul sistema in esecuzione.

Un esempio di come può apparire nella pratica:

  • Esegui pg_basebackup dell'istanza esistente.
  • Imposta la replica UDR tra l'istanza originale e quella creata da basebackup.
  • Pg_upgrade la nuova istanza.
  • Consenti a UDR di riprodurre le modifiche avvenute nel frattempo.
  • Passa il traffico alla nuova istanza.

Per istruzioni con istruzioni più dettagliate, vedere la guida all'aggiornamento in linea UDR sul wiki di PostgreSQL. I sorgenti UDR sono disponibili nel repository 2ndquadrant_bdr sul server git di PostgreSQL (bdr-plugin/next branch).

Infine, poiché UDR non è solo uno strumento di aggiornamento online ma anche una soluzione di replica, può essere utilizzato per le normali esigenze di replica, invece della replica fisica in streaming. Inoltre offre numerosi vantaggi come la possibilità di creare tabelle temporanee, replicare da più database OLTP in un database di big data warehouse o replicare solo una parte del database.

La mia speranza è che questo sforzo significhi che le considerazioni sui tempi di inattività non siano più un problema quando si tratta di eseguire l'aggiornamento da PostgreSQL 9.4 e versioni successive a una nuova versione principale.

La ricerca che ha portato a questi risultati ha ricevuto finanziamenti dal Settimo programma quadro dell'Unione europea (7° PQ/2007-2013) nell'ambito della convenzione di sovvenzione n. 318633.