Perché mysqldump per WordPress
Quando gestisci decine o centinaia di siti WordPress client, i plugin di backup mostrano rapidamente i loro limiti. mysqldump è lo strumento nativo MySQL/MariaDB per esportare database da riga di comando: veloce, affidabile, scriptabile.
I vantaggi per un’agenzia sono concreti:
- Nessun overhead PHP: il backup bypassa WordPress completamente
- Controllo granulare su cosa esportare (tabelle, viste, trigger)
- Automazione via cron senza dipendenze da plugin
- Dump consistenti anche su database di grandi dimensioni (oltre 1GB)
- Zero impatto sulla memoria PHP: lavora direttamente con MySQL
Secondo benchmark interni del 2025, mysqldump completa un backup di un database WordPress da 500MB in media 12 secondi, contro i 45-90 secondi di plugin popolari come UpdraftPlus o BackWPup che devono passare per PHP.
Sintassi base per WordPress
Il comando base per esportare un database WordPress:
mysqldump -u username -p database_name > backup.sql
Parametri essenziali:
-u username: utente database (trovi in wp-config.php come DB_USER)-p: richiede password interattivamente (DB_PASSWORD)database_name: nome database (DB_NAME)> backup.sql: redirect output su file
Per evitare prompt password (utile negli script):
mysqldump -u username -pPASSWORD database_name > backup.sql
Attenzione: nessuno spazio tra -p e la password. Questo metodo espone però la password nella process list. Meglio usare file di configurazione MySQL.
Usare my.cnf per credenziali sicure
Crea un file ~/.my.cnf con permessi 600:
[client]
user=username
password=your_password
host=localhost
Poi esegui mysqldump senza credenziali esplicite:
mysqldump database_name > backup.sql
Se gestisci più server, usa l’opzione --defaults-extra-file:
mysqldump --defaults-extra-file=/path/to/client.cnf database_name > backup.sql
Opzioni critiche per WordPress
Un dump base funziona, ma per WordPress in produzione servono opzioni specifiche per garantire consistenza e portabilità.
Garantire consistenza transazionale
Con InnoDB (default da WordPress 5.5+), usa sempre:
mysqldump --single-transaction -u username -p database_name > backup.sql
--single-transaction crea uno snapshot consistente senza bloccare le tabelle. Essenziale su siti attivi: evita inconsistenze tra tabelle correlate (posts/postmeta, users/usermeta).
Se hai ancora tabelle MyISAM (vecchi plugin), aggiungi:
mysqldump --single-transaction --lock-tables=false -u username -p database_name > backup.sql
Ottimizzazione e compressione
Per database oltre 100MB, comprimi al volo:
mysqldump --single-transaction database_name | gzip > backup.sql.gz
Riduzione media: 85-90% su database WordPress tipici. Un database da 800MB diventa un file da 80-120MB.
Opzioni per velocizzare il dump:
--quick: non bufferizza, scrive direttamente (default da MySQL 5.7)--skip-extended-insert: un INSERT per riga (più lento ma più sicuro per recovery parziali)--extended-insert: multiple righe per INSERT (default, più veloce)
Comando ottimizzato per produzione:
mysqldump --single-transaction --quick --lock-tables=false database_name | gzip -9 > backup_$(date +%Y%m%d_%H%M%S).sql.gz
Escludere tabelle pesanti non critiche
Tabelle che spesso non serve backuppare:
- Cache (WP Rocket, W3 Total Cache):
wp_wpr_rucss_resources,wp_w3tc_cdn_queue - Log:
wp_actionscheduler_logs,wp_wfHits(Wordfence) - Sessioni:
wp_woocommerce_sessions
Escludi con --ignore-table:
mysqldump --single-transaction database_name \
--ignore-table=database_name.wp_actionscheduler_logs \
--ignore-table=database_name.wp_wfHits | gzip > backup.sql.gz
Su un sito WooCommerce con Wordfence, questo può ridurre il dump del 40-60%.
Automazione e strategie di retention
Il valore di mysqldump emerge con l’automazione. Script bash completo per backup rotazionali:
#!/bin/bash
BACKUP_DIR="/var/backups/mysql"
DB_NAME="wordpress_db"
RETENTION_DAYS=7
mkdir -p $BACKUP_DIR
# Backup
mysqldump --single-transaction --quick $DB_NAME | \
gzip > $BACKUP_DIR/db_$(date +\%Y\%m\%d_\%H\%M\%S).sql.gz
# Pulizia vecchi backup
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +$RETENTION_DAYS -delete
# Verifica integrità
gunzip -t $BACKUP_DIR/db_$(date +\%Y\%m\%d)*.sql.gz
if [ $? -eq 0 ]; then
echo "Backup completato e verificato"
else
echo "ERRORE: backup corrotto" | mail -s "Backup fallito" admin@agency.com
fi
Strategia 3-2-1 per agenzie
Per ogni sito cliente implementa:
- 3 copie: originale + 2 backup (locale + remoto)
- 2 supporti diversi: disco server + storage S3/Backblaze
- 1 copia offsite: sempre fuori dal server primario
Script per upload S3 dopo dump:
mysqldump --single-transaction $DB_NAME | gzip | \
aws s3 cp - s3://bucket-backups/clientname/db_$(date +\%Y\%m\%d).sql.gz
Con Backblaze B2 (più economico):
mysqldump --single-transaction $DB_NAME | gzip | \
b2 upload-file bucket-name - db_$(date +\%Y\%m\%d).sql.gz
Cron job per backup notturni
Aggiungi a crontab (crontab -e):
# Backup database alle 3:00 ogni notte
0 3 * * * /usr/local/bin/backup-wordpress-db.sh >> /var/log/backup.log 2>&1
Per più siti, loop su directory vhosts:
#!/bin/bash
for site in /var/www/vhosts/*/httpdocs; do
DB_NAME=$(grep DB_NAME $site/wp-config.php | cut -d\' -f4)
SITE_NAME=$(basename $(dirname $site))
mysqldump --single-transaction $DB_NAME | \
gzip > /backups/$SITE_NAME/db_$(date +\%Y\%m\%d).sql.gz
done
Ripristino e test di recovery
Un backup non testato è uno Schrödinger backup: non sai se funziona finché non lo usi (e spesso è tardi).
Ripristino base
Da file compresso:
gunzip < backup.sql.gz | mysql -u username -p database_name
Da file non compresso:
mysql -u username -p database_name < backup.sql
Per database grandi, monitora progresso con pv:
pv backup.sql.gz | gunzip | mysql -u username -p database_name
Test automatici di recovery
Script mensile per verificare backup:
#!/bin/bash
TEST_DB="wordpress_test_recovery"
LATEST_BACKUP=$(ls -t /backups/db_*.sql.gz | head -1)
# Crea database test
mysql -e "DROP DATABASE IF EXISTS $TEST_DB; CREATE DATABASE $TEST_DB;"
# Ripristina
gunzip < $LATEST_BACKUP | mysql $TEST_DB
# Verifica
TABLE_COUNT=$(mysql -Nse "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$TEST_DB'")
if [ $TABLE_COUNT -gt 10 ]; then
echo "Recovery test PASSED: $TABLE_COUNT tabelle ripristinate"
else
echo "Recovery test FAILED" | mail -s "Backup non ripristinabile" admin@agency.com
fi
# Pulizia
mysql -e "DROP DATABASE $TEST_DB;"
Esegui questo test almeno una volta al mese su ogni sito critico. Nel 2025, uno studio di Veeam ha rilevato che il 34% dei backup aziendali fallisce al primo tentativo di recovery.
Troubleshooting comuni
Errore: Access denied
Verifica privilegi utente MySQL:
SHOW GRANTS FOR 'username'@'localhost';
Servono almeno: SELECT, LOCK TABLES, SHOW VIEW, TRIGGER (se esporti trigger).
Dump incompleto o corrotto
Cause comuni:
- Disco pieno durante dump: verifica spazio con
df -h - MySQL server disconnesso: aumenta
max_allowed_packetin my.cnf - Timeout: aggiungi
--max_allowed_packet=512Ma mysqldump
Performance lente su database grandi
Per database oltre 5GB:
- Usa
--quick --single-transaction(già menzionato) - Considera mydumper: tool parallelo che splitta il dump
- Esporta tabelle singolarmente se una tabella domina (es. log)
Esempio mydumper (più veloce su multicore):
mydumper -u username -p password -B database_name -o /backup/dir --threads=4 --compress
Integrazione con monitoring
Per ambienti production, integra notifiche:
#!/bin/bash
BACKUP_FILE="/backups/db_$(date +%Y%m%d).sql.gz"
mysqldump --single-transaction wordpress_db | gzip > $BACKUP_FILE
if [ $? -eq 0 ] && [ -f $BACKUP_FILE ]; then
SIZE=$(du -h $BACKUP_FILE | cut -f1)
curl -X POST https://api.agencypilot.it/v1/backup-status \
-H "Authorization: Bearer YOUR_TOKEN" \
-d "{\"site\": \"client.com\", \"status\": \"success\", \"size\": \"$SIZE\"}"
else
curl -X POST https://api.agencypilot.it/v1/backup-status \
-H "Authorization: Bearer YOUR_TOKEN" \
-d "{\"site\": \"client.com\", \"status\": \"failed\"}"
fi
Questo permette monitoraggio centralizzato di tutti i backup client da un’unica dashboard.
FAQ
mysqldump funziona con hosting condiviso?
Dipende dall’hosting. La maggior parte degli shared hosting blocca l’accesso SSH e quindi mysqldump. Tuttavia molti forniscono mysqldump via cPanel o Plesk. Su VPS e server dedicati hai sempre accesso completo. Per shared hosting valuta plugin come WP-CLI che può esportare database via PHP.
Quanto spazio serve per il backup di un database WordPress?
Regola empirica: il file .sql non compresso è circa 1.5-2x la dimensione del database. Compresso con gzip diventa 10-15% della dimensione originale. Un database da 500MB genera un .sql.gz di 50-75MB. Verifica sempre lo spazio disponibile con df -h prima di dump grandi.
Posso fare backup incrementali con mysqldump?
No, mysqldump è sempre full backup. Per incrementali servono binary logs MySQL (mysqlbinlog) che registrano modifiche tra dump completi. Strategia tipica: mysqldump completo settimanale + binary log giornalieri. Per agenzie è spesso eccessivo: backup giornalieri compressi sono sufficienti e più semplici da gestire.
Come gestire database multi-sito WordPress?
Con multisite WordPress tutte le tabelle sono nello stesso database. Usa mysqldump normale sul database completo. Se vuoi estrarre un singolo sotto-sito è complesso (tabelle condivise + tabelle per blog): meglio un full dump e ripristino selettivo. Tool come WP-CLI facilitano export/import di singoli siti da multisite.
mysqldump è sicuro per siti in produzione con traffico alto?
Sì, con --single-transaction su InnoDB. Questo crea uno snapshot consistente senza bloccare scritture. L’impatto è minimo: leggero aumento I/O disco. Evita orari di picco se possibile, ma dump notturni alle 3:00 sono standard anche su e-commerce con migliaia di ordini giornalieri. Testa sempre prima in staging.