Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
prune delete and remove old bacula volumes
#!/usr/bin/env bash
#set -x
# Prune and volumes older than 2 months:
PAST=`date --date='-2 months 0 day ago' +%Y-%m-%d`
#EG a hard coded date
#extract stuff from postgresq
psql $DB -c "select volumename from media where lastwritten < '$PAST' " > "$TMPF1"
#an ugly attempt to clean the output.. I'm sure this can be fixed with a flag on the above cmd sometime
VOLS=`awk '{print $1}' "$TMPF1" | tail -n+3 | grep -v "(" `
#output a clean list of volumes into TMPF2
cp /dev/null $TMPF2
for a in $VOLS ; do
echo $a >> $TMPF2
#how many volumes did we match btw?
COUNT=`wc -l $TMPF2 | awk '{print $1}'`
if [ "$COUNT" -gt 0 ]; then
echo "Found $COUNT volumes"
for a in `cat "$TMPF2"` ; do
echo "### processing $a ###"
cp /dev/null $TMPF1
printf "prune yes volume=$a\n" >> $TMPF1
printf "delete yes volume=$a\n" >> $TMPF1
#bconsole <$TMPF1 1>/dev/null
# ^ uncomment the above to go live, check this works first!
#check if bconsole exited with an error
if [ "$?" -gt 0 ]; then
echo "+[$a]: WARNING: something went wrong with bconsole: $?"
echo "See: TMPF1=$TMPF1 / TMPF2=$TMPF2"
# The above takes care of the bacula side.. now delete files
# as I store my files in a per-host directory (and keep catalog files elsewhere I just split this into two:
#Firstly lets remove the Catalog files
if grep -q ^Catalog_File <<< "$a" ; then
echo "+[$a] removing file: $FPATH/$a"
echo rm -f "$FPATH/$a"
# rm -f "$FPATH/$a"
# ^ uncomment the above to go live
# else its a client..
# get the clients name from $a
NAME="$(cut -d "-" -f 1 <<<"$a")"
echo "+[$a] removing file: $FPATH/$NAME/$a"
echo rm -f "$FPATH/$NAME/$a"
# rm -f "$FPATH/$NAME/$a"
# ^ uncomment the above to go live
echo "No volumes found older than $PAST"
rm "$TMPF1" "$TMPF2"
## Now as you may note the log table can get quite large.
# bacula does not (internally) rely on this in any form.. rather the "file" table is the important one
# bacula=# SELECT
#bacula-# relname AS objectname,
#bacula-# relkind AS objecttype,
#bacula-# reltuples AS "#entries", pg_size_pretty(relpages::bigint*8*1024) AS size
#bacula-# FROM pg_class
#bacula-# WHERE relpages >= 8
#bacula-# ORDER BY relpages DESC;
# objectname | objecttype | #entries | size
# log | r | 2.18772e+06 | 78 GB
# file | r | 3.49857e+08 | 51 GB
# file_jpfid_idx | i | 3.49857e+08 | 24 GB
# file_jobid_idx | i | 3.49857e+08 | 13 GB
# file_pkey | i | 3.49857e+08 | 11 GB
# log_name_idx | i | 2.18772e+06 | 7681 MB
# I suggest you truncate the bastard
# psql $DB -c "TRUNCATE log;"

This comment has been minimized.

Copy link

@dlangille dlangille commented Jun 3, 2014

With reference to this is a good start. I reckon it'll be useful. If you can avoid bash in shell scripts, it'll be more likely to be adopted by those without bash.


This comment has been minimized.

Copy link

@umardraz umardraz commented Jun 20, 2017


Good script, Now is it possible to select lastwritten from media only for specific client?

Actually I want to delete few days old data only for one client including any prune, purged and from /var/lib/bareos/storage


This comment has been minimized.

Copy link

@rsftsi rsftsi commented Dec 13, 2019

Great job, thanks a lot! ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment