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:
- Application inventory: tutti i sistemi che connettono al database (ERP, CRM, web app, batch jobs)
- Connection strings: hostname attuale, porta, credential — tutte le applicazioni
- Query pattern analysis: identifica query che potrebbero soffrire latenze maggiori (cross-join, full table scans)
- 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)
- Freeze delle modifiche: comunica al team che nessuna modifica dati manuale sarà permessa durante la finestra
- Pausa la replica DMS se usi CDC, per assicurarti che tutti i dati siano sincronizzati
- Backup finale del sorgente: snapshot o mysqldump point-in-time
- 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
- Stop applicazioni dal connettere a RDS
- Aggiorna DNS al vecchio hostname
- Ripristina connection string applicative
- Verifica connettività alla sorgente originale
- Validazione funzionale su ambiente sorgente
- 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:
- Assessment di 4 settimane per mappare tutte le dipendenze prima di scegliere la strategia
- Strategia dimensionata: mysqldump per < 50 GB, DMS per dataset più grandi
- Staging che replica production per validation realistica
- Rollback testato eseguito in staging almeno 48 ore prima della migrazione
- 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