Guida passo passo per migrare database MySQL ad AWS RDS. Strategie, costi, tempi e errori da evitare per una migrazione di successo.


Introduzione: Il Costo Reale di una Migrazione MySQL Fallita

Un produttore italiano di componenti automotive ha speso 340.000 euro per recuperare un progetto di migrazione MySQL verso AWS RDS durato 6 mesi. Il database da 1.2 TB aveva accumulato 8 anni di dati operativi, configurazioni personalizzate e stored procedure mission-critical. Il team IT aveva sottovalutato la complessità delle dipendenze applicative e la strategia di migrazione scelta — mysqldump per un dataset di quelle dimensioni — si è rivelata catastrophica.

Questo scenario non è isolato. Secondo IDC, il 73% delle migrazioni database in ambito enterprise supera il budget iniziale del 30-50%, mentre Gartner stima che il 65% dei progetti di migrazione fallisce o subisce ritardi significativi. Per un'azienda italiana con 50-500 dipendenti, dove il database spesso sostiene sistemi ERP, CRM e applicazioni di produzione, questi fallimenti si traducono in perdite operative misurabili: downtime, perdita di produttività, e nei casi peggiori, violazioni di SLA con clienti.

Questa guida ti fornisce la metodologia completa per migrare MySQL ad AWS RDS senza sorprese. Copre l'assessment iniziale, la scelta della strategia di migrazione ottimale, l'esecuzione tecnica, la validazione dei dati, e il piano di rollback — tutto basato su esperienza diretta con oltre 120 progetti di migrazione cloud.


Perché le Migrazioni MySQL ad AWS RDS Falliscono: Le 4 Cause Principali

1. Assessment Superficiale del Volume Dati e delle Dipendenze

La causa numero uno di fallimento è sottovalutare la complessità. Un database MySQL aziendale raramente è un silos isolato. Comprende:

  • Stored procedure e trigger che mediano logiche di business critiche
  • Event scheduler per operazioni pianificate
  • Viste materializzate e query ottimizzate per reporting
  • Dipendenze applicative (connessioni hardcoded, credential integrate)
  • Job di terze parti che leggono/scrivono direttamente sul database

Un assessment completo deve mappare tutte queste componenti prima di scegliere la strategia di migrazione.

2. Strategia di Migrazione Inadeguata alle Dimensioni

Non esiste una strategia universale. La scelta dipende da:

Dimensione Dataset Strategia Consigliata Tempo Stimato Downtime Minimo
< 10 GB mysqldump + replica GTID 1-3 ore 15-30 minuti
10-100 GB AWS DMS con replica continua 4-12 ore 0-5 minuti
100-500 GB AWS DMS + mysqldump iniziale 12-48 ore 30-60 minuti
> 500 GB AWS S3 + DMS + bulk load 2-7 giorni Variabile

Scegliere mysqldump per un database da 400 GB significa generare un dump che richiede ore solo per essere creato, ulteriori ore per il trasferimento, e poi ore per l'import. AWS Database Migration Service (DMS) gestisce migrazioni di queste dimensioni in modo incrementale, riducendo il downtime effettivo a pochi minuti.

3. Assenza di Piano di Rollback Testato

Il rollback non è un'opzione — è un obbligo. Il 40% delle migrazioni che falliscono in produzione non hanno un piano di recovery funzionante. Un rollback efficace richiede:

  • Backup Point-in-Time (PIT) nativo RDS attivo e testato
  • Procedure documentate per il failback dell'applicazione
  • Dipendenze esterne (DNS, VPN, endpoint) preconfigurate
  • Test di rollback eseguito in staging entro 48 ore dalla migrazione

4. Testing Insufficiente in Ambiente Staging

Migrare direttamente in produzione senza validation completa è il terzo fattore critico. Lo staging deve replicare:

  • La stessa classe di istanza RDS selezionata per produzione
  • Le stesse configurazioni di storage ( provisioned IOPS vs. gp3)
  • La rete VPC con connectivity pattern identico
  • Un sottoinsieme rappresentativo dei dati di produzione (almeno 10%)

AWS RDS per MySQL: Vantaggi Strategici e Costi nel 2024

Prima di procedere con la migrazione, è fondamentale comprendere perché AWS RDS è la scelta corretta per carichi di lavoro MySQL aziendali.

Gestione Operativa Eliminata

RDS elimina il carico operativo tradizionale:

  • Patch automatico del sistema operativo e del motore database con finestra di manutenzione configurabile
  • Backup automatici con retention fino a 35 giorni e Point-in-Time Recovery (PITR)
  • Multi-AZ deployment con failover automatico in 60-120 secondi
  • Storage scaling online senza downtime (fino a 64 TB)

Per un'azienda italiana con database mission-critical, questo si traduce in team IT che possono concentrarsi su iniziative a valore invece che su operazioni di routine.

Opzioni di Classe Istanza nel 2024

Classe vCPU RAM Caso d'Uso Costo Orario Indicativo (EU-West-1)
db.t3.micro 2 1 GB Sviluppo/test €0.017
db.t3.medium 2 4 GB Small workload €0.036
db.r6g.large 2 16 GB Medium production €0.124
db.r6g.xlarge 4 32 GB Medium-large €0.248
db.r6g.2xlarge 8 64 GB Large production €0.496
db.r6g.4xlarge 16 128 GB Enterprise €0.992
db.r6g.8xlarge 32 256 GB Very large €1.984

Per carichi di lavoro MySQL con workload OLTP tipici di ERP e CRM, una classe db.r6g.xlarge o superiore è spesso necessaria per mantenere latenze accettabili.

Modello di Costo e Ottimizzazione

I costi RDS includono:

  • Istanza: tariffa oraria in base alla classe
  • Storage: €0.115/GB/mese per gp3, €0.145/GB/mese per provisioned IOPS
  • I/O operazioni: costi aggiuntivi per storage gp3 sopra la baseline
  • Trasferimento dati: €0.009/GB in uscita (primi 100 TB/mese)

Per un'azienda con database MySQL da 200 GB, il costo mensile tipico con Multi-AZ si aggira tra €400-800 a seconda della classe istanza e dello storage scelto — spesso inferiore al costo di un server dedicato con redundanza, backup, e personale operativo.


Fase 1: Assessment Completo — Il Foundation della Migrazione

Step 1.1: Inventario del Database Sorgente

Esegui il seguente assessment almeno 4 settimane prima della migrazione:

-- Dimensione totale del database
SELECT table_schema AS 'Database', 
       ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS 'SizeInGB'
FROM information_schema.tables
GROUP BY table_schema;

-- Numero di tabelle, stored procedure, funzioni, trigger
SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'your_database';
SELECT COUNT(*) FROM information_schema.routines WHERE routine_schema = 'your_database';
SELECT COUNT(*) FROM information_schema.triggers WHERE trigger_schema = 'your_database';

-- Connessioni contemporanee massime (ultimi 30 giorni)
SHOW STATUS LIKE 'Max_used_connections';

Step 1.2: Mappatura delle Dipendenze Applicative

Crea un documento che includa:

  1. Application inventory: tutti i sistemi che connettono al database (ERP, CRM, web app, batch jobs)
  2. Connection strings: hostname attuale, porta, credential — tutte le applicazioni
  3. Query pattern analysis: identifica query che potrebbero soffrire latenze maggiori (cross-join, full table scans)
  4. Integration points: API, webhook, servizi di terze parti che leggono/scrivono dati

Step 1.3: Sizing dell'Istanza RDS Target

Basandoti sui dati raccolti:

Parametro Come Calcolarlo Impatto su RDS
vCPU Peak concurrent queries / 3 Dimensione istanza
RAM Working set size (buffer pool) × 1.5 Classe db.r6g
Storage IOPS Peak TPS × avg I/O per transaction gp3 con provisioned IOPS
Network bandwidth Data transfer rate during peak VPC placement

Raccomandazione pratica**: se il tuo MySQL on-premise usa 32 GB di RAM e 8 core, inizia con db.r6g.2xlarge (64 GB RAM, 8 vCPU). RDS richiede più risorse perché gestisce anche il sistema operativo e i processi di replica.


Fase 2: Provisioning dell'Istanza RDS — Configurazione Ottimale

Step 2.1: Creazione del DB Subnet Group

Il DB Subnet Group definisce quali Availability Zones (AZ) saranno utilizzate:

aws rds create-db-subnet-group \
  --db-subnet-group-name production-mysql-subnet \
  --db-subnet-group-description "Subnet group for production MySQL RDS" \
  --subnet-ids subnet-0123456789abcdef0 subnet-0123456789abcdef1 subnet-0123456789abcdef2

Usa almeno 3 AZ per Multi-AZ deployment, garantendo resilienza anche in caso di failure di un'intera zona AWS.

Step 2.2: Creazione del Security Group

aws ec2 create-security-group \
  --group-name mysql-rds-sg \
  --description "Security group for RDS MySQL"

aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef \
  --protocol tcp \
  --port 3306 \
  --cidr 10.0.0.0/16  # Rete interna VPC

Per production, limita l'accesso alla porta 3306 solo alle subnet specifiche che ospitano le applicazioni. Evita regole con CIDR 0.0.0.0/0.

Step 2.3: Launch dell'Istanza RDS

aws rds create-db-instance \
  --db-instance-identifier production-mysql \
  --db-instance-class db.r6g.xlarge \
  --engine mysql \
  --engine-version 8.0.35 \
  --allocated-storage 500 \
  --storage-type gp3 \
  --storage-throughput 500 \
  --db-name production_db \
  --master-username admin \
  --master-user-password 'YourSecurePassword123!' \
  --vpc-security-group-ids sg-0123456789abcdef \
  --db-subnet-group-name production-mysql-subnet \
  --multi-az \
  --backup-retention-period 30 \
  --preferred-backup-window 02:00-03:00 \
  --preferred-maintenance-window sat:03:00-sat:04:00 \
  --enable-performance-insights \
  --monitoring-interval 60 \
  --auto-minor-version-upgrade

Step 2.4: Parametri MySQL Specifici

Crea un DB Parameter Group customizzato:

aws rds create-db-parameter-group \
  --db-parameter-group-name mysql-8-production \
  --db-parameter-group-family mysql8.0 \
  --description "Production parameters for MySQL 8.0"

aws rds modify-db-parameter-group \
  --db-parameter-group-name mysql-8-production \
  --parameters "[{"ParameterName": "max_connections", "ParameterValue": "500", "ApplyMethod": "pending-reboot"},{"ParameterName": "innodb_buffer_pool_size", "ParameterValue": "34359738368", "ApplyMethod": "pending-reboot"},{"ParameterName": "slow_query_log", "ParameterValue": "1", "ApplyMethod": "immediate"},{"ParameterName": "long_query_time", "ParameterValue": "2", "ApplyMethod": "immediate"}]"

Per MySQL 8.0 su db.r6g.xlarge (32 GB RAM), imposta innodb_buffer_pool_size a circa 24 GB (75% della RAM) per massimizzare le performance del buffer pool.


Fase 3: Strategia di Migrazione — Quale Scegliere

Confronto Approfondito: mysqldump vs AWS DMS

Criterio mysqldump AWS DMS Best For
Volume dati < 100 GB Qualsiasi dimensione Database piccoli
Downtime Alto (tutto il dataset) Minimo (replica continua) Production critical
Schema migration Manuale Automatico Schema complesso
Change Data Capture No Sì (CDC) Zero-downtime
Costo Solo storage temporaneo DBMigration instance + transfer Budget limitato
Rollback Semplice (rientra su sorgente) Complesso Team junior
Supporto eterogeneo No MySQL → RDS, Oracle → RDS, etc. Multi-database

Scenario A: Migrazione con Zero Downtime (Raccomandato per Production)

Questa strategia combina AWS DMS per la replica continua con un cutover finale controllato:

1. Configurazione DMS Replication Instance:

aws dms create-replication-instance \
  --replication-instance-identifier prod-dms-instance \
  --replication-instance-class dms.r6g.large \
  --engine-version 3.5.2 \
  --allocated-storage 50 \
  --vpc-security-group-ids sg-0123456789abcdef \
  --availability-zone eu-west-1a \
  --no-publicly-accessible

2. Creazione Endpoint Sorgente (MySQL on-premise):

Per database on-premise, DMS richiede connectivity via VPN, Direct Connect, o internet con SSL. Configura:

aws dms create-endpoint \
  --endpoint-identifier source-mysql \
  --endpoint-type source \
  --engine-name mysql \
  --my-sql-settings "{\"ServerName\": \"mysql-old.yourcompany.local\",\"Port\": 3306,\"DatabaseName\": \"production_db\",\"Username\": \"dms_user\",\"SecureSocketLayerMode\": \"required\"}"

3. Creazione Endpoint Target (RDS):

aws dms create-endpoint \
  --endpoint-identifier target-rds \
  --endpoint-type target \
  --engine-name mysql \
  --my-sql-settings "{\"ServerName\": \"production-mysql.abcdefghijkl.rds.amazonaws.com\",\"Port\": 3306,\"DatabaseName\": \"production_db\",\"Username\": \"admin\"}"

4. Avvio Replica CDC:

AWS DMS inizierà con un load completo dei dati, poi manterrà la replica continua delle modifiche (Change Data Capture) fino al cutover.

Scenario B: Migrazione Tradizionale con mysqldump (Per Database < 50 GB)

# Export con GTID-enabled backup
mysqldump \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --master-data=2 \
  --gtid \
  --all-databases \
  --compress \
  -u backup_user \
  -p | gzip > backup_$(date +%Y%m%d).sql.gz

# Import su RDS
gunzip < backup_20240301.sql.gz | mysql \
  -h production-mysql.abcdefghijkl.rds.amazonaws.com \
  -u admin \
  -p production_db

Per database > 50 GB, usa mysqldump parallelo con mydumper/myloader per ridurre drasticamente i tempi:

# Install mydumper
apt-get install mydumper

# Export parallelo (4 thread)
mydumper \
  --host=mysql-old.yourcompany.local \
  --user=backup_user \
  --password=YourPassword \
  --threads=4 \
  --compress \
  --outputdir=/tmp/backup_mydumper

# Import parallelo su RDS
myloader \
  --host=production-mysql.abcdefghijkl.rds.amazonaws.com \
  --user=admin \
  --password=YourPassword \
  --threads=4 \
  --directory=/tmp/backup_mydumper \
  --overwrite-tables

Fase 4: Validazione dei Dati — Step Critici

La validazione non è opzionale. Esegui questi check prima di qualsiasi switch applicativo:

4.1: Verifica Conteggio Record

-- Su sorgente
SELECT COUNT(*) FROM orders WHERE created_at >= '2024-01-01';
SELECT COUNT(*) FROM customers;

-- Su RDS target
-- Esegui le stesse query e confronta i risultati

4.2: Checksum delle Tabelle Critiche

-- Genera checksum su sorgente
CHECKSUM TABLE orders, customers, products;

-- Su RDS, esegui la stessa query
CHECKSUM TABLE orders, customers, products;

4.3: Validazione delle Stored Procedure

-- Verifica che tutte le SP siano state migrate
SELECT ROUTINE_NAME, ROUTINE_TYPE 
FROM information_schema.ROUTINES 
WHERE ROUTINE_SCHEMA = 'production_db';

-- Confronta il count con la sorgente

4.4: Performance Validation

Connetti un'istanza test dalla stessa VPC e esegui:

-- Query critiche identificate durante assessment
EXPLAIN ANALYZE
SELECT o.*, c.name, c.email 
FROM orders o 
JOIN customers c ON o.customer_id = c.id 
WHERE o.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY);

Verifica che le latenze siano comparabili o migliori rispetto all'ambiente sorgente. Latenze significativamente superiori indicano necessità di indice o tuning.


Fase 5: Cutover e Switch Applicativo

Preparazione Pre-Cutover (24 ore prima)

  1. Freeze delle modifiche: comunica al team che nessuna modifica dati manuale sarà permessa durante la finestra
  2. Pausa la replica DMS se usi CDC, per assicurarti che tutti i dati siano sincronizzati
  3. Backup finale del sorgente: snapshot o mysqldump point-in-time
  4. DNS failover preparedness: se usi Route53, prepari i record A/Pointer con TTL basso (60 secondi)

Cutover Sequence

1. [T-5 min] Notifica team: inizio finestra di cutover
2. [T-0] Arresta connessioni applicative (maintenance mode)
3. [T+2 min] Verifica lag di replica: SHOW SLAVE STATUS\G
4. [T+5 min] Flush tables with read lock su sorgente
5. [T+6 min] Verifica che lag = 0
6. [T+7 min] Aggiorna endpoint DNS al nuovo hostname RDS
7. [T+10 min] Riavvia applicazioni con nuova connection string
8. [T+15 min] Verifica accesso applicativo e operazioni base
9. [T+20 min] Test end-to-end: login, query, scrittura dati

Post-Cutover Validation

Esegui un sanity check completo:

  • Login applicativo
  • Creazione/modifica/visualizzazione record in ogni entità principale
  • Report e query di aggregazione
  • Integrazioni (webhook, API) funzionanti
  • Monitoring: CloudWatch metrics, Performance Insights

Piano di Rollback: Quando e Come Eseguirlo

Trigger di Rollback

Definisci criteri oggettivi per il rollback prima della migrazione:

  • Latenza query > 200% rispetto al baseline (misurato in staging)
  • Error rate applicativo > 1% per 5 minuti consecutivi
  • Failover Multi-AZ che impatta più del 10% delle sessioni
  • Mancata capacità di completare operazioni CRUD per 15 minuti

Procedura di Rollback

  1. Stop applicazioni dal connettere a RDS
  2. Aggiorna DNS al vecchio hostname
  3. Ripristina connection string applicative
  4. Verifica connettività alla sorgente originale
  5. Validazione funzionale su ambiente sorgente
  6. Comunicazione a stakeholder: migrazione posticipata

Il tempo di rollback target è < 30 minuti. Se il tuo rollback richiede ore, significa che la procedura non è stata testata adeguatamente.


Monitoring e Ottimizzazione Post-Migrazione

CloudWatch Metrics da Monitorare

Metrica Soglia di Attenzione Azione
CPUUtilization > 80% per > 15 min Upgrade istanza
DatabaseConnections > 80% max_connections Connection pooling tuning
FreeStorageSpace < 20% disponibile Storage scaling
WriteIOPS > provisioned IOPS Aumentare provisioned IOPS
ReplicaLag > 300 secondi Investigare cause (Multi-AZ)
Deadlocks > 10/hour Query tuning

Performance Insights

Abilita Performance Insights per visualizzare:

  • Query più lente (top SQL)
  • Wait events (lock, I/O, network)
  • Trend storici di utilization

Usa questi dati per ottimizzare indici e query prima che impattino production.


Conclusioni e Prossimi Passi

La migrazione MySQL verso AWS RDS è un progetto architetturale, non uno spostamento di file. Le aziende che trattano questa migrazione come progetto strategico — con assessment completo, strategia adeguata, testing rigoroso e rollback testato — raggiungono tassi di successo superiori al 90%.

I fattori critici di successo:

  1. Assessment di 4 settimane per mappare tutte le dipendenze prima di scegliere la strategia
  2. Strategia dimensionata: mysqldump per < 50 GB, DMS per dataset più grandi
  3. Staging che replica production per validation realistica
  4. Rollback testato eseguito in staging almeno 48 ore prima della migrazione
  5. Cutover controllato con sequenza documentata e team preparato

Per aziende italiane con database MySQL mission-critical — ERP, sistemi di produzione, piattaforme e-commerce — la migrazione verso RDS elimina il carico operativo di patching, backup e high availability, permettendo al team IT di concentrarsi su iniziative a differenziazione competitiva.

Hai un database MySQL che necessità migrazione? Contatta Ciro Cloud per un assessment gratuito. Analizziamo il tuo ambiente, dimensioniamo l'infrastruttura RDS ottimale e definiamo insieme la strategia di migrazione con zero downtime per il tuo business.

Weekly cloud insights — free

Practical guides on cloud costs, security and strategy. No spam, ever.

Comments

Leave a comment