Ripristina il tuo DB Oracle con i Restore Point

R

rollback di un aggiornamento software

L’upgrade di un software di produzione e’ sicuramente una delle operazioni più’ critiche nell’industria del software. Il software evolve sempre più’ velocemente ed e’ necessario prevedere rilasci frequenti sposando le metodologie previste nella disciplina  Continuous Integration e Continuous Delivery. Ma che succede se qualcosa va storto ? E’ sempre fattibile effettuare il rollback dell aggiornamento (ovvero ripristinare il software alla versione precedente) ?

Le domande sopra riportate possono sembrare banali ma in realtà’ non lo sono affatto. Cerchiamo di rispondere “step by step”.

sistemi di versioning

Escludendo per adesso la componente dati rappresentata dal DBMS, i sistemi di versioning svolgono un ruolo fondamentale per avere tutte le carte a disposizione per ripristinare il vostro software alla versione precedente. Qualsiasi sistema di versioning ha a disposizione la TAG feature. Il tagging viene generalmente utilizzato per acquisire un punto nella history  utilizzato per una versione di rilascio contrassegnata (ad esempio v1.0.1). Se seguiamo la best practices di taggare ogni versione rilasciata, sara’ facilmente ripristinare il vostro software alla versione rappresentata da un determinato TAG.

database versioning e best practices

Spesso un upgrade di un software comporta delle modifiche lato DBMS: ad esempio per un upgrade di versione del software potrebbe essere necessario creare una nuova tabella, modificarne una esistente o inserire/aggiornare record nel database. Quando siamo da soli a sviluppare e il progetto non e’ in produzione spesso trascuriamo la problematica del versioning del database ma non sappiamo a cosa andiamo in contro: Che succede quando nel team entra un nuovo collega che ha bisogno di riprodurre nel proprio db locale le strutture dati necessarie agli sviluppi dell’applicazione ? Come possiamo sincronizzare diversi ambienti di sviluppo? Come identificare gli aggiornamenti che ha bisogno un database per una determinata versione del software ? Come tenere sincronizzati i database di diversi clienti i quali magari hanno anche diverse versioni del software?  Le domande e i dubbi sono molti, in letteratura sono nate diverse best practices che riporto in maniera riassuntiva:

  • Database sotto sistema di versioning
  • Identificare con la semantic version la versione delle strutture dati di un database ( come per il tag nei sistemi di versioning)
  • Riportare tale versione in una tabella o procedura in modo che uno sviluppatore in ogni istante con una banale select possa identificare la versione attuale.
  • Ogni intervento al DB deve essere fatto tramite script e quindi sono banditi interventi manuali. Riporto alcune best practices sul come devono essere strutturati tali script:
    • separare gli interventi per Schema e per Tipo di Operazione (DDL o DML). Pertanto un determinato file conterrà’ al suo interno operazioni DDL o DML da eseguire su un determinato schema.
    • utilizzare una convention per il nome degli script: ad es Upgrade_DDL_SchemaX_from_1.0.1_to_1.0.2
    • tali script sono immutabili e tenuti sotto un sistema di versioning
    • Ogni script a fine esecuzione inserisce un record in una tabella la quale contiene il log di tutti gli script eseguiti.

Le Best Practices sopra riportate agevolano l’evoluzione di un Database ma non risolvono il tema cuore di questo articolo: come effettuare il ripristino ad una versione precedente del Database. Quello che si può’ fare e’ scrivere per ogni script di upgrade anche lo script di undo, il quale deve contenere tutti i comandi da eseguire per fare il downgrade di versione. Tale attività’ e’ molto dispendiosa e molti sviluppatori non la attuano con il conseguente rischio di complicare l’eventuale attività’ di ripristino in caso di bisogno. Non sottovalutate che sia cosi’ rara la necessita’ di roll-back di un rilascio: nella mia vita da sviluppatore e’ capitato più’ volte che uno sviluppatore rilasciasse uno script DDL con alcuni errori di sintassi. In tale situazione accade che lo script di aggiornamento termina non appena viene eseguita l’istruzione contenente l’errore consolidando le modifiche apportate dalle istruzioni precedenti essendo le istruzioni DDL, nella maggior parte dei database,  non transazionali e quindi con commit implicito. In tali scenari il database si trova in uno stato indefinito ed e’ quindi importante avere un piano di rollback per ripristinare velocemente il database alla versione precedente. Se fate uso di un database Oracle, potete fare uso della seguente feature: restore point.

restore point in oracle

Oracle Flashback Database e i restore point (punti di ripristino) ci consentono di ripristinare lo stato del database: come con l’uso dei TAG nei VCS, con i restore point e’ possibile riportare l’intero Database indietro nel tempo fornendo una valida alternativa al Recovery. I restore point non sono efficaci solo nelle tradizionali situazioni di recovery del database, ma possono anche essere utili  in seguito a caricamenti massivi o aggiornamenti applicativi non andati a buon fine oppure dopo l’esecuzione di una suite test per ripristinare il database. Il suo funzionamento si basa sull’utilizzo di particolari Log che sono memorizzati nella Fast Recovery Area che, pertanto deve essere obbligatoriamente configurata. Una volta abilitata questa feature, a intervalli regolari, il database copia le immagini di ciascun blocco modificato in ogni file di dati nei registri di flashback. In questo modo Oracle e’ in grado di ripristinare lo stato in maniera veloce e sicura.

prerequisiti

1. Un requisito necessario per utilizzare questa feature e’ quella che il Database deve essere  in Archivelog Mode. Per verificare se il Database è impostato in Archivelog Mode basta eseguire il seguente comando:

SELECT LOG_MODE  FROM V$DATABASE;

2. Occorre abilitare il flashback ed eventualmente modificare il parametro DB_FLASHBACK_RETENTION_TARGET
il cui valore rappresenta di quanti minuti si può tornare indietro A partire dalla versione 11.2 è possibile attivare il Flashback Database nello stato di OPEN, mentre nelle versioni precedenti si doveva fare nello stato di MOUNT e quindi aprire il Database con l’opzione RESETLOGS. Per verificare se tale feature e’ abilitata possiamo verificarlo eseguendo la seguente query:

SELECT FLASHBACK_ON  FROM V$DATABASE;

Per abilitare le flashback features basterà’ esegure da sys

ALTER DATABASE FLASHBACK ON;

In qualsiasi momento si voglia disabilitare l’uso dei restore point basta eseguire il comando di disattivazione:

ALTER DATABASE FLASHBACK OFF

ripristino utilizzando RESTORE POINT

Una volta che il Flashback database è attivato è possibile riportare indietro nel tempo il Database mediante uno dei seguenti comandi:

FLASHBACK DATABASE TO SCN <scn>;

FLASHBACK DATABASE TO TIMESTAMP <data>;

FLASHBACK DATABASE TO SEQUENCE <sequende_number>;

FLASHNACK DATABASE TO RESTORE POINT <nome_restore_point>;

FLASHBACK DATABASE TO BEFORE SCN <scn>;

FLASHBACK DATABASE TO BEFORE TIMESTAMP <data>;

FLASHBACK DATABASE TO BEFORE SEQUENCE <sequende_number>;

FLASHBACK DATABASE TO BEFORE RESETLOGS;

Cerchiamo di capire come funzionano con un esempio pratico. Come già’ accennato i restore point sono molto utili durante il rilascio di un aggiornamento software che comporta modifiche al db; essi se qualcosa va storto possono essere la soluzione al problema di ripristino. Per capirci meglio facciamo un esempio”:

  • Supponiamo di seguire le best practices elencate ad inizio articolo e che quindi l attuale stato del db sia identificato da una versione 1.0.0.
  • Supponiamo che dobbiamo installare un aggiornamento del database che comporta una serie di operazioni DDL e DML contenute in uno script Upgrade_DDL_SchemaX_from_1.0.0_to_1.0.1.SQL

Per assicurarmi una veloce via di ripristino procediamo quindi nella creazione del restore point prima di eseguire lo script di upgrade.

create restore point before_upgrade_100_to_101;

Questo comando crea un named restore point, che non e’ altro che un alias del system change number (SCN) del database in quell’istante.

A questo punto posso eseguire  lo script di upgrade in totale tranquillita’:se qualcosa va storto posso ripristinare il database al restore point precedentemente creato eseguendo il comando

flashback database to restore point before_upgrade_100_to_101;

Una volta completata l’operazione di upgrade o ripristino possiamo quindi eliminare il restore point eseguendo il comando

drop restore point before_upgrade_100_to_101;

Ricordiamoci che possiamo in ogni momento conoscere i restore point attivi eseguendo il comando

LIST RESTORE POINT ALL;

Guaranteed Restore Points

Come un normale restore point, un guaranteed restore point (punto di ripristino garantito) funge da alias per un SCN nelle operazioni di ripristino. La differenza principale con i normali restore point è che i guaranteed restore points  non “invecchiano” mai dal file di controllo e devono essere eliminati in modo esplicito. In generale, è possibile utilizzare un punto di ripristino garantito come alias per un SCN con qualsiasi comando che funzioni con un normale punto di ripristino. Ad eccezione di quanto indicato, le informazioni su dove e come utilizzare i normali punti di ripristino si applicano anche ai punti di ripristino garantiti. Un punto di ripristino garantito assicura che è possibile utilizzare il database Flashback per eseguire il ripristinare lo stato del database allo stato identificato dal SCN a cui punta il restore point, anche se la generazione di registri di flashback è disabilitata. Se la registrazione flashback è abilitata, un punto di ripristino garantito impone la conservazione dei log di flashback richiesti per il database Flashback su qualsiasi SCN dopo il primo punto di ripristino garantito.  La sintassi del comando per la creazione di un punto di ripristino garantito e’ la seguente

CREATE RESTORE POINT before_damage GUARANTEE FLASHBACK DATABASE;

CONCLUSIONI

I restore point sono feature davvero interessante, essi ci permettano di far tornare indietro lo stato del database in maniera veloce e sicura garantendo un piano di fuga per una release andata male. Essi sono anche molto utili in ambito di testing: e’ possibile eseguire una suite di test e ripristinare lo stato dopo l’esecuzione dei test. Se siete interessati a questa feature vi consiglio di leggere la documentazione ufficiale e il seguente articolo che riporta una serie di esempi pratici e best practices di utilizzo.

 

A proposito di me

Dario Frongillo

Uno degli admin di Italiancoders e dell iniziativa devtalks.
Dario Frongillo è un software engineer e architect, specializzato in Web API, Middleware e Backend in ambito cloud native. Attualmente lavora presso NTT DATA, realtà di consulenza internazionale.
E' membro e contributor in diverse community italiane per developers; Nel 2017 fonda italiancoders.it, una community di blogger italiani che divulga articoli, video e contenuti per developers.

Gli articoli più letti

Articoli recenti

Commenti recenti