I log binari (binary log, o binlog) di MySQL registrano ogni operazione che modifica i dati. Servono per la replica e per il point-in-time recovery, ma se nessuno li ripulisce crescono all’infinito: su un server attivo da mesi è facile ritrovarsi con decine di GB occupati senza accorgersene.

1. Vedere quali log esistono

Collegati al database con un utente amministrativo e lancia:

SHOW BINARY LOGS;

L’output è un elenco dei file con la rispettiva dimensione in byte:

binlog.000090    1091364833    No
binlog.000091     122143900    No
binlog.000092    1087892780    No
binlog.000093    1091373360    No
binlog.000094     667851129    No
binlog.000095    1087954844    No
binlog.000096    1091582734    No
binlog.000097     311958852    No
binlog.000098    1074928434    No
binlog.000099    1074984551    No
binlog.000100    1076460123    No
binlog.000101    1076405091    No
binlog.000102    1090304282    No
binlog.000103     828034329    No
binlog.000104    1053782309    No
binlog.000105     412825926    No

Le colonne sono Log_name, File_size (in byte) ed Encrypted. In questo esempio i 16 file occupano complessivamente circa 13 GB: quasi tutti pesano intorno a 1 GB l’uno, che è il valore predefinito di max_binlog_size, la dimensione oltre la quale MySQL chiude il file e ne apre uno nuovo.

2. Cancellare tutti i log tranne l’ultimo

Individua l’ultimo file della lista — nell’esempio binlog.000105, quello attualmente in scrittura — e lancia:

PURGE BINARY LOGS TO 'binlog.000105';

Il comando elimina tutti i file precedenti a quello indicato, lasciando solo l’ultimo. Nel nostro caso libera circa 12,9 GB immediatamente.

Se preferisci ragionare per data anziché per nome file, puoi cancellare tutto ciò che è più vecchio di un certo momento:

PURGE BINARY LOGS BEFORE NOW();
PURGE BINARY LOGS BEFORE '2026-09-01 00:00:00';

3. Evitare che si riaccumulino

La pulizia manuale è inutile se fra un mese il problema si ripresenta. Imposta una scadenza automatica:

-- MySQL 8.0 e successivi (in secondi: 604800 = 7 giorni)
SET GLOBAL binlog_expire_logs_seconds = 604800;

-- MySQL 5.7 e precedenti (in giorni)
SET GLOBAL expire_logs_days = 7;

Per renderla permanente aggiungila a my.cnf (o my.ini su Windows), così sopravvive al riavvio del servizio:

[mysqld]
binlog_expire_logs_seconds = 604800

Tre avvertenze importanti

  1. Non cancellare i file a mano con rm o da Esplora risorse: l’indice binlog.index resterebbe disallineato e MySQL potrebbe andare in errore. Usa sempre PURGE.
  2. Se hai la replica attiva, verifica prima che le repliche abbiano già consumato quei log (SHOW REPLICA STATUS, o SHOW SLAVE STATUS sulle versioni più vecchie): cancellare un log non ancora letto rompe la replica.
  3. I binlog fanno parte della strategia di backup: una volta eliminati, il recupero si ferma all’ultimo backup completo disponibile.

Leggi anche: