Вопрос или проблема
каждый из наших файлов резервной копии базы данных создается. Файлы именуются следующим образом:
prod20210528_1200.sql.gz
шаблон: prod`date +\%Y%m%d_%H%M`
Шаблон можно настроить при необходимости.
Я хотел бы, чтобы у меня был скрипт, который:
- хранит все резервные копии за последние x (например, 3) дня
- для резервных копий старше x (например, 3) дня следует сохранять только резервную копию с временем 00:00
- для резервных копий старше y (например, 14) дней следует сохранять только один файл в неделю (понедельник)
- для резервных копий старше z дней (например, 90) следует сохранять только один файл в месяц (1-е число каждого месяца)
- скрипт должен использовать имя файла вместо информации о дате (создании) файла, если это возможно
- скрипт должен запускаться каждый день
К сожалению, у меня очень мало знаний о языке сценариев shell/bash.
Я бы сделал что-то вроде этого:
if (file < today - x AND date > today - (x + 1))
{
if (%H_of_file != 00 AND %M_of_file != 00)
{
delete file
}
}
if (file < today - y AND date > today - (y + 1))
{
if (file != Monday)
{
delete file
}
}
if (file < today - z AND date > today - (z + 1))
{
if (%m_of_file != 01)
{
delete file
}
}
Это имеет для вас какой-либо смысл?
Большое спасибо!
Всего наилучшего,
Фантом
Это работает для меня (BSD date, не GNU date)
#!/usr/local/bin/bash
DIR_BACKUPS='/backups'
KEEP_DAILY=3
KEEP_WEEKLY=14
KEEP_MONTHLY=90
date_keep_daily=$(date -j -v-${KEEP_DAILY}d +"%Y%m%d")
date_keep_weekly=$(date -j -v-${KEEP_WEEKLY}d +"%Y%m%d")
date_keep_monthly=$(date -j -v-${KEEP_MONTHLY}d +"%Y%m%d")
for file in $DIR_BACKUPS/prod*.sql.gz; do
timestamp=${file#*onwalt}
timestamp=${timestamp%%.*}
date_of_file=${timestamp%%_*}
hour_of_file=${timestamp:(-4):2}
if [[ $date_of_file < $date_keep_monthly ]]; then
if [[ $(date -jf "%Y%m%d_%H%M" $timestamp +"%d") != 01 ]]; then
rm $file
fi
elif [[ $date_of_file < $date_keep_weekly ]]; then
if [[ $(date -jf "%Y%m%d_%H%M" $timestamp +"%u") != 1 ]]; then
rm $file
fi
elif [[ $date_of_file < $date_keep_daily ]]; then
if [[ $(date -jf "%Y%m%d_%H%M" $timestamp +"%H") != 00 ]]; then
rm $file
fi
fi
done
Как коммиттер pyExpireBackups, я могу указать вам реализацию ExpirationRule моего решения (исходный код ниже и в репозитории github). Он использует mtime
modified = datetime.datetime.fromtimestamp(stats.st_mtime, tz=datetime.timezone.utc)
для оценки “возраста” файла.
См. https://wiki.bitplan.com/index.php/PyExpireBackups для документации.
Скрипт установки:
pip install PyExpireBackups
установит команду shell “expireBackups”.
Использование:
expireBackups -h
использование: expireBackups [-h] [-d] [--days DAYS] [--weeks WEEKS] [--months MONTHS] [--years YEARS]
[--minFileSize MINFILESIZE] [--rootPath ROOTPATH] [--baseName BASENAME] [--ext EXT]
[--createTestFiles CREATETESTFILES] [-f] [-V]
Истечение сроков резервного копирования на основе правил (ежегодно, ежемесячно, еженедельно, ежедневно ...)
Создано Вольфгангом Фалем 2022-04-01.
Авторское право 2008-2022 Вольфганг Фаль. Все права защищены.
Лицензировано по лицензии Apache 2.0
http://www.apache.org/licenses/LICENSE-2.0
Распространяется на условиях "КАК ЕСТЬ" без каких-либо гарантий
или условий любого рода, как явных, так и подразумеваемых.
ИСПОЛЬЗОВАНИЕ
дополнительные аргументы:
-h, --help показать это сообщение и выйти
-d, --debug показать информацию для отладки
--days DAYS количество последовательных дней, для которых нужно сохранить ежедневную резервную копию (по умолчанию: 7)
--weeks WEEKS количество последовательных недель, для которых нужно сохранить еженедельную резервную копию (по умолчанию: 6)
--months MONTHS количество последовательных месяцев, для которых нужно сохранить ежемесячную резервную копию (по умолчанию: 8)
--years YEARS количество последовательных лет, для которых нужно сохранить ежегодную резервную копию (по умолчанию: 4)
--minFileSize MINFILESIZE
минимальный размер файла в байтах для фильтрации (по умолчанию: 1)
--rootPath ROOTPATH
--baseName BASENAME основное имя для фильтрации (по умолчанию: None)
--ext EXT расширение для фильтрации (по умолчанию: None)
--createTestFiles CREATETESTFILES
создать заданное количество временных тестовых файлов (по умолчанию: None)
-f, --force
-V, --version показать номер версии программы и выйти
Пример выполнения приведет к:
expireBackups --ext .tgz
хранят 7 файлов для ежедневного резервного копирования
хранят 6 файлов для еженедельного резервного копирования
хранят 8 файлов для ежемесячного резервного копирования
хранят 4 файла для ежегодного резервного копирования
истечение 269 файлов, сухой запуск
# 1✅: 0.0 days( 5 GB/ 5 GB)→./sql_backup.2022-04-02.tgz
# 2✅: 3.0 days( 5 GB/ 9 GB)→./sql_backup.2022-03-30.tgz
# 3✅: 4.0 days( 5 GB/ 14 GB)→./sql_backup.2022-03-29.tgz
# 4✅: 5.0 days( 5 GB/ 18 GB)→./sql_backup.2022-03-28.tgz
# 5✅: 7.0 days( 5 GB/ 23 GB)→./sql_backup.2022-03-26.tgz
# 6✅: 9.0 days( 5 GB/ 27 GB)→./sql_backup.2022-03-24.tgz
# 7✅: 11.0 days( 5 GB/ 32 GB)→./sql_backup.2022-03-22.tgz
# 8❌: 15.0 days( 5 GB/ 37 GB)→./sql_backup.2022-03-18.tgz
# 9❌: 17.0 days( 5 GB/ 41 GB)→./sql_backup.2022-03-16.tgz
# 10✅: 18.0 days( 5 GB/ 46 GB)→./sql_backup.2022-03-15.tgz
# 11❌: 19.0 days( 5 GB/ 50 GB)→./sql_backup.2022-03-14.tgz
# 12❌: 20.0 days( 5 GB/ 55 GB)→./sql_backup.2022-03-13.tgz
# 13❌: 22.0 days( 5 GB/ 59 GB)→./sql_backup.2022-03-11.tgz
# 14❌: 23.0 days( 5 GB/ 64 GB)→./sql_backup.2022-03-10.tgz
# 15✅: 35.0 days( 4 GB/ 68 GB)→./sql_backup.2022-02-26.tgz
# 16❌: 37.0 days( 4 GB/ 73 GB)→./sql_backup.2022-02-24.tgz
# 17❌: 39.0 days( 4 GB/ 77 GB)→./sql_backup.2022-02-22.tgz
# 18❌: 40.0 days( 5 GB/ 82 GB)→./sql_backup.2022-02-21.tgz
# 19✅: 43.0 days( 4 GB/ 86 GB)→./sql_backup.2022-02-18.tgz
...
...
# 264✅:1426.0 days( 4 GB/ 1 TB)→./sql_backup.2018-05-07.tgz
# 265❌:1433.0 days( 4 GB/ 1 TB)→./sql_backup.2018-04-30.tgz
# 266❌:1447.0 days( 4 GB/ 1 TB)→./sql_backup.2018-04-16.tgz
# 267❌:1482.0 days( 4 GB/ 1 TB)→./sql_backup.2018-03-12.tgz
# 268❌:1489.0 days( 4 GB/ 1 TB)→./sql_backup.2018-03-05.tgz
# 269❌:1509.0 days( 4 GB/ 1 TB)→./sql_backup.2018-02-12.tgz
сохранили 24 файла 105 ГБ
.
Ответ или решение
Скрипт для удаления старых резервных копий с использованием Bash
В данном разделе будет представлен подробный Bash-скрипт, который поможет автоматизировать процесс удаления старых резервных копий вашей базы данных, следуя заданным критериям. Резервные копии формируются с именами, которые имеют заданный вами шаблон. Скрипт обеспечит сохранность необходимых копий и удалит ненужные так, как это описано в вашем запросе.
Описание задачи
Файлы ваших резервных копий именуются по следующему шаблону: prodYYYYMMDD_HHMM.sql.gz
. Вам требуется, чтобы скрипт выполнял следующие действия:
- Сохранять все резервные копии за последние 3 дня.
- Хранить только одну резервную копию в день (в 00:00) для файлов старше 3 дней.
- Хранить одну резервную копию в неделю (по понедельникам) для файлов старше 14 дней.
- Хранить одну резервную копию в месяц (1 числа каждого месяца) для файлов старше 90 дней.
Bash-скрипт
#!/bin/bash
# Определяем переменные
DIR_BACKUPS='/backups' # Путь к директории с резервными копиями
KEEP_DAILY=3 # Количество дней для ежедневных резервных копий
KEEP_WEEKLY=14 # Количество дней для еженедельных резервных копий
KEEP_MONTHLY=90 # Количество дней для ежемесячных резервных копий
# Получаем даты для определения удаляемых файлов
date_keep_daily=$(date -d "-${KEEP_DAILY} days" +"%Y%m%d")
date_keep_weekly=$(date -d "-${KEEP_WEEKLY} days" +"%Y%m%d")
date_keep_monthly=$(date -d "-${KEEP_MONTHLY} days" +"%Y%m%d")
# Проходим по всем файлам резервных копий
for file in $DIR_BACKUPS/prod*.sql.gz; do
# Извлекаем дату и время из имени файла
timestamp=$(basename "$file" .sql.gz)
date_of_file=${timestamp:4:8} # YYYYMMDD
hour_of_file=${timestamp:13:2} # HH
if [[ $date_of_file < $date_keep_monthly ]]; then
# Удаляем, если это не 1-е число месяца
if [[ $(date -d "$date_of_file" +"%d") != "01" ]]; then
rm "$file"
fi
elif [[ $date_of_file < $date_keep_weekly ]]; then
# Удаляем, если это не понедельник
if [[ $(date -d "$date_of_file" +"%u") != "1" ]]; then
rm "$file"
fi
elif [[ $date_of_file < $date_keep_daily ]]; then
# Удаляем, если это не 00:00
if [[ $hour_of_file != "00" ]]; then
rm "$file"
fi
fi
done
Автоматизация выполнения скрипта
Для автоматического выполнения скрипта каждый день вы можете использовать планировщик задач cron
. Для этого выполните команду:
crontab -e
Добавьте следующую строку, чтобы запускать скрипт каждый день в 2:00 ночи:
0 2 * * * /bin/bash /path/to/your_script.sh
Заключение
Этот Bash-скрипт позволяет эффективно управлять резервными копиями базы данных, обеспечивая сохранность важной информации и удаляя лишние данные согласно установленным правилам. Регулярное использование скрипта не только освободит место на диске, но и поможет поддерживать порядок в резервных копиях. Если у вас есть дополнительные требования или изменения в шаблоне именования файлов, вы можете легко адаптировать скрипт под свои нужды.