You check disk usage on your VPS and /var/lib/mysql is somehow 40GB. Your actual databases add up to maybe 3GB. The rest? A long trail of files named mysql-bin.000001, mysql-bin.000002, and so on, some of them going back months. These are binary logs, and if nobody's been managing them, they will eventually fill your disk and take MySQL down with it.

Symptom

Usually it shows up one of these ways:

  • df -h shows the root or /var partition at 90%+ with no obvious culprit
  • MySQL/MariaDB refuses to start after a reboot, with ERROR 1114 (HY000): The table is full or disk-related errors in /var/log/mysqld.log
  • Backups start failing partway through because there's no room left to write the dump
  • WordPress or your app throws intermittent database write errors under load

Run this to confirm binlogs are the cause before you touch anything:

du -sh /var/lib/mysql/mysql-bin.* 2>/dev/null | tail -20
du -sh /var/lib/mysql/*.0* 2>/dev/null | sort -rh | head -20

If you see dozens of files at a few hundred MB to a few GB each, that's your answer.

Cause

Binary logs record every change made to your data — every INSERT, UPDATE, DELETE, schema change. MySQL keeps them for two reasons: point-in-time recovery (replaying changes since your last backup) and replication (a replica reads the primary's binlog to stay in sync).

The problem is that binary logging is on by default on most cPanel and self-managed MySQL/MariaDB installs, and by default there's often no automatic expiry configured — or the expiry window is set way longer than anyone needs. Every write to the database adds to the current binlog file. Busy WooCommerce stores, WordPress sites with heavy autosave/revision activity, or any app doing frequent writes will generate binlogs fast — a few hundred MB to a couple of GB per day isn't unusual on an active site.

Without a cleanup policy, they just accumulate until the disk fills.

Fix

First, check whether you're actually using replication anywhere. If you have a replica reading from this server (or this run itself is a replica), you cannot blindly delete files a replica still needs — check replica lag first.

-- On the primary, check which binlog file replicas still need
SHOW BINARY LOGS;
SHOW REPLICAS;
-- or on older MySQL/MariaDB:
SHOW SLAVE HOSTS;

If there's no replication in play (the common case on a standalone VPS), you can purge safely. Never delete the files directly with rm — MySQL tracks them in an internal index and will error out or corrupt state if the files and the index disagree. Always purge through MySQL itself:

-- Purge everything older than 3 days
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;

-- Or purge everything up to (but not including) a specific file
PURGE BINARY LOGS TO 'mysql-bin.000045';

Check how much space that freed:

df -h /var/lib/mysql

If you're on a cPanel server and prefer not to touch MySQL directly, WHM's MySQL/MariaDB Configuration or the phpMyAdmin SQL tab both let you run the same PURGE BINARY LOGS statement — the effect is identical either way.

Prevention

A one-time purge just buys you time. Set an actual expiry so this doesn't happen again. Add this to your MySQL/MariaDB config (/etc/my.cnf or /etc/my.cnf.d/server.cnf, depending on distro) under the [mysqld] section:

[mysqld]
binlog_expire_logs_seconds=604800
max_binlog_size=200M

binlog_expire_logs_seconds=604800 keeps 7 days of logs and auto-purges anything older on the next log rotation or server restart. Older MySQL/MariaDB versions use expire_logs_days=7 instead — check your version with mysql --version before picking which directive to use.

Restart the service to apply it:

systemctl restart mysqld
# or on some distros:
systemctl restart mariadb
DirectiveMySQL/MariaDB versionWhat it does
binlog_expire_logs_secondsMySQL 8.0+, MariaDB 10.6+Auto-purges binlogs older than N seconds
expire_logs_daysMySQL 5.x/5.7, older MariaDBAuto-purges binlogs older than N days
max_binlog_sizeAll versionsCaps individual log file size before rotating to a new one

If you don't actually need binary logging at all — no replication, no point-in-time recovery requirement, just relying on your regular JetBackup/cPanel backups — you can disable it entirely by removing or commenting out any log-bin or log_bin line in your config and restarting MySQL. That's a reasonable call for most single-server WordPress or small business sites. If you're not sure, keep logging on with a short expiry rather than turning it off outright — a few days of binlogs is cheap insurance and costs you almost nothing once expiry is set.

Last thing worth doing: add a quick disk-usage check to whatever monitoring you already have (Netdata, a cron script, even a simple df check emailed weekly) so a stuck expiry setting or a replica that silently disconnected doesn't quietly fill the disk again before anyone notices.

Frequently Asked Questions

Is it safe to just delete mysql-bin files with rm -f?

No. MySQL keeps an index file (mysql-bin.index) listing which binlog files exist. If you delete files manually without updating that index, MySQL can throw errors on the next restart or during replication setup. Always use PURGE BINARY LOGS instead.

Will purging binary logs break my WordPress site or database?

No. Binary logs are a record of changes for replication and recovery — they're not your actual data. Your tables, rows, and current data are completely unaffected by purging old binlogs.

What if I have a replica server reading from this one?

Check SHOW REPLICAS (or SHOW SLAVE HOSTS) and confirm which binlog file each replica has last read via SHOW REPLICA STATUS on the replica itself. Never purge past the file a replica still needs, or you'll break replication and have to re-sync from scratch.

How do I know if binary logging is even enabled on my server?

Run SHOW VARIABLES LIKE 'log_bin'; in MySQL. If it returns ON, logging is active and you should set an expiry. If it's OFF, binlogs aren't your disk problem — look elsewhere (backups, logs, uploads).

Does cPanel manage binlog expiry automatically?

Not by default. cPanel/WHM ships MySQL/MariaDB with its standard configuration, which usually doesn't set an expiry unless you or a previous admin configured one. It's worth checking on any cPanel VPS you've inherited or migrated.