151

I have MM Replication in mysql, and I want to squeeze some free space in the box be deleting unnecessary files, I came across these mysql-bin files inside /var/db/mysql/ There are hundreds of those files like mysql-bin.000123, mysql-bin.000223 etc. I have checked the mysql replication by doing show master status and show slave status they are using some mysql-bin files at certain positions, but I guess all the other bin files are leftovers which will not be used anymore. In this case is it safe to delete all those mysql-bin files except the ones that replication is currently pointing at ?

If it is safe to delete, then is there anything I could do to automatically delete those files once they are not in use ?

4 Answers 4

227

Please do not just delete them in the OS.

You need to let mysqld do that for you. Here is how mysqld manages it:

The file mysql-bin.[index] keeps a list of all binary logs mysqld has generated and auto-rotated. The mechanisms for cleaning out the binlogs in conjunction with mysql-bin.[index] are:

PURGE BINARY LOGS TO 'binlogname';
PURGE BINARY LOGS BEFORE 'datetimestamp';

These will clear all binary logs before the binlog or timestamp you just specified.

For example, if you run

PURGE BINARY LOGS TO 'mysql-bin.000223';

this will erase all binary logs before mysql-bin.000223.

If you run

PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 3 DAY) + INTERVAL 0 SECOND;

this will erase all binary logs before midnight 3 days ago.

If you want to have binlog rotated away automatically and keep 3 days woth, simply set this:

mysql> SET GLOBAL expire_logs_days = 3;

then add this to /etc/my.cnf

[mysqld]
expire_logs_days=3

and mysqld will delete them logs for you

SHOW SLAVE STATUS\G

This is critical. When you run SHOW SLAVE STATUS\G, you will see two binary logs from the Master:

  • Master_Log_File
  • Relay_Master_Log_File

When replication has little or no lag these are usually the same value. When there is a lot of replication lag, these values are different. Just to make it simple, choose whatever Relay_Master_Log_File is, and go back to the Master and run

PURGE BINARY LOGS TO 'Whatever Relay_Master_Log_File Is';

That way, replication is not interrupted.

4
  • 2
    Please note that my post is over 8 years old. I try not amend my very old answers (which are 10 years old) and address older versions of MySQL. The majority of MySQL installation out there still use 5.5/5.6 even though they are EOL. So my older answers help such users. Commented May 20, 2021 at 20:08
  • 1
    As answer's author does not wish to update the answer to mention the new MySQL features, I advise to read this answer too.
    – T.Todua
    Commented May 23, 2021 at 12:13
  • 8
    Use System Variable binlog_expire_logs_seconds instead of deprecated system variable expire_logs_days. See: dev.mysql.com/doc/refman/8.0/en/… Commented May 24, 2021 at 19:50
  • SET GLOBAL binlog_expire_logs_seconds = 3*24*3600;
    – SuB
    Commented May 3 at 7:53
24

This really depends on your backup strategy. One of the main reasons to keep the binary logs around is to restore your database to a 'point-in-time'. If your database crashes and requires restoration, you would restore the latest full backup, and then play back the binary logs starting with the position of the full backup.

So, if you do a full backup every day and you have 7 days worth of binary logs, it is likely that you can delete the past 4-6 days worth of binary logs. You can control how many days worth of binary logs are kept with the expire_logs_days setting.

You can delete the binary logs you don't need by first seeing what is the oldest log you want to keep:

ls -lh /path/to/binary/logs/mysql-bin.0*

and then in mysql:

mysql> PURGE BINARY LOGS TO 'mysql-bin.XXXXX';
1
  • NOTE: expire_logs_days is deprecated and binlog_expire_logs_seconds should be used instead. Commented Dec 9, 2022 at 18:26
13

Try this:

RESET MASTER;

as the document said:

RESET MASTER enables you to delete any binary log files and their related binary log index file, returning the master to its state before binary logging was started.

This will delete all the related binary log files, which may not what you want.

0
12

Yes, it is safe. For mysql 8, here's how you can do it.

We can set binlog_expire_logs_seconds as a option or as a system variable or as a command line parameter too, but I will show how to use it as configuration option.

Using as a options, you have to edit configurations files. You can look for windows and linux files here. For linux, I went to /etc/mysql/my.cnf file:

$ cat /etc/mysql/my.cnf
...
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

Let's see what's inside /etc/mysql/mysql.conf.d/:

$ ls /etc/mysql/mysql.conf.d/
mysql.cnf  mysqld.cnf

For example, to keep only 3 days of logs, you have to calculate total of seconds (246060*3). Now, all we have to add binlog_expire_logs_seconds option to a mysqld section. My solution was to create a file with this content:

$ cat /etc/mysql/mysql.conf.d/binlog_expiration.cnf 
[mysqld]

# Three days: 24*60*60*3
binlog_expire_logs_seconds=259200

Since the file was inside a directory included by /etc/mysql/my.cnf it will be loaded with the service.

And then, restart the service:

sudo service mysql restart

It will erase the log for you and will keep deleting them.

NOTE: For reference, expire_logs_days was deprecated.

1
  • Yes that helped me minimize with ec2 EBS volumn size, but in my case this was the config file sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf Commented Jan 25, 2023 at 13:58