我写了一个bash脚本,从cron开始,它每晚和每周备份一台特定机器上的所有数据库。该脚本正确地删除了旧数据库,但在月份发生更改的情况下除外。
举个例子,比方说是11月2日。脚本在晚上11:00运行,并正确地删除了从11月1日开始的备份。但是到了12月1日,脚本变得混乱了,没有正确地删除11月30日所做的备份。
在这种情况下,如何修复此脚本以正确删除旧备份?
DATABASES=$(echo 'show databases;' | mysql -u backup --password='(password)' | grep -v ^Database$)
LIST=$(echo $DATABASES | sed -e "s/\s/\n/g")
DATE=$(date +%Y%m%d)
DAYOLD=$(($DATE-1))
SUNDAY=$(date +%a)
WEEKOLD=$(($DATE-7))
for i in $LIST; do
if [[ $i != "mysql" ]]; then
mysqldump --single-transaction $i > /mnt/backups/mariadb/daily/$i.$DATE.sql
if [ -f /mnt/backups/mariadb/daily/$i.$DAYOLD.sql ]; then
rm -f /mnt/backups/mariadb/daily/$i.$DAYOLD.sql
fi
if [[ $SUNDAY == "Sun" ]]; then
cp /mnt/backups/mariadb/daily/$i.$DATE.sql /mnt/backups/mariadb/weekly/$i.$DATE.sql
rm -f /mnt/backups/mariadb/weekly/$i.$WEEKOLD.sql
fi
fi
done发布于 2016-05-11 11:07:00
我把事情搞得太复杂了。我只是搜索文件备份的时间,而不是使用日期,而是使用:
find /mnt/backups/mariadb/weekly/* -type f -mtime +8 -exec rm -f {} \;所以整个脚本变成:
DATABASES=$(echo 'show databases;' | mysql -u backup --password='foo' | grep -v ^Database$)
LIST=$(echo $DATABASES | sed -e "s/\s/\n/g")
DATE=$(date +%Y%m%d)
SUNDAY=$(date +%a)
for i in $LIST; do
if [[ $i != "mysql" ]]; then
/bin/nice mysqldump --single-transaction $i > /mnt/backups/mariadb/daily/$i.$DATE.sql
find /mnt/backups/mariadb/daily/* -type f -mtime +1 -exec rm -f {} \;
if [[ $SUNDAY == "Sun" ]]; then
cp /mnt/backups/mariadb/daily/$i.$DATE.sql /mnt/backups/mariadb/weekly/$i.$DATE.sql
find /mnt/backups/mariadb/weekly/* -type f -mtime +8 -exec rm -f {} \;
fi
fi
chown -R backup.backup /mnt/backups
done发布于 2015-02-21 13:39:06
如果您知道在特定时间范围内执行的备份数量,假设您知道从11月2日到12月2日,您知道已经做了30个备份,现在您想要删除这些备份,只需使用备份的数量,这样做非常简单,您不必处理在bash中非常复杂的日期:
$ (ls -t|head -n 30;ls)|grep -v ^Database|sort|uniq -u|xargs rm -rf然后,您可以轻松地通过每天删除旧脚本来自动执行此脚本,这样您就只能获得所需备份的固定数量:
#! /bin/bash
# Create new full backup
BACKUP_DIR="/path-to-backups/"
BACKUP_DAYS=1
# Prepare backup
cd ${BACKUP_DIR}
latest=`ls -rt | grep 201 | head -1`
# Change latest reference
ln -sf ${BACKUP_DIR}${latest} latest
# Cleanup older than one week (n days)
to_remove=`(ls -t | grep 201 | head -n 3;ls)|sort|uniq -u`
echo "Cleaning up... $to_remove"
(ls -t|head -n ${BACKUP_DAYS};ls)|sort|uniq -u|xargs rm -rf
echo "Backup Finished"
exit 0然后你就可以把它和每日的cron联系起来。这是在这篇博客文章中解释的,如何以一种非常简单的方式(但是使用热备份,没有mysqldump):http://codeispoetry.me/index.php/mariadb-daily-hot-backups-with-xtrabackup/
https://stackoverflow.com/questions/25852341
复制相似问题