Столкнулся с интересной проблемой:
Стоит сервер с системой резервного копирования Bacula. Все настроено, все отлично работает. Но вот недавно обнаружилась нехватка дискового пространства, хотя по всем расчетам места было достаточно. В итоге анализа выяснилось следующее:Для большинства серверов настроена схема резервирования 1/m Full, 1/w Diff, 1/d Increment (раз в месяц Полный, раз в неделю дифференциальный, в остальные дни инкрементный). Полные и дифференциальные бэкапы хранятся год, а инкрементные неделю-месяц, в зависимости от сервера. Кроме того выставлена опция делать полный бэкап при изменении конфига - в ней собака и зарыта. По определению дифф. или инкремент. бэкапы меньше полного и когда Вы меняете конфиг для сервера, то полный бэкап создается в пуле для типа бэкапа по планировщику (например сегодня задача инкрементного бэкапа, а в пуле для daily выполнился Full). Еще такой эффект будет наблюдаться в случае уменьшение файлсета или в любом другом случае, когда естественная ротация бэкапов приводит к уменьшению объема хранимой в пуле информации. В случае использования каких то продвинутых систем хранения в Bacula есть механизм переноса томов из пула в пул, но в моем случае неиспользуемые тома необходимо просто выявить и удалить.
Вот так ситуация выглядит в Bacula Admin Tool
Смотрим задачи для тома (List Jobs on Volume)
Резульнат:
Как видим том не используется, а место занимает, мне проще такие тома удалить, а задачи, которым нужны новые просто их создадут себе.
Скрипт предполагает наличие определенного соглашения об именах, а именно:
- Имя клиента - "полное DNS имя"-fd
- Название пулов - "короткое DNS имя"-daily/weekly/monthly
- FileSet - короткое имя
- Job Name - короткое имя
- Storage Name - короткое имя
- Label Format - "короткое имя"-daily/weekly/monthly-date
Собственно скрипт(Python):
#!/usr/bin/env python2.7
# -*- coding: utf8 -*-
import subprocess,os,sys
clients=[]
for i in subprocess.check_output("echo 'list clients' | bconsole | grep fd | cut -d '|' -f3 | cut -d '.' -f1",shell=True).split('\n'):
if (i !=''):
clients.append(i.strip())
listMedia=[]
for i in subprocess.check_output("echo 'list media' | bconsole | grep -E \"(Used | Append | Full)\" | cut -d '|' -f3",shell=True).split('\n'):
if i !='':
listMedia.append(i.strip())
listJobMedia=[]
for n in clients:
for i in subprocess.check_output(["echo 'list jobmedia' | bconsole |grep "+n+" | cut -d '|' -f3"],shell=True).split('\n'):
if (i !='') :
listJobMedia.append(i.strip())
f = open('delVol.txt', 'a')
for i in listMedia:
if i not in listJobMedia:
f.write(i+'\n')
cm=['purge', 'delete']
for k in cm:
comd="echo '"+k+" volume="+i+" yes' | bconsole"
subprocess.call(comd, shell=True)
f.close
Что делает?
С помощью парсинга вывода bconsole, получаем:
- Список clients - список клиентских серверов(вспомогательный для парсинга listJobMedia)
- Список listMedia - список всех томов системы
- Список listJobMedia - список томов, используемыз для хранения данных заданий.
Далее в цикле проверяем есть ли том из listMedia в listJobMedia, если нет - заносим его в файл-список delVol.txt и выролняем для него purge и delete.
В итоге:
Мы удалили пустые тома из bacula и получили список для физического удаления файлов, так как тома для каждого клиента хранятся в разных местах процес удаления физики в скрипте не реализован чтоб не усложнять - при желании можно скрипт доработать, но это уже без меня.
Комментариев нет:
Отправить комментарий