Vai al contenuto
Posta Pannello Scegli un piano

Backup del sito web: regola 3-2-1, strumenti e test di ripristino

Backup del sito web: regola 3-2-1, strumenti e test di ripristino

Un backup completo di un sito è un dump del database più un archivio dei file, cartella uploads compresa, eseguiti in modo coerente, conservati in almeno due posti di cui uno fuori dal server web e verificati con un ripristino di prova. Sul nostro banco di prova la maggior parte degli errori classici ha prodotto un backup creato senza un solo avviso: il problema è emerso solo al momento del ripristino. Di seguito: la regola 3-2-1 spiegata in modo semplice, una tabella «cosa salvare, con cosa, ogni quanto, come verificare», le misure di mysqldump, della compressione e di restic, e un test di ripristino passo dopo passo.

Come abbiamo testato

Il 10 novembre 2026 su un banco di prova: container Ubuntu 24.04.5 (2 vCPU, 8 GB di RAM), nginx 1.24.0, PHP-FPM 8.3.6, due istanze separate di MariaDB 10.11.14, WordPress 6.4.3 con 6.001 articoli, 450 foto (330 MB) e una tabella di log con 1,5 milioni di righe; il dump del database era di 404 MB. Abbiamo eseguito dump mentre venivano scritti «ordini» senza sosta, confrontato gzip, zstd e xz, fatto backup con restic 0.16.4 su una directory separata che faceva da storage remoto, simulato la perdita del disco e ripristinato il sito in un’istanza MariaDB vuota. È il comportamento del server di prova, non dati dei server RichHost.

La regola 3-2-1 per un sito su hosting condiviso

La regola 3-2-1 significa tre copie dei dati, su due supporti o sistemi diversi, con una copia in un altro luogo. Per un sito su hosting condiviso funziona così. Copia uno: il sito online stesso. Copia due: il backup che fa il tuo provider e che conserva fuori dal server web. Copia tre: il tuo backup presso un altro fornitore, su uno storage cloud o sul tuo computer. Conta non il numero di copie ma la loro indipendenza: se tutte e tre stanno sullo stesso disco o sono raggiungibili dallo stesso account, hai una sola copia, ripetuta tre volte.

Altre due condizioni fanno funzionare la regola. Conserva backup di diversi giorni o settimane, non solo l’ultimo, perché un attacco o un sito danneggiato si possono notare tardi. E verifica ogni configurazione con almeno un ripristino, altrimenti non sai se hai davvero un backup.

Cosa salvare, con cosa, ogni quanto, come verificare

Cosa Strumento Frequenza Come verificare
Database (articoli, ordini, utenti, impostazioni) mariadb-dump o mysqldump con --single-transaction, poi zstd Ogni giorno; più volte al giorno per un negozio online Ultima riga «Dump completed», zstd -t, importazione di prova e conteggio delle righe
Uploads: foto, PDF, file dei clienti tar + zstd -3 o restic Ogni giorno o dopo ogni caricamento consistente Numero di file nel backup, alcune immagini a caso si aprono dopo il ripristino
Codice: core, temi, plugin tar + zstd, git per il tuo tema Prima di ogni aggiornamento Il sito ripristinato risponde 200, l’accesso all’amministrazione funziona
Configurazione: wp-config.php, .htaccess, cron job Insieme ai file; cron job elencati in un file di testo Dopo ogni modifica I file sono nell’archivio, i job corrispondono a quelli attuali
Posta, record DNS Zona DNS esportata in un file di testo, posta tramite il client di posta o il pannello Ogni mese e dopo ogni modifica Confrontare la zona con quella attiva usando dig

Le tabelle di log, statistiche e cache dei plugin spesso pesano più di tutti i contenuti. Sul banco la tabella di log occupava circa 350 MB dei 404 MB del dump. Ripulirla rende i backup più piccoli e veloci; vedi la nostra guida per ottimizzare il database.

Database: perché --single-transaction è importante

Uno script creava «ordini» di continuo: una riga in wp_posts e quattro righe in wp_postmeta in una sola transazione, circa 45 ordini al secondo. Due secondi dopo partiva un dump in una di tre modalità.

Modalità di dump Ordini senza dati nel backup Attesa di scrittura più lunga
Senza lock (--skip-lock-tables), 3 esecuzioni 3, 7 e 5 0,17 s
Predefinita (--lock-tables) 0 3,84 s: tutte le scritture hanno atteso il dump
--single-transaction --quick, 3 esecuzioni 0, 0 e 0 0,18 s

Senza lock il dump legge le tabelle una alla volta: wp_postmeta prima di wp_posts. Gli ordini salvati tra queste due letture sono finiti nel backup senza totale, email e metodo di pagamento. Un dump del genere si importa senza errori e te ne accorgi solo quando un cliente chiede del suo ordine. La modalità predefinita mantiene il backup coerente, ma blocca le scritture per tutta la durata del dump: su un database più grande significa minuti in cui il negozio non può ricevere ordini. --single-transaction crea uno snapshot InnoDB coerente senza lock. Non aiuta con le tabelle MyISAM, quindi converti quelle vecchie in InnoDB.

mariadb-dump --single-transaction --quick --default-character-set=utf8mb4 wp > db.sql
tail -1 db.sql
-- Dump completed on 2026-11-10 14:51:46

Senza carico le due modalità hanno impiegato lo stesso tempo: 3,2-3,9 secondi per 404 MB. La differenza appare solo mentre il database riceve scritture, cioè, per un negozio, in orario di attività.

File: quale compressore usare

Ogni compressore ha lavorato su un solo thread con gli stessi dati.

Compressore File del sito, 388 MB Dump del database, 404 MB
gzip -6 16,6 s, 341,7 MB (88%) 9,2 s, 85,9 MB (21%)
zstd -3 1,5 s, 343,4 MB (88%) 1,9 s, 79,8 MB (20%)
zstd -19 149,4 s, 333,8 MB (86%) 350,1 s, 64,8 MB (16%)
xz -6 207,2 s, 335,0 MB (86%) 289,3 s, 64,3 MB (16%)

Le foto JPEG sono già compresse, quindi l’archivio dei file si riduce appena, qualunque strumento si usi. Il dump invece si riduce di cinque volte. zstd -3 ha offerto il miglior compromesso: da 5 a 11 volte più veloce di gzip con un file leggermente più piccolo. I livelli massimi di zstd e xz hanno risparmiato circa 15 MB in più sul dump al costo di cinque minuti di CPU, un carico sprecato su un hosting condiviso.

Backup incrementali: cosa offre la deduplicazione di restic

restic e borg dividono i dati in blocchi e salvano solo quelli nuovi. Il primo backup del sito con il dump era di 791 MB (427 MB nel repository, perché restic comprime). Poi:

  • Un nuovo articolo, una foto da 454 KB e 20 ordini: il secondo backup ha aggiunto 4,6 MB.
  • Eliminate le 1.000 righe più vecchie della tabella di log, come fanno i plugin di pulizia: il terzo backup ha aggiunto 359,6 MB, quasi tutto il dump.
  • Stessa modifica, ma con un dump a una riga per INSERT (--skip-extended-insert): 7,6 MB aggiunti.
Grafico del banco di prova: il primo backup restic ha aggiunto 791 MB, il successivo dopo un nuovo articolo 4,6 MB, dopo la pulizia dei log 359,6 MB e con un dump a una riga per INSERT 7,6 MB
Quanti dati ha aggiunto ogni nuovo backup restic sul banco di prova

Un dump normale mette centinaia di righe in ogni istruzione INSERT. Eliminare righe all’inizio di una tabella sposta i confini di tutte le istruzioni successive, e restic vede il resto del file come nuovo. Un dump a una riga per INSERT si deduplica bene, ma ha un prezzo: sul banco l’importazione ha richiesto 507 secondi invece di 35. Se paghi lo storage a volume e ripristini di rado, ne vale la pena; se conta la velocità di ripristino, tieni il dump normale e conserva meno versioni. Non abbiamo misurato borg: non si avviava nel container di prova per una versione di Python incompatibile, quindi i numeri riguardano solo restic.

export RESTIC_REPOSITORY=sftp:backup@storage.example.net:/restic
export RESTIC_PASSWORD_FILE=~/.restic-pass
restic init
restic backup ~/backup/db.sql ~/web/example.com/public_html
restic forget --keep-daily 14 --keep-weekly 8 --prune
restic check

Sostituisci l’indirizzo del repository con il tuo. Tieni la password del repository lontano dal server: senza di essa nessuno può decifrare il backup, nemmeno tu.

Ripristino di prova: come verificare che un backup funzioni

Abbiamo riprodotto il caso peggiore: fermato il database, cancellato l’intera directory del «server» compresi i backup locali e ripristinato il sito da restic in una nuova istanza MariaDB con la cartella del sito vuota.

restic restore latest --target /srv/restore
Summary: Restored 3523 files/dirs (789.971 MiB) in 0:02
mariadb -e "CREATE DATABASE wp"
mariadb wp < db.sql
curl -s -o /dev/null -w "%{http_code}\n" http://bench.test:8122/
200
curl -sI "http://bench.test:8122/wp-json/wp/v2/posts?per_page=1" | grep -i x-wp-total
X-WP-Total: 6002

Dall’avvio alla risposta 200 sono passati 23 secondi: 4 per i file, 19 per l’importazione del database. Il numero di articoli e ordini e l’ID più alto coincidevano con il sito online, la nuova foto è tornata con lo stesso checksum e i titoli in alfabeti non latini erano intatti. Il nostro primo tentativo, tra l’altro, è fallito per un errore nostro: restic ha salvato i percorsi esattamente come glieli avevamo passati e i file sono finiti in una cartella diversa da quella che lo script si aspettava. È proprio il tipo di dettaglio che un ripristino di prova fa emergere.

Un controllo mensile minimo:

  1. Verificare l’integrità dell’archivio: zstd -t, gzip -t o restic check.
  2. Controllare che il dump termini con «Dump completed».
  3. Importare il dump in un database di prova separato e confrontare il numero di articoli, ordini e utenti con il sito online.
  4. Pubblicare i file su un sottodominio di prova e controllare la risposta 200, l’accesso all’amministrazione e qualche immagine vecchia.
  5. Annotare quanto tempo è servito: è il tuo tempo reale di ripristino.

In sostanza è la stessa procedura che serve per migrare WordPress su un altro hosting, solo senza cambiare il dominio.

Quattro guasti che abbiamo riprodotto sul banco

Backup senza la cartella uploads

Un archivio creato con --exclude=wp-content/uploads pesava 15 MB invece di 361 MB. Dopo il ripristino la home page rispondeva 200 e la REST API elencava tutti i 6.002 articoli, ma ogni foto restituiva 404: 450 allegati nel database, 0 file sul disco. Il sito sembra vivo finché non apri un articolo qualsiasi. Spesso gli uploads vengono esclusi per rientrare in un limite di spazio, quindi controlla il numero di file nel tuo backup.

Backup solo sullo stesso server

Quando è sparita la directory del «server», con il sito se ne sono andati anche il dump, l’archivio dei file e i checksum accanto: No such file or directory. Solo la copia nello storage separato ha salvato il sito. Inoltre, non tenere mai gli archivi nella web root del sito, dove chiunque può scaricarli tramite URL. Per una directory di backup bastano permessi 700 sulla cartella e 600 sui file.

File troncato

Un backup interrotto al 60% (disco pieno o trasferimento interrotto) non supera zstd -t con «Read error (39) : premature end»; gzip segnala «unexpected end of file». Un dump non compresso è peggio: l’importazione si è fermata con ERROR 1064, ma a quel punto aveva già creato 7 tabelle su 13 e 3.825 righe su 9.304 in wp_posts. Mancavano le tabelle degli utenti e delle categorie, quindi nessuno poteva accedere. Un dump troncato si riconosce facilmente: alla fine manca la riga «Dump completed».

Set di caratteri o collation sbagliati

Un dump eseguito con --default-character-set=latin1 è terminato senza errori, ma in 5.986 titoli su 6.001 il testo cirillico si è trasformato in punti interrogativi. Questa perdita è definitiva: i byte giusti semplicemente non sono nel file. Un’altra variante: un dump senza la riga SET NAMES importato da un client che lavora in latin1 (come il client mariadb sul banco in una sessione senza locale UTF-8). I titoli sono usciti come caratteri illeggibili del tipo «Ð”оÑтавка», mentre lo stesso file si importava correttamente con --default-character-set=utf8mb4. Il terzo caso l’abbiamo emulato sostituendo nel dump la collation con quella che MySQL 8 crea di default: MariaDB 10.11 ha risposto ERROR 1273 (HY000): Unknown collation: 'utf8mb4_0900_ai_ci' e non ha creato alcuna tabella. La soluzione è sostituire la collation con una supportata, per esempio utf8mb4_unicode_520_ci, e ripetere l’importazione.

Se questa è la tua situazione, fai così

Se Fai così
Blog o sito vetrina, modifiche settimanali Backup del provider più un tuo backup settimanale di database e file altrove, un ripristino di prova ogni trimestre
Negozio o sito che riceve ordini Dump con --single-transaction più volte al giorno, file ogni giorno, un ripristino di prova ogni mese
I backup non rientrano nel limite di spazio restic o borg con deduplicazione e pulizia delle tabelle di log, senza escludere gli uploads
Passaggio da MySQL 8 a MariaDB Provare l’importazione prima di spostare il dominio; con ERROR 1273 sostituire la collation nel dump
Il sito è già stato violato o è offline Prima trovare la causa e salvare lo stato attuale, poi ripristinare un backup precedente all’incidente
Non sai quando è stato fatto l’ultimo backup Impostare un avviso per i backup mancanti e fare oggi stesso un ripristino di prova

Se il sito è già offline, inizia a cercare la causa nei log del server: spesso è un plugin o un disco pieno, e tornare al backup di ieri cancellerebbe solo i nuovi ordini. Pianifica lo script di backup con i cron job sul tuo hosting, aggiungi un controllo di «Dump completed» e zstd -t, e lascia che il monitoraggio del server ti avvisi quando qualcosa va storto.

I backup su RichHost

Tutti i piani di hosting RichHost includono backup continui nel cloud: una copia conservata fuori dal server web. Seguendo la regola 3-2-1, aggiungi un tuo backup altrove e verificalo ogni tanto con un ripristino su un sottodominio di prova. Il supporto risponde alle domande sui backup dalle 10:00 alle 20:00, ora di Kyiv, di solito entro circa 30 minuti.

Domande frequenti

Bastano i backup del mio provider di hosting?

Per la maggior parte degli incidenti sì, ma la regola 3-2-1 chiede un’altra copia indipendente. Ti salva quando il problema riguarda il tuo account o la fatturazione, oppure quando ti serve una versione più vecchia di quelle che il provider conserva.

Ogni quanto devo fare il backup del sito?

Con la frequenza dettata dalla quantità di dati che puoi permetterti di perdere. Per un blog bastano backup giornalieri o settimanali, un negozio online ha bisogno di più dump del database al giorno. I file cambiano meno spesso del database e si possono salvare con minore frequenza.

Posso fare il dump del database mentre il sito è online?

Sì, con --single-transaction per le tabelle InnoDB. Sul banco un dump di questo tipo non ha perso ordini e non ha bloccato le scritture, mentre un dump senza lock ha perso i dati di 3-7 ordini a ogni esecuzione.

Come provo un backup senza rompere il sito online?

Ripristinalo in un database separato e su un sottodominio di prova, mai sopra il sito online. Confronta il numero di articoli e ordini, apri alcune pagine e immagini ed esegui l’accesso all’amministrazione.

Altro su questo argomento

Tutti gli articoli
Limiti dell’hosting condiviso: cosa scatta prima e come verificarlo
Hosting condiviso28.03.2026

Limiti dell’hosting condiviso: cosa scatta prima e come verificarlo

Cosa limita davvero un hosting condiviso «illimitato»: inode, processi PHP simultanei, CPU, memoria, connessioni al database ed email. I limiti pubblicati da…

Sito non raggiungibile: cosa fare nei primi 10 minuti
Risoluzione dei problemi di hosting27.03.2026

Sito non raggiungibile: cosa fare nei primi 10 minuti

Sito non raggiungibile, cosa fare? Abbiamo messo fuori uso un WordPress di prova in dieci modi e costruito una tabella con sintomi,…

La connessione non è privata: come risolvere gli errori NET::ERR_CERT
Risoluzione dei problemi di hosting05.04.2026

La connessione non è privata: come risolvere gli errori NET::ERR_CERT

Perché il browser mostra «La connessione non è privata» e cosa significano NET::ERR_CERT_DATE_INVALID, COMMON_NAME_INVALID e AUTHORITY_INVALID: verificato su un banco di prova,…