Troubleshooting Guide: Why Logrotate Fails to Rotate MySQL Slow Logs on Ubuntu


1 views

When logrotate fails to automatically rotate MySQL slow logs despite proper configuration, we need to systematically examine several aspects. Here's the configuration in question:

/var/log/mysql/mysql-slow.log {
    daily
    rotate 3
    compress
    notifempty
    missingok
    create 660 mysql adm
    postrotate 
    if test -x /usr/bin/mysqladmin && \
       /usr/bin/mysqladmin ping &>/dev/null
    then
       /usr/bin/mysqladmin flush-logs
    fi
    endscript
}

First, let's verify the basic requirements:

# Check log file existence
ls -la /var/log/mysql/mysql-slow.log

# Test mysqladmin command manually
/usr/bin/mysqladmin ping

# Verify file permissions
stat /var/log/mysql/mysql-slow.log

The most critical place to check is the logrotate execution log. On Ubuntu systems, this is typically located at:

/var/log/syslog
/var/log/cron.log

Search for logrotate entries with:

grep logrotate /var/log/syslog
grep CRON /var/log/syslog | grep -i logrotate

When testing manually, always use verbose flags:

logrotate -vf /etc/logrotate.d/mysql-slow

The -v flag provides verbose output, while -f forces rotation regardless of schedule.

Here are some common issues and their solutions:

# 1. Permission issues
chown mysql:adm /var/log/mysql/mysql-slow.log
chmod 660 /var/log/mysql/mysql-slow.log

# 2. Missing cron job
cat /etc/cron.daily/logrotate

# 3. Test postrotate script independently
if test -x /usr/bin/mysqladmin && \
   /usr/bin/mysqladmin ping &>/dev/null
then
   /usr/bin/mysqladmin flush-logs
fi

For more robust logging, consider this enhanced configuration:

/var/log/mysql/mysql-slow.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 660 mysql adm
    sharedscripts
    postrotate
        # More robust version with error logging
        if [ -x /usr/bin/mysqladmin ]; then
            if /usr/bin/mysqladmin ping > /dev/null 2>&1; then
                /usr/bin/mysqladmin flush-logs >> /var/log/mysql/logrotate.log 2>&1
            else
                echo "$(date): MySQL not running" >> /var/log/mysql/logrotate.log
            fi
        else
            echo "$(date): mysqladmin not found" >> /var/log/mysql/logrotate.log
        fi
    endscript
}

To better track rotation attempts, add this to your rsyslog configuration:

# /etc/rsyslog.d/10-logrotate.conf
if $programname == 'logrotate' then /var/log/logrotate.log
& stop

This will capture all logrotate activity in a dedicated file.


When logrotate fails to rotate MySQL slow query logs despite correct configuration, we need to examine several technical aspects. Your configuration appears valid, but let's systematically verify each component.

# Confirmed log file exists
ls -la /var/log/mysql/mysql-slow.log

# Verified mysqladmin works
/usr/bin/mysqladmin ping
/usr/bin/mysqladmin flush-logs

# Checked file permissions
stat /var/log/mysql/mysql-slow.log

Your manual test with logrotate -d -f worked, which indicates the configuration is syntactically correct. The main suspects become:

1. Logrotate Execution Timing

# Check when logrotate runs
cat /etc/cron.daily/logrotate

# Verify last execution time
grep logrotate /var/log/syslog | tail -n 5

2. Permission Issues During Cron Execution

The cron job might run with different permissions than your manual test:

# Create test script
echo '#!/bin/bash
whoami
/usr/sbin/logrotate -v /etc/logrotate.conf' > /tmp/logrotate_test.sh
chmod +x /tmp/logrotate_test.sh

# Run as cron would
sudo -u nobody /tmp/logrotate_test.sh

Here's a more robust version of your configuration with additional debugging:

/var/log/mysql/mysql-slow.log {
    daily
    rotate 3
    compress
    delaycompress
    notifempty
    missingok
    create 660 mysql adm
    sharedscripts
    postrotate
        logger -t logrotate "Rotating MySQL slow log"
        if [ -x /usr/bin/mysqladmin ]; then
            /usr/bin/mysqladmin ping &>/dev/null && \
            /usr/bin/mysqladmin flush-logs || \
            logger -t logrotate "MySQL flush-logs failed"
        fi
    endscript
}

To capture what happens during automatic rotation:

# Method 1: Force run with debug
sudo /usr/sbin/logrotate -vf /etc/logrotate.d/mysql-slow

# Method 2: Add verbose logging
*/5 * * * * root /usr/sbin/logrotate -v /etc/logrotate.d/mysql-slow >> /var/log/logrotate.debug 2>&1
  • selinux Context: ls -Z /var/log/mysql/
  • Inode Changes: Some applications require special handling
  • Disk Space: Check with df -h /var/log

After implementing changes, monitor for rotation:

watch -n 60 'ls -l /var/log/mysql/mysql-slow.log*'