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.

Steps to purge MySQL or MariaDB binary logs:

  1. Use an account that can inspect and purge binary logs. Run the examples with mysql or mariadb. Local administrative access on some hosts uses sudo mysql or sudo mariadb instead of -u root -p. MySQL 8.4 requires REPLICATION CLIENT for SHOW BINARY LOG STATUS and BINLOG_ADMIN for PURGE BINARY LOGS. MariaDB uses BINLOG MONITOR for binary-log inspection and BINLOG ADMIN for purging.
  2. Confirm binary logging is enabled and record the log basename and index path.
    $ 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.

  3. List the binary logs currently retained by the server.
    $ 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.

  4. Check the current writable binary log on the source.
    $ 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.

  5. Check every replica before purging logs from a replication source.
    $ 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.

  6. Rotate the binary log first when the current writable file also needs to become eligible for removal.
    $ 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.

  7. Purge every binary log older than the oldest file that must remain.
    $ 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.

  8. Verify that the binary-log list now starts at the expected boundary file.
    $ mysql --table -u root -p -e "SHOW BINARY LOGS;"
    Enter password:
    +---------------+-----------+-----------+
    | Log_name      | File_size | Encrypted |
    +---------------+-----------+-----------+
    | binlog.000004 |       202 | No        |
    | binlog.000005 |       158 | No        |
    +---------------+-----------+-----------+
  9. Review automatic retention so manual purges do not become the only cleanup path.
    $ 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.

  10. Set a live retention window when the current value is shorter or longer than the recovery policy.
    $ 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.

  11. Persist the retention setting in the server configuration.
    [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.

  12. Avoid full binary-log resets except on a fresh standalone source or disposable lab server.
    $ 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.