Binary logs can quietly consume a large share of the filesystem behind MySQL or MariaDB, especially on write-heavy servers or replicas that retain logs for recovery. Purging old files reclaims disk space without turning off binary logging, which keeps replication and point-in-time recovery available for the logs you still need.
The server writes binary log events into numbered files plus an index file that tracks the sequence. Manual cleanup must go through SQL so the server updates that index safely. The key boundary is the current writable log file, because PURGE BINARY LOGS TO 'file' keeps the named file and removes only older files.
Binary log removal is irreversible, so confirm every replica has already consumed the files you plan to remove and keep a retention window that still covers your backup and recovery policy. Current MySQL 8.4 uses SHOW BINARY LOG STATUS and RESET BINARY LOGS AND GTIDS, while current MariaDB still exposes SHOW BINLOG STATUS and RESET MASTER; many MariaDB installs also keep log_bin=OFF until binary logging is configured explicitly.
Steps to purge MySQL or MariaDB binary logs:
- Use an account that can read binary-log status and purge old files.
Run the examples with mysql or mariadb. Local administrative access on some hosts uses
sudo mysql
or
sudo mariadb
instead of -u root -p. Current MySQL 8.4 uses REPLICATION CLIENT for SHOW BINARY LOG STATUS and an administrative privilege such as BINLOG_ADMIN for PURGE BINARY LOGS.</WRAP> - Confirm binary logging is enabled before planning a purge. <code bash>$ mysql –table -u root -p -e “SHOW VARIABLES LIKE 'log_bin';” Enter password: +—————+——-+ | Variable_name | Value | +—————+——-+ | log_bin | ON | +—————+——-+</code>
If log_bin=OFF, there are no active binary logs to purge. Current MariaDB container defaults often start with binary logging disabled until log_bin is configured.
- Record the binary-log basename and index file path. <code bash>$ mysql –table -u root -p -e “SHOW VARIABLES WHERE Variable_name IN ('log_bin_basename','log_bin_index');” Enter password: +——————+—————————–+ | Variable_name | Value | +——————+—————————–+ | log_bin_basename | /var/lib/mysql/binlog | | log_bin_index | /var/lib/mysql/binlog.index | +——————+—————————–+</code>
Use the basename your server actually reports. Current MySQL 8.4 defaults to binlog when no basename is configured, while many existing MySQL or MariaDB installs still use mysql-bin or mariadb-bin.
- List the retained binary log files and note how much disk they already consume. <code bash>$ mysql –table -u root -p -e “SHOW BINARY LOGS;” Enter password: +—————+———–+———–+ | Log_name | File_size | Encrypted | +—————+———–+———–+ | binlog.000001 | 2997943 | No | | binlog.000002 | 909 | No | | binlog.000003 | 492 | No | | binlog.000004 | 450 | No | +—————+———–+———–+</code>
Current MariaDB returns the same file list without the Encrypted column, and current MariaDB documentation requires BINLOG MONITOR for SHOW BINARY LOGS.
- Capture the current writable binary log file and use it as the default purge boundary. <code bash>$ mysql -u root -p -e “SHOW BINARY LOG STATUS\\G” Enter password: * 1. row * File: binlog.000004 Position: 450 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set:</code>
Current MariaDB reports the same boundary with
SHOW BINLOG STATUS;
and also accepts
SHOW MASTER STATUS;
. Current MySQL 8.4 no longer supports
SHOW MASTER STATUS;
.
- Rotate to a new binary log file when the current writer should become purgeable. <code bash>$ mysql -u root -p -e “FLUSH BINARY LOGS;” Enter password:</code>
Run the status command again after the flush and use the new File value as the purge boundary if you need to remove the file that was active a moment ago.
- Check each replica before purging files the topology might still need. <code bash>$ mysql -u root -p -e “SHOW REPLICA STATUS\\G” Enter password:</code>
On current MySQL, compare the purge boundary against Relay_Source_Log_File. On current MariaDB, read the same checkpoint from Relay_Master_Log_File, and the thread state fields still appear as Slave_IO_Running and Slave_SQL_Running.
Related: How to monitor replication in MySQL or MariaDBDo not purge a binary log file that any replica still needs for catch-up.
- Purge every binary log older than the selected boundary file. <code bash>$ mysql -u root -p -e “PURGE BINARY LOGS TO 'binlog.000004';” Enter password:</code>
PURGE BINARY LOGS deletes the older files immediately. Removing a file that replication or point-in-time recovery still needs can break restores and stop replicas from catching up.
- Verify the binary-log list now starts at the expected file. <code bash>$ mysql –table -u root -p -e “SHOW BINARY LOGS;” Enter password: +—————+———–+———–+ | Log_name | File_size | Encrypted | +—————+———–+———–+ | binlog.000004 | 450 | No | +—————+———–+———–+</code> - Review the live automatic-retention settings before deciding whether manual purges should stay routine. <code bash>$ 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 | 2592000 | +——————————-+———+</code>
Current MySQL 8.4 defaults to automatic purge ON with a 30-day window. Current MariaDB 11.4 commonly reports binlog_expire_logs_seconds=864000 and expire_logs_days=10.000000 when binary logging is enabled.
- Set a new live retention window when the current default does not match your recovery policy. <code bash>$ mysql -u root -p -e “SET GLOBAL binlog_expire_logs_seconds = 604800;” Enter password:</code>
On current MariaDB, the same change also updates expire_logs_days to 7.000000 because the variables are aliases. Older MariaDB releases may still use expire_logs_days directly.
- Persist the retention window in the server configuration so it survives restarts. <file>[mysqld] binlog_expire_logs_seconds = 604800</file>
On MariaDB 10.6.1 and later, this setting also drives expire_logs_days automatically. Older MariaDB builds can require
expire_logs_days = 7
instead. Current MySQL also keeps automatic purge enabled with binlog_expire_logs_auto_purge=ON unless you turn it off explicitly.
- Reset the entire binary-log history only when building a fresh standalone source or disposable lab instance. <code bash>$ mysql -u root -p -e “RESET BINARY LOGS AND GTIDS;” Enter password:</code>
The equivalent full reset on current MariaDB is
RESET MASTER;
, which recreates the first file as mariadb-bin.000001.
Either reset destroys the current binary-log history and is unsafe on servers that still need replication continuity or point-in-time recovery coverage.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
