Introduzione

  • Il database versioning è una pratica di gestione delle versioni delle strutture e dei dati di un database in modo simile alla gestione del codice sorgente in un sistema di controllo delle versioni (VCS).

  • Questa pratica è fondamentale per mantenere la coerenza, la tracciabilità e la riproducibilità delle modifiche apportate al database nel tempo, soprattutto in ambienti di sviluppo software complessi dove più sviluppatori lavorano in modo distribuito e collaborativo e dove il database è un componente critico del sistema.

  • Obiettivi principali

    • Ricreare un database da zero.
    • Mantenere sempre chiaro lo stato del database.
    • Migrazione deterministica dalla versione corrente del database a una più recente o anche più vecchia.
    • Assicurare che tutti gli sviluppatori lavorino con la stessa versione del database.
    • Facilitare il deployment delle modifiche al database (preferibilmente con strumenti CI/CD)
    • Permettere il rollback in caso di errori.
1 / 24
1

Introduzione

  • Il database versioning è una pratica di gestione delle versioni delle strutture e dei dati di un database in modo simile alla gestione del codice sorgente in un sistema di controllo delle versioni (VCS).

  • Questa pratica è fondamentale per mantenere la coerenza, la tracciabilità e la riproducibilità delle modifiche apportate al database nel tempo, soprattutto in ambienti di sviluppo software complessi dove più sviluppatori lavorano in modo distribuito e collaborativo e dove il database è un componente critico del sistema.

  • Obiettivi principali

    • Ricreare un database da zero.
    • Mantenere sempre chiaro lo stato del database.
    • Migrazione deterministica dalla versione corrente del database a una più recente o anche più vecchia.
    • Assicurare che tutti gli sviluppatori lavorino con la stessa versione del database.
    • Facilitare il deployment delle modifiche al database (preferibilmente con strumenti CI/CD)
    • Permettere il rollback in caso di errori.
2
3

Componenti chiave del database versioning

  • Controllo delle versioni degli schemi
    • Gestione delle versioni degli schemi di database, che include tabelle, indici, viste, procedure, trigger, e altri oggetti di database. Ogni modifica a questi oggetti viene tracciata e documentata.
  • Migrazioni del database
    • È uno script che apporta una modifica specifica allo schema del database, come l’aggiunta di una nuova tabella, la modifica di una colonna, o l’eliminazione di un indice. Le migrazioni possono essere applicate in sequenza per aggiornare lo schema del database da una versione precedente a una nuova versione.
  • Rollback
    • La capacità di annullare una migrazione, tornando a una versione precedente dello schema. Questo è utile per gestire errori o modifiche non desiderate.
  • Script di seed e fixture
    • Script utilizzati per popolare il database con dati iniziali o di esempio, necessari per testare l’applicazione (vedi integration test).
4

Benefici del database versioning

  • Coerenza
    • Garantisce che tutti i membri del team di sviluppo lavorino con la stessa versione dello schema del database, riducendo il rischio di conflitti e incoerenze.
  • Tracciabilità
    • Ogni modifica al database è tracciata con un record chiaro di chi ha fatto cosa e quando. Questo facilita il debug e la manutenzione; inoltre, è utile per scopi di audit e conformità.
  • Automazione
    • Le migrazioni possono essere automatizzate, facilitando l’implementazione delle modifiche in ambienti diversi, come sviluppo, test e produzione.
  • Riproducibilità
    • Permette di ricreare esattamente la stessa versione del database in qualsiasi momento, utile per replicare bug o testare nuove funzionalità.
5

La sicurezza delle Migrazioni 1/3

Per migliorare la sicurezza quando si utilizzano strumenti di Database Migration senza concedere privilegi di livello DBA agli utenti delle applicazioni, si possono adottare diverse strategie.

  • Account separati per le migrazioni
    • Utilizza un account separato con privilegi elevati esclusivamente per le migrazioni. Questo account dovrebbe essere utilizzato solo durante il processo di deployment o aggiornamento del database e non essere accessibile all’applicazione stessa.
  • Utilizzo di un servizio intermedio
    • Implementa un servizio intermedio o un job runner che ha i privilegi necessari per eseguire le migrazioni. L’applicazione comunica con questo servizio quando è necessario eseguire una migrazione. Questo permette di mantenere i privilegi elevati isolati dall’applicazione.
  • Gestione delle migrazioni tramite CI/CD
    • Integra le migrazioni del database nella pipeline di Continuous Integration/Continuous Deployment (CI/CD). I sistemi CI/CD possono essere configurati con credenziali di amministratore del database, riducendo la necessità per gli utenti applicativi di avere tali privilegi.
6

La sicurezza delle Migrazioni 2/3

  • Ruoli con privilegi limitati
    • Configura ruoli specifici con i minimi privilegi necessari per eseguire migrazioni. Per esempio, puoi creare un ruolo che ha solo i permessi per modificare schemi specifici o eseguire particolari comandi DDL (Data Definition Language).
  • Migrazioni supervisionate
    • Esegui migrazioni manualmente o semi-automaticamente sotto la supervisione di un DBA. Questo approccio è più sicuro ma può essere meno pratico per ambienti con frequenti rilasci.
  • Sandbox per test e approvazione
    • Prima di eseguire migrazioni sul database di produzione, esegui tutte le migrazioni in un ambiente di sandbox o staging. Questo ambiente può essere una copia del database di produzione dove è possibile testare le migrazioni senza rischi. Una volta verificate, le migrazioni possono essere applicate in produzione da un DBA.
7

La sicurezza delle Migrazioni 3/3

  • Logging e auditing
    • Abilita il logging e l’auditing delle migrazioni per tracciare quali modifiche sono state fatte, quando e da chi. Questo non solo migliora la sicurezza, ma aiuta anche nella diagnosi di eventuali problemi.
  • Gestione delle chiavi di accesso
    • Usa strumenti di gestione delle chiavi di accesso come HashiCorp Vault, AWS Secrets Manager o Azure Key Vault per gestire e distribuire le credenziali di accesso verso i database in modo sicuro.


Implementando queste strategie, è possibile ridurre significativamente il rischio associato alla concessione di privilegi elevati agli utenti delle applicazioni durante le migrazioni del database, mantenendo al contempo un flusso di lavoro efficiente per la gestione delle migrazioni stesse.

8

Strumenti comuni per il database versioning

  • Flyway
    • Uno strumento di migrazione del database open-source che utilizza script SQL o Java per definire le migrazioni. È noto per la sua semplicità e facilità di integrazione con i processi CI/CD.
  • Liquibase
    • Un altro strumento di migrazione del database open-source che supporta una varietà di formati di definizione delle migrazioni, tra cui SQL, XML, YAML e JSON. È potente e flessibile, con una buona integrazione con gli strumenti DevOps.
  • Alembic
    • Uno strumento per la gestione delle migrazioni del database, spesso utilizzato con SQLAlchemy in progetti Python. Fornisce un framework per la creazione, l’applicazione e la gestione delle migrazioni del database.
9

Esempio di script di migrazione

  • Script SQL (esempio Flyway)
    • Versione 1.0.0: Crea la tabella users con campi id, username ed email.
    • Versione 1.1.0: Aggiunge il campo last_login alla tabella users.

-- Versione 1.0.0
CREATE TABLE users (
    id INT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

-- Versione 1.1.0
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;

Per eseguire la migrazione è sufficiente eseguire il comando flyway migrate nella directory contenente gli script di migrazione.

10

Esempio di progetto di migrazione con Flyway 1/8

Brevemente vedremo com’è strutturato un classico progetto di migrazione del database usando Flyway e come gestire le migrazioni attraverso la CLI (Command Line Interface) messa a disposizione. La versione di riferimento è la OSS Edition v10.13.0

Un progetto standard (standalone) in genere include: script di migrazione, configurazione di Flyway e uno script di esecuzione (quest’ultimo opzionale e costruito sulla base delle proprie esigenze).

# V: Indica che si tratta di una migrazione versionata. È un prefisso obbligatorio.
# <Version>: Numero di versione della migrazione. Può essere un numero intero (es. 1, 2, 3) o semantic version. Le versioni devono seguire un ordine naturale per Flyway.
# __: Doppio underscore come separatore tra il numero di versione e la descrizione. È obbligatorio.
# <Description>: Descrizione della migrazione. Deve essere una stringa descrittiva senza spazi (può usare underscore 
# _ o trattini - per separare le parole). La descrizione è facoltativa ma consigliata per rendere il file di migrazione leggibile e comprensibile.
├── flyway.toml
├── migrate.sh
└── sql
    ├── V1.0.0__create_users_table.sql
    ├── V1.1.0__add_email_to_users.sql
    ├── V2.0.0__create_orders_table.sql
    └── V2.0.1__add_foreign_key_to_orders.sql
  • flyway.toml: contiene le configurazioni di Flyway (comprese le informazioni di connessioni al database)
  • migrate.sh: script shell che esegue la migrazione
11

Esempio di progetto di migrazione con Flyway 2/8

Configurazione di Flyway tramite il file di properties flayway.toml ed esecuzione della migrazione attraverso lo script shell migrate.sh

# More information on the parameters can be found
# here: https://documentation.red-gate.com/flyway/flyway-cli-and-api/configuration/parameters

[environments.default]
url = "jdbc:postgresql://localhost:5432/migration_db"
user = "migration_user"
password = "migration_password"

[flyway]
locations = ["filesystem:sql"]

Il file di configurazione è in formato TOML - Tom’s Obvious, Minimal Language e sostituisce il formato tradizionale (legacy) conf (properties format). Per maggiori consultare la guida TOML Configuration.

12

Esempio di progetto di migrazione con Flyway 3/8

#!/usr/bin/env bash

# Assicurati che Flyway sia installato e che il comando `flyway` sia disponibile nel PATH
# Puoi installare Flyway seguendo le istruzioni 
# qui: https://documentation.red-gate.com/fd/command-line-184127404.html

# Esegui la migrazione
flyway migrate

# Visualizza lo stato delle migrazioni
flyway info

Il comando di migrazione di Flyway (flyway migrate) è uno degli strumenti principali utilizzati per applicare le modifiche al database, mentre il comando flyway info visualizza le informazioni circa lo stato delle migrazioni.

Nelle successive slide vedremo una spiegazione breve e dettagliata di come funziona il processo di migrazione, che in genere i vari tool gestiscono alla stesso modo.

13

Esempio di progetto di migrazione con Flyway 4/8

Sotto il cofano, l’esecuzione del comando flyway migrate esegue le seguenti attività.

  1. Configurazione
    • Flyway legge la configurazione da flyway.toml, flyway.conf o dalle variabili d’ambiente. Queste configurazioni includono le informazioni di connessione al database, la posizione degli script di migrazione, e altre impostazioni.
  2. Connessione al Database
    • Flyway si connette al database specificato usando le credenziali fornite nella configurazione.
  3. Verifica della Tabella di Metadati
    • Flyway verifica l’esistenza di una tabella di metadati (di solito chiamata flyway_schema_history) nel database. Questa tabella tiene traccia delle migrazioni che sono state già applicate al database.
  4. Ricerca delle Migrazioni
    • Flyway cerca gli script di migrazione nelle posizioni specificate (come filesystem:sql). Gli script devono seguire una convenzione di denominazione specifica (es., V1__init.sql, V2__add_email_to_users.sql).
14

Esempio di progetto di migrazione con Flyway 5/8

  1. Ordinamento delle Migrazioni
    • Flyway ordina gli script di migrazione in base alla loro versione. Le versioni devono essere univoche e incrementali.
  2. Verifica degli Stati delle Migrazioni
    • Flyway confronta le migrazioni trovate con quelle registrate nella tabella di metadati. Se ci sono nuove migrazioni che non sono state ancora applicate, Flyway le identifica.
  3. Applicazione delle Migrazioni
    • Flyway applica le nuove migrazioni in ordine sequenziale. Per ogni migrazione:
      1. Esegue il codice SQL nello script.
      2. Aggiorna la tabella di metadati per registrare che la migrazione è stata applicata correttamente.
      3. Se una migrazione fallisce, Flyway interrompe il processo e segnala l’errore.
  4. Conferma dello Stato Finale
    • Dopo aver applicato tutte le migrazioni, Flyway aggiorna la tabella di metadati e fornisce un riepilogo delle migrazioni applicate, quelle in sospeso, e qualsiasi errore che potrebbe essersi verificato.
15

Esempio di progetto di migrazione con Flyway 6/8

Quelli a seguire sono gli script SQL di migrazione che rappresentano rispettivamente le versioni del database: 1.0.0, 1.1.0, 2.0.0 e 2.0.1.

-- Code 1 - Script di migrazione V1.0.0__create_users_table.sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL
);
-- Code 2 - Script di migrazione V1.1.0__add_email_to_users.sql
ALTER TABLE users ADD COLUMN email VARCHAR(100);
-- Code 3 - Script di migrazione V2.0.0__create_orders_table.sql
CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    user_id INT NOT NULL,
    order_date TIMESTAMP NOT NULL,
    FOREIGN KEY (user_id) REFERENCES users(id)
);
-- Code 4 - Script di migrazione V2.0.1__add_foreign_key_to_orders.sql
ALTER TABLE orders ADD CONSTRAINT fk_user
FOREIGN KEY (user_id) REFERENCES users(id);
16

Esempio di progetto di migrazione con Flyway 7/8

Prima di eseguire il processo di migrazione, proviamo a vedere lo stato attuale del database eseguendo il comando flyway info.

Flyway OSS Edition 10.13.0 by Redgate

See release notes here: https://rd.gt/416ObMi
Database: jdbc:postgresql://localhost:5432/migration_db (PostgreSQL 16.3)
Schema history table "public"."flyway_schema_history" does not exist yet
Schema version: << Empty Schema >>

+-----------+---------+---------------------------+------+--------------+---------+----------+
| Category  | Version | Description               | Type | Installed On | State   | Undoable |
+-----------+---------+---------------------------+------+--------------+---------+----------+
| Versioned | 1.0.0   | create users table        | SQL  |              | Pending | No       |
| Versioned | 1.1.0   | add email to users        | SQL  |              | Pending | No       |
| Versioned | 2.0.0   | create orders table       | SQL  |              | Pending | No       |
| Versioned | 2.0.1   | add foreign key to orders | SQL  |              | Pending | No       |
+-----------+---------+---------------------------+------+--------------+---------+----------+

L’output mostrato è quello atteso, dato che il database è praticamente "nuovo", ovvero, non ha ancora subito nessun processo di migrazione.

17

Esempio di progetto di migrazione con Flyway 8/8

A seguire un video che mostra l’esecuzione di una serie di migrazioni partendo da zero. Il video è accelerato 3 volte per questioni di tempo. Qui https://asciinema.org/a/660361 puoi trovare il video completo.

Esecuzione della prima migrazione del database
18

Conclusioni

  • Riepilogo dei punti chiave

    • Il Database Versioning è fondamentale per mantenere la coerenza e la tracciabilità delle modifiche al database.
  • Importanza della disciplina nel versioning

    • È importante seguire una disciplina rigorosa per gestire le versioni e automatizzare il più possibile il processo.
  • Prossimi passi per implementare il database versioning

    • Scegliere uno strumento di versioning appropriato.
    • Integrare il versioning nel flusso di lavoro del team.
    • Formare il team sulle migliori pratiche di migrazione.
19

Riferimenti riguardo il Database Versioning 1/3

  1. Libri
    • Refactoring Databases: Evolutionary Database Design" by Scott W. Ambler and Pramodkumar J. Sadalage: questo libro offre una panoramica completa sull’evoluzione del database e sulle tecniche per gestire le modifiche in modo sicuro ed efficace (https://amzn.to/4bshqOe).
    • Migrating to Microservice Databases: From Relational Monolith to Distributed Data" by Edson Yanaga: questo libro si concentra sulla migrazione dei database in un ambiente di microservizi, ma offre anche una buona copertura del versioning del database in questo contesto (https://developers.redhat.com/e-books/migrating-microservice-databases-relational-monolith-distributed-data).
20

Riferimenti riguardo il Database Versioning 2/3

  1. Risorse Online
    • Flyway Documentation: la documentazione ufficiale di Flyway fornisce una guida completa sull’uso di Flyway per la migrazione e il versioning del database. Include esempi pratici, suggerimenti e casi d’uso comuni (https://documentation.red-gate.com/fd/flyway-documentation-138346877.html).
    • Liquibase Documentation: altro popolare strumento di versioning del database, ha una documentazione dettagliata che copre i concetti di base, le migliori pratiche e le varie funzionalità offerte (https://docs.liquibase.com/home.html).
    • Database Continuous Delivery by Yaniv Yehuda: A fast moving world; Agile, DevOps & Automation (https://www.infoq.com/articles/Database-Continuous-Delivery/).
    • Evolutionary Database Design by Martin Fowler and Pramod Sadalage: tecniche che consentono alla progettazione di un database di evolversi man mano che si sviluppa un’applicazione (https://martinfowler.com/articles/evodb.html).
21

Riferimenti riguardo il Database Versioning 3/3

  1. Risorse Online - Frameworks Java
    • Quarkus: Using Flyway: guida ufficiale su come utilizzare Flyway con Quarkus (https://quarkus.io/guides/flyway).
    • Quarkus: Using Liquibase: guida ufficiale su come utilizzare Liquibase con Quarkus (https://quarkus.io/guides/liquibase).
    • Using Liquibase with Spring Boot: lo scopo di questo tutorial è guidarti attraverso il processo di utilizzo di Liquibase come parte del flusso di lavoro Spring Boot (https://contribute.liquibase.com/extensions-integrations/directory/integration-docs/springboot/).
    • Intro to Database Migrations in Spring Boot 3 with Flyway: in questo video è mostrato come integrare Flyway in un’applicazione Spring Boot 3 e utilizzarlo per gestire in modo efficace le migrazioni dei database. Concetti di base di Flyway, come la sua configurazione, la creazione ed esecuzione di script di migrazione e il controllo delle versioni del database (https://www.youtube.com/watch?v=p1V5GcKUJv0).
22

Domande?

Grazie per l’attenzione! Se avete domande, sono qui per rispondere.

23

About Me

  • Nome: Antonio Musarra
  • Professione: Software Architect, Tech Blogger
  • Località: Roma

Contatti

  • Email: antonio.musarra@gmail.com
  • LinkedIn: https://www.linkedin.com/in/amusarra/
  • My GitHub Repositories: https://github.com/amusarra
  • My Blog: https://www.dontesta.it
24