I have a new requirement to purge MySQL dump files that are older than 30 days. The files use a naming convention of “all-mysql-YYYYMMDD-HHMM.dump”. The files are located on SAN mounted file system, so restoration is not an issue, but the drive space is limited unfortunately and fills up quickly so it requires frequent human intervention.
Example of files names
- all-mysql-20130324-2330.dump
- all-mysql-20130325-2330.dump
- all-mysql-20130326-2330.dump
My first thought was to use “find” inside a batch script with -mtime +30, however, the modification times cannot be guaranteed and some of the older archives could evade the purge date 🙂
I created the following BASH script, but I was hoping there was there was a cleaner way to perform this operation.
#!/bin/bash
STARTING_DIR=$(pwd)
FILE_PREFIX=all-mysql-
BACKUP_DIR=/opt/backup/mysql/dumps
ARCHIVE_WINDOW_DAYS=30
cd $BACKUP_DIR
# Create YYYYMMDD datestamp for Today - $ARCHIVE_WINDOW_DAYS
ARCHIVE_WINDOW_IN_SECS=$(echo "$(date +%s) - (${ARCHIVE_WINDOW_DAYS} * 86400)" | bc)
PURGE_BEFORE_DATE=$(date -d @${ARCHIVE_WINDOW_IN_SECS} +%Y%m%d)
for backup_file in $FILE_PREFIX*
do
# Trim prefix, time portion of date stamp, and file extension
# from $backup_file to allow numeric comparison against YYYYMMDD
backup_trim_tmp=${backup_file#${FILE_PREFIX}}
backup_trimmed=${backup_trim_tmp%-****.dump}
if [ ${PURGE_BEFORE_DATE} -gt ${backup_trimmed} ]
then
rm $backup_file
fi
done
cd $STARTING_DIR
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Another way to delete all except the last 30 files:
rm $(ls -r | tail -n +31)
Or here is a shorter version of the script in the original post:
cd /opt/backup/mysql/dumps
d=$(date -r $(($(date +%s)-30*86400)) +%Y%m%d)
for f in all-mysql-*; do
[[ ${f#all-mysql-} < $d ]] && rm $f
done
Method 2
If you want to delete all except for the last 30 files:
rm `echo " " all-mysql-*.dump | sed -r -e 's/( [^ ]+){0,30}$//'`
That would fulfill your requirement provided that there is one backup per day, and the naming scheme stays the way it is (i.e. alphabetical order = chronological order, no spaces in filenames).
You specifically requested a one-liner in one of your comments. Personally I like to write things out more. This one liner is a bit on the dangerous side (if the sed fails, everything is deleted).
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0