Binary logs can consume a large share of the filesystem behind MySQL or MariaDB after heavy writes, delayed replicas, or backup windows that keep old recovery points around longer than expected. Purging old binary logs reclaims disk space without disabling binary logging for the logs that still matter.
MySQL and MariaDB store binary-log history as numbered files plus an index file. Use SQL statements instead of deleting files with rm so the server removes the same entries from the index. PURGE BINARY LOGS TO 'binlog.000004' keeps the named file and any later files, then deletes only the earlier files.
Binary-log removal is irreversible. Choose the oldest log file that must remain by comparing the current source log, replica read positions, and the recovery window covered by backups. MySQL 8.4 LTS uses SHOW BINARY LOG STATUS, while MariaDB uses SHOW BINLOG STATUS; MariaDB's SHOW BINARY LOGS output also omits the Encrypted column that MySQL shows.
$ mysql --table -u root -p -e "SHOW VARIABLES WHERE Variable_name IN ('log_bin','log_bin_basename','log_bin_index');" Enter password: +------------------+-----------------------------+ | Variable_name | Value | +------------------+-----------------------------+ | log_bin | ON | | log_bin_basename | /var/lib/mysql/binlog | | log_bin_index | /var/lib/mysql/binlog.index | +------------------+-----------------------------+
If log_bin=OFF, there are no active binary logs to purge. Enable binary logging first when the server must support replication or point-in-time recovery.
$ mysql --table -u root -p -e "SHOW BINARY LOGS;" Enter password: +---------------+-----------+-----------+ | Log_name | File_size | Encrypted | +---------------+-----------+-----------+ | binlog.000001 | 2997943 | No | | binlog.000002 | 202 | No | | binlog.000003 | 202 | No | | binlog.000004 | 202 | No | | binlog.000005 | 158 | No | +---------------+-----------+-----------+
MariaDB returns the same log names and sizes without the Encrypted column.
$ mysql -u root -p -e "SHOW BINARY LOG STATUS\G" Enter password: *************************** 1. row *************************** File: binlog.000005 Position: 158 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set:
Use mariadb -u root -p -e "SHOW BINLOG STATUS;" on MariaDB. SHOW MASTER STATUS appears in older examples, but MySQL 8.4 removed that statement.
$ mysql -u root -p -e "SHOW REPLICA STATUS\G" Enter password:
On MySQL replicas, compare the purge boundary with Source_Log_File and Relay_Source_Log_File. On MariaDB replicas, compare it with Master_Log_File and Relay_Master_Log_File, and confirm Slave_IO_Running and Slave_SQL_Running before removing source logs.
Related: How to monitor replication in MySQL or MariaDB
Do not purge a binary log that a disconnected or lagging replica has not read yet.
$ mysql -u root -p -e "FLUSH BINARY LOGS;" Enter password:
Run the status command again after the flush and use the new File value as the purge boundary if the former current file should be deleted too.
$ mysql -u root -p -e "PURGE BINARY LOGS TO 'binlog.000004';" Enter password:
PURGE BINARY LOGS deletes matching files immediately. Removing files needed by replication or point-in-time recovery can break replica catch-up and leave backups without the logs needed for replay.
$ mysql --table -u root -p -e "SHOW BINARY LOGS;" Enter password: +---------------+-----------+-----------+ | Log_name | File_size | Encrypted | +---------------+-----------+-----------+ | binlog.000004 | 202 | No | | binlog.000005 | 158 | No | +---------------+-----------+-----------+
$ mysql --table -u root -p -e "SHOW VARIABLES WHERE Variable_name IN ('binlog_expire_logs_auto_purge','binlog_expire_logs_seconds','expire_logs_days');" Enter password: +-------------------------------+--------+ | Variable_name | Value | +-------------------------------+--------+ | binlog_expire_logs_auto_purge | ON | | binlog_expire_logs_seconds | 604800 | +-------------------------------+--------+
MySQL 8.4 LTS defaults automatic purge to ON and uses binlog_expire_logs_seconds. MariaDB 10.6 and later also supports binlog_expire_logs_seconds and reports expire_logs_days as the day-based value.
$ mysql -u root -p -e "SET GLOBAL binlog_expire_logs_seconds = 604800;" Enter password:
Set the value higher than the longest expected replica lag and the longest point-in-time recovery window. On MariaDB 10.6 and later, setting binlog_expire_logs_seconds also updates expire_logs_days.
[mysqld] binlog_expire_logs_seconds = 604800
Use the option-file directory used by the installed package, such as /etc/mysql/conf.d/, /etc/mysql/mysql.conf.d/, /etc/mysql/mariadb.conf.d/, or /etc/my.cnf.d/. Restart the service or container during a maintenance window after changing persistent startup configuration.
$ mysql -u root -p -e "RESET BINARY LOGS AND GTIDS;" Enter password:
RESET BINARY LOGS AND GTIDS deletes the full MySQL binary-log history and resets GTID execution history. The MariaDB equivalent is RESET MASTER;, which is intended for a new source state and not for routine cleanup on active replication servers.