Percona Server for MySQL Highlights – binlog_space_limit

Percona Server for MySQLI think it is often confusing to compare upstream MySQL and Percona Server for MySQL, and some helpful information can be found in the introductory notes. But what does that really mean for an ordinary DBA, especially if none of the known big extra features are important in a particular use case?

In this article, I would like to start a series of short blog posts highlighting small, often less known, but potentially useful features, available in Percona Server for MySQL. Let’s start with a relatively new feature.

Limit the disk space used by binary logs problem

Historically, dealing with binary logs and the disk space used by them was quite challenging. The only thing that let you control this is the expire_logs_days variable, which can be useless in some scenarios (binlogs growing faster than can be purged) and does not solve all problems. Therefore, in order to avoid disk full and server crashes, it is often needed to create smart scripts that monitor the situation and call PURGE BINARY LOGS TO when necessary.

This isn’t very convenient and so a feature request appeared in September 2012 – to use the already existing logic for relay logs and apply it for binary logs as well. It has not been addressed in upstream yet.

We attempted to deal with it in Percona Server by introducing max_binlog_files variable (Percona Server 5.5.27, October 2012). This was a good step forward, but still not as good as expected. Even though limiting the number of binary log files gives much better control in terms of disk space used by them, it has one serious downside. It does not take into account situations when there may be binary logs lot smaller or a lot bigger then the max_binlog_size specifies.

Most common situations like that may be that the server rotates to a new binary log faster due to FLUSH LOGS issued, or due to restarts. A couple of such FLUSH commands in a row may completely ruin the ability to point in time recovery by losing a large part of the history of the binary log. An opposite case is when a binary log gets bigger than maximum size due to large transactions (which are never going to be split).

Recently, a new variable in MySQL 8.0 has replaced the expire_logs_days– the binlog_expire_logs_secondsand also a period of 30 days became the new default (previously it was unlimited).  It is certainly better to have more precise control on binary logs history then “days”, for example, we can set the rotation period to 2 days 6 hours and 30 minutes or whatever best matches the backup schedule. Again, a good time limit control on binary logs may not be sufficient in all cases and won’t help much when it is hard to predict how much data will be written or changed over time. Only space-based limits can actually save us from hitting the disk space problem.

Expected solution is there

Finally, something better has arrived, the binlog_space_limit variable, introduced in Percona Server 5.7.23 on September 2018 (ported to 8.0 as well). The idea is very simple: it does the same thing as relay_log_space_limit does for the relay logs. Finally, both sides of binary logging have comparable functionality when it comes to controlling the space on the disk.

How to use it

When the binlog_space_limit variable is set to 0 (default), the feature is turned off and no limit is set apart from the one imposed by expire_logs_days. I think it is a good idea is to dedicate a separate disk partition for the binary logs (or binary and redo logs), big enough to keep as many of them as needed for a good backup and replication strategy, and set the variable to around 95% of this partition size. Remember, that even though max_binlog_sizedefines the maximum size of a single binary log, this is not a hard limit. This is because a single transaction is never split between multiple binlog files and has to be written to the same binary log as a whole.

Let’s say the max_binlog_size is set to 1GB (default and maximum), and the binlog_space_limit is set to 10GB, but it happens that a really big transaction changes 3GB of data. What will happen with the binlog_space_limit set is that in order to store that new 3GB in the binary log (when the total size of logs is going to hit the limit), it will remove as many old binary logs as needed first, in this case, up to three oldest ones. This way there is no risk in hitting disk full situation even if the free disk space is smaller then the new binary log addition would need. But still, I would recommend reserving at least little more than 1GB of free disk space for such partition, just in case.

Example settings for a 16GB disk partition, dedicated for binary logs only, may look like this:

max_binlog_size = 512M
binlog_space_limit = 15G

One thing that could be still improved about this functionality is to make this variable dynamic. But to stay consistent with the one for relay logs, it would be best if the upstream makes this one dynamic first 🙂

Best binlog rotation strategy?

There may be still cases where I think you would rather prefer to stay with a time-based limit. Let’s imagine a situation where the full backups are made every week, and the binlog_space_limit is set to hold an average total size of two weeks of writes, so all should be safe. However, some heavy maintenance tasks alter a large portion of the data, creating more binary logs in one day then usually it takes two weeks. This may also break the point in time recovery capability. So if possible, maybe better to give an ample supply for the disk partition and specify 8 days rotation via expire_logs_days or binlog_expire_logs_secondsinstead.

Do you like it?

I am very interested to find out if this feature was already noticed by the community and how useful you think it is. Your comments are more than welcome!

Share this post

Comments (3)

  • M Reply

    Don’t underestimate how much space you can save with binlog-row-image=minimal, which stores only PK for lookup, and modified rows, where possible.

    This will help in cases where you have a lot of UPDATE or DELETE commands, but obviously workloads with mostly INSERT would not benefit.

    Note that this setting may not be compatible with external replication tools or cases where you want to use a “flashback” type utility.

    July 3, 2019 at 7:05 pm
  • Stofa Reply


    Is this parameter aware about what happens on slaves side?
    For instrance, let assume that one or more slaves are stopped for some reason and the DML in the master binary logs are not been read by the slaves for a while. Then, if the master purges the old binary files as requested by binlog_space_limit value, to sync the stopped slaves , one must take a full backup in order to rebuild the slaves.
    I know that could be a challenge on master side to discover if any of the slaves are stopped. Right ?



    October 30, 2019 at 6:48 am
  • John Nicholls Reply

    Hi Przemysław

    Great post, thanks.

    The documentation for both settings shows both as being non-dynamic?

    As we’re running in Google Cloud and use XFS on the persistent disks, when we want to expand our disk sizes, we just do this on the fly with a couple of commands and no downtime.

    If we were to set these two values on instance creation, when we came to expand our disks we would find that we were unable to make this additional capacity available to MySQL – binlog_space_limit and relay_log_space_limit would remain fixed with values that are no longer suitable.



    September 1, 2020 at 7:04 am

Leave a Reply