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 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 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 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
You can’t perform that action at this time.