BACULA CommunityDiskBackupDesign
BACULA CommunityDiskBackupDesign
Using Bacula
Bacula
Systems
Version 2.5, November 25, 2014
Copyright (C) 2008-2014, Bacula Systems S.A.
White
All rights reserved.
Paper
Contents
1 General 2
1.1 Assumptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2 Volume Management 3
2.1 Optimal Volume Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Recycling Volumes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Limiting Volume Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.4 Pruning Volumes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.1 New Prune “Expired” Volume Command . . . . . . . . . . . 5
2.4.2 Manual Pruning . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.5 Attribute Spooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.6 Creating New Volumes . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.7 Volume Fragmentation . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5 Conclusions 22
www.baculasystems.com – 1 / 23
1
General
This White Paper will outline the best practices for setting up a large disk based
backup using Bacula version 7.0 or later.
This document has been adapted from a Bacula Enterprise white paper and is
provided to you by Bacula Systems for your personal use in the hopes that it will
improve your experiences with the Bacula community version.
1.1 Assumptions
The following are the assumptions that we have made:
◾ You are using Bacula 7.0 or later. If using Bacula 5.2 or older, the Changer
Command should be set to an empty string instead of /dev/null.
◾ The retention period for recovering a file on a daily basis is 30 days. That is
for 30 days, you can go back to any prior version of a file on a day by day
basis.
◾ You are using PostgreSQL as your Bacula catalog database. This is highly
recommended by Bacula Systems.
◾ You are using multiple Pools to separate the Volumes that various clients write
to, and to help optimize recycling of old data that is no longer needed. More
on Pools below.
www.baculasystems.com – 2 / 23
2
Volume Management
When using disk based backup, there are a number of basic Bacula issues we must
discuss before getting into the details of designing a backup strategy.
www.baculasystems.com – 3 / 23
Often times, you will want to make some compromise to balance Volume size versus
the number of Volumes. For example, you might limit the number of Jobs to 100
for a given Volume. Doing so with the above example, will mean that you will need
10 Volumes per night to store 1,000 Jobs or 300 for 30 days. Depending on your
data size this may be a good compromise.
If you change the values in the Pool definition the new values will apply to any
new Volumes that you create. If you want your old existing Volumes to use the new
values, you must explicitly do so with the:
update volume FromAllPools
www.baculasystems.com – 4 / 23
2.4 Pruning Volumes
Since automatic catalog pruning can be time consuming, for maximum performance,
you may want to avoid automatic pruning of old jobs at the end of each backup Job.
To do that, set the directive AutoPrune = No in all Client resources, and Bacula
will not automatically try to prune jobs. However, unless you want your catalog
to grow very large, you will need to schedule a RunScript to explicitly handle the
pruning. described in the following section.
Note, the file manual_prune.pl is available on the bacula.org web site with this white
paper.
www.baculasystems.com – 5 / 23
that it can be inserted in one big batch at the end of each job. To do so, use the
following ...
Job {
...
Spool Attributes = Yes
}
The file attributes are spooled into the working directory, and require about 150 bytes
per file, which means a backup consisting of a million files (moderately large backup)
would need 150 MB of space in the working directory. This must be multiplied by
the number of simultaneous Jobs you are running.
Due to the importance of attribute spooling, we have made it default on for Bacula
version 6.0.3 and later.
www.baculasystems.com – 6 / 23
Figure 2.1: Impact of Volume Fragmentation
www.baculasystems.com – 7 / 23
3
Writing Concurrently to
Multiple Devices
We have seen that disk backup can use multiplexing with multiple concurrent jobs
without problems. Now we will discuss how to configure Bacula to spread the work
load over multiple devices automatically.
While it is possible to define multiple Devices in the Storage daemon, and multiple
Storage resources in the Director that use those devices, it can be very complicated
to decide what Job to put on what storage device. In the extreme case, where you
want every Job to have its own set of Volumes to cleanly separate the data, and you
run 2000 Jobs a night, say 50 at a time, you will need 50 separate Storage definitions
in the Director and 50 separate Device definitions in the Storage daemon, further
more, each of your Jobs will have to reference one of the 50 devices that it can write
to. The next section explains how to do this.
www.baculasystems.com – 8 / 23
Changer Device = /dev/null
}
Device {
Name = FileChgr1-Dev1
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
Device {
Name = FileChgr1-Dev2
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
Notice that the Changer Command is empty and the Changer Device points to
/dev/null. This is because the autochanger is virtual, and Bacula knows from each
of the Device definitions where the Volumes are located (in the Archive Device
directive).
Each Device should point to the same directory, have the same MediaType. If two
Devices point to different directories, they should have different MediaType.
Setting Maximum Concurrent Jobs will limit the number of jobs that will be able
to use each Device at the same time (5 in the above example). When the first Device
is running the maximum concurrent jobs defined, Bacula will automatically have the
next Job use the next available Device.
www.baculasystems.com – 9 / 23
second Autochanger, you will want to define a different Media Type so that restores
will work correctly.
If we take the example configuration file given above and expand it to include writing
to a second Autochanger, we might have something like the following:
In the bacula-dir.conf file, you can define two Autochangers as follows:
# Definition of file Virtual Autochanger device
Storage {
Name = File1
# Do not use "localhost" here
Address = bacula-sd # N.B. Use a fully qualified name here
SDPort = 9103
Password = "a+YXY3kfS9ObgZ52ebJT3W"
Device = FileChgr1
Media Type = File1
Maximum Concurrent Jobs = 10 # run up to 10 jobs a the same time
Autochanger = yes
}
Device {
Name = FileChgr1-Dev1
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
Device {
Name = FileChgr1-Dev2
Media Type = File1
Archive Device = /tmp
www.baculasystems.com – 10 / 23
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
#
# Define a Virtual autochanger
#
Autochanger {
Name = FileChgr2
Device = FileChgr2-Dev1, FileChgr2-Dev2
Changer Command = /dev/null
Changer Device = /dev/null
}
Device {
Name = FileChgr2-Dev1
Media Type = File2
Archive Device = /var/tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
Device {
Name = FileChgr2-Dev2
Media Type = File2
Archive Device = /var/tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
For each physical device on which you write Volumes (/tmp and /var/tmp in the
above example), you will need sufficient disk space to hold all the data in your
Volumes. If Bacula fills a disk partition completely, it will stop and ask you to mount
a new Volume and you will be stuck unless you can recycle or delete some of your
existing Volumes. This is because once Bacula chooses a drive to write on at the
beginning of the Job, it cannot switch during that Job to writing on another drive.
Thus currently, there is no way for you to create Volumes on another disk partition
and have Bacula automatically switch when the disk fills.
Just the same, there is a simple way to make Bacula read or write to a different
partition. You may do it by manually creating Volumes and using symbolic linking.
For example:
$ ln -s /var/tmp/Vol001 /tmp/Vol001
$ ln -s /var/tmp/Vol002 /tmp/Vol002
$ ln -s /var/tmp/Vol003 /tmp/Vol003
www.baculasystems.com – 11 / 23
Thus the Volumes you created on /var/tmp appear to Bacula as if they are on /tmp.
So after linking as shown above, you can label the Volumes as Volume Vol001,
Vol002, ... and Bacula will use them as if they were on /tmp but actually write the
data to /var/tmp. The only minor inconvenience with this method is that you must
explicitly name the disks and cannot use automatic labeling unless you take care so
that the labels exactly match the links you have created.
Due to the manual nature of the above, we do not particularly recommend symbolic
linking. However, a bit of scripting could certainly make it much simpler.
By having a different Pool for each Job, you can also force Bacula to write all the
data for each Job on separate Volumes. This technique can also be applied to groups
within an organization. You may want the data for your Personnel department, R&D
department, Sales, and Management all on separate Volumes. This is relatively easy
to do by configuring each Client machine to use the appropriate Pool.
www.baculasystems.com – 12 / 23
3.4 A Dedicated Device per Client
If you want every Client to write to a separate Volume, probably the easiest way
is to define a separate Pool for each Client. When the Job is run to backup that
Client, Bacula will automatically ensure that no other Jobs use the same Device
because the Pool will be different. This will effectively force each Device to run a
single Job at a time. Consequently, in your bacula-sd.conf file, you will want to
define one Device for each Job that will run simultaneously. However, since we are
using a Virtual Autochanger, each Job in the bacula-dir.conf file can reference the
same Storeage resource. Bacula will automatically manage which Job uses which
Drive.
Storage {
Name = RestoreStorage1
# Do not use "localhost" here
Address = bacula-sd # N.B. Use a fully qualified name here
SDPort = 9103
Password = "a+YXY3kfS9ObgZ52ebJT3W"
Device = RestoreStorage1
Media Type = File1
Autochanger = yes # important
}
Above, we have added another Storage device definition in the Director that is named
RestoreStorage1, and this device will be always ready in the Storage daemon to
accept restore Job. During a restore, if all drives are busy, you can manually enter
the Restore storage to be used for the restore.
In the bacula-sd.conf file, the equivalent definitions are:
www.baculasystems.com – 13 / 23
#
# Define a Virtual autochanger
#
Autochanger {
Name = FileChgr1
Device = FileChgr1-Dev1, FileChgr1-Dev2, Restore
Changer Command = /dev/null
Changer Device = /dev/null
}
Device {
Name = FileChgr1-Dev1
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
Device {
Name = FileChgr1-Dev2
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
Device {
Name = RestoreStorage1
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
AutoSelect = no
Autochanger = yes
}
Notice that we have set AutoSelect = no in the Device definition. This prevents
Bacula from selecting that particular device for backup. When AutoSelect=no is
present, the only way to use that Device is by explicitly referencing it (rather than
the Autochanger) in the Director.
During the restore process, Bacula will choose the original Storage resource that was
used to backup your files to restore your files, and if all devices are busy, you will be
able to manually select the RestoreStorage and thus complete the restore.
If you are using Virtual autochanger or group of devices, you can add this Device to
the Autochanger device group.
www.baculasystems.com – 14 / 23
3.6 Truncate Volume on Purge
By default, when Bacula purges a volume, it just changes the volume status in
the catalog. It doesn’t physically touch your Volume or its data. Thus you can still
recover data after the retention period has expired, but the Volume continues to
occupy disk space. This is generally what one wants providing one has sufficient
disks space. For tape based backup, this default behavior is also very useful because
you may want to avoid extra mount operations to just truncate volumes.
However, by truncating the Volume when it is purged, you can recover the disk space
allocated. To do this, you will need to add the directive:
Action On Purge = Truncate
to all your Pool resources, and you will need to schedule a console RunScript to
execute the purge during a period when Bacula is not backing up files. (Note: if
you add this directive, you may need to run an update command to apply Pool’s
configuration changes to the Volumes already created in the catalog).
Below, we show an example of executing the truncate in the Job that runs the nightly
catalog backup.
Job {
Name = CatalogBackup
...
RunScript {
RunsWhen=After
RunsOnClient=No
Console = "purge volume action=all allpools storage=File"
}
}
www.baculasystems.com – 15 / 23
3.8 Accurate
Normally, Bacula does not track deleted files nor does it detect files added to a
system but with an old date. If you have a requirement to track deleted and/or files
added to the system but with old dates, then you should consider using Accurate
= yes in your Job definitions. However, it does require more memory on the Client
machines.
If do not absolutely require Accurate backups, you might still turn it on once a week
if you do only one Full per month as this will keep your backups a bit more in sync
with the real state of the filesystem. To do this, we suggest that you add it as an
option in your Schedule. Please see the Schedule examples at the end of this white
paper.
in your Job resource. This will cause an Incremental Job to be upgraded to a Full if
Bacula does not find a Full that is less than 31 days old.
Another interesting variation of this is to not have any Full backup in your schedule
but to simply set:
Max Full Interval = 30 days
This will cause the Director to automatically upgrade your Incremental Jobs to a
Full at the right interval.
3.10 Schedules
If you are doing a monthly Full backup and then daily Incrementals, and you have
1000 Jobs, to balance your load, you will probably want to run roughly an equal
number of Jobs with Full backups each night of the month, so you need to have 30
different Schedules so that you don’t overload your backup system by running all
your full Jobs the same night.
to email a copy of the BSR file that was written for the Job that does your Catalog
backup to yourself or to some safe email address where these BSR files can be stored
on another machine. If your Bacula server crashes due to a disk failure or some other
catastrophic event, with the BSR files, you will be able to easily recover your catalog
database and thus your server configuration.
www.baculasystems.com – 16 / 23
4
Now that we have covered the main points of how one devises a good backup
strategy for Bacula, let’s put it all together using the assumptions at the beginning
of this white paper, namely:
The steps to take to get to where you have a good system are:
◾ In the Director define one Storage resource for each Storage daemon you will
have. It should have a sufficient number of Devices to run approximately 50-60
simultaneous Jobs, plus one or two Devices to be reserved for restores. If you
put all your data for a given Client on one Volume, you will need 50-60 Device
definitions plus say two reserved Devices. If you allow 10 simultaneous Jobs
per Device, you will only need 5 or 6 Devices.
◾ You will probably want 30 different Schedules so that your Full backups are
even distributed across the different days of the month.
◾ You will want two Pools per client: one for Full backups, and one for Incremental
backups, because the two Pools will have different retention periods to keep
storage space to a minimum.
4.1 bacula-dir.conf
Your Director configuration file bacula-dir.conf has the following main elements:
JobDefs {
Name = "DefaultJob"
Type = Backup
Level = Incremental
www.baculasystems.com – 17 / 23
Client = bacula-fd
FileSet = "All"
Schedule = "First-Sun-Full"
Storage = File1
Messages = Standard
Pool = Client1-Full
SpoolAttributes = yes
Priority = 10
Write Bootstrap = "/opt/bacula/bsr/%c.bsr"
Max Full Interval = 31 days # a full once a month
Spool Attributes = yes
}
Job {
Name = "CatalogBackup"
Type = Backup
JobDefs = DefaultJob
Priority = 11
Schedule = EveryNight
RunBeforeJob = "/opt/bacula/scripts/make_catalog_backup bacula bacula"
RunScript {
RunsWhen = After
RunsOnClient = No
Command = "/opt/bacula/scripts/delete_catalog_backup"
Console = "purge volume action=all allpools storage=File"
}
}
Job {
Name = "Pruning"
Type = Admin
JobDefs = DefaultJob
Priority = 12
Schedule = EveryNight
RunBeforeJob = "/opt/bacula/scripts/manual_prune.pl --doprune --expired"
}
Job {
Name = Client1
JobDefs = "DefaultJob"
Pool = Client1-Full
Full Backup Pool = Client1-Full
Incremental Backup Pool = Client1-Inc
Client = Client1
Schedule = First-Sun-Full
}
...
Client {
Name = Client1
Address = Client1
...
}
...
Pool {
Name = Client1-Full
Pool Type = Backup
Recycle = yes
AutoPrune = no # Done by Pruning Job
www.baculasystems.com – 18 / 23
Volume Retention = 70d # 60 days + a bit extra
Label Format = Client1-Full # Allow to auto label
Action On Purge = Truncate # Allow to volume truncation
Maximum Volume Bytes = 50GB # Limit volume size
Maximum Volumes = 100 # allow 5TB for this Pool
Maximum Volume Jobs = 1 # Force a Volume switch after 100 Jobs
}
Pool {
Name = Client1-Inc
Pool Type = Backup
Recycle = yes
AutoPrune = no # Done by Pruning Job
Volume Retention = 70d # 2 X 30 days + a bit extra
Label Format = Client1-Inc # Allow to auto label
Action On Purge = Truncate # Allow to volume trucation
Maximum Volume Bytes = 50GB # Limit volume size
Maximum Volumes = 20
Maximum Volume Jobs = 6 # Force a Volume switch after a week
}
...
Schedule {
Name = "EveryNight"
Run = Level=Full sun-sat at 5:04
}
Schedule {
Name = First-Sun-Full
Run = Full 1st sun at 22:00
Run = Incremental mon-sat at 22:00
Run = Incremental Accurate=yes 2nd-5th sun at 22:00
}
Schedule {
Name = First-Mon-Full
Run = Full 1st mon at 22:00
Run = Incremental tue-sun at 22:00
Run = Incremental Accurate=yes 2nd-5th mon at 22:00
}
...
Storage {
Name = RestoreStorage1
# Do not use "localhost" here
Address = bacula-sd # N.B. Use a fully qualified name here
SDPort = 9103
www.baculasystems.com – 19 / 23
Password = "a+YXY3kfS9ObgZ52ebJT3W"
Device = RestoreStorage1
Media Type = File1
Autochanger = yes
}
4.2 bacula-sd.conf
Your bacula-sd.conf has the following main elements:
Storage { # definition of myself
Name = bacula-sd
SDPort = 9103 # Director's port
WorkingDirectory = "/opt/bacula/working"
Pid Directory = "/opt/bacula/working"
Maximum Concurrent Jobs = 60
}
Director {
Name = bacula-dir
Password = "a+YXY3kfS9ObgZ52ebJT3W"
}
Messages {
Name = Standard
director = bacula-dir = all
}
#
# Define a Virtual autochanger
#
Autochanger {
Name = FileChgr1
Device = FileChgr1-Dev1, FileChgr1-Dev2, RestoreStorage1
Changer Command = /dev/null
Changer Device = /dev/null
}
Device {
Name = FileChgr1-Dev1
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
Maximum Concurrent Jobs = 5
Autochanger = yes
}
Device {
Name = FileChgr1-Dev2
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
www.baculasystems.com – 20 / 23
Maximum Concurrent Jobs = 5
Autochanger = yes
}
...
Device {
Name = RestoreStorage1
Media Type = File1
Archive Device = /tmp
LabelMedia = yes # lets Bacula label unlabeled media
Random Access = Yes
AutomaticMount = yes # when device opened, read it
RemovableMedia = no
AlwaysOpen = no
AutoSelect = no
Autochanger = yes
}
...
www.baculasystems.com – 21 / 23
5
Conclusions
www.baculasystems.com – 22 / 23
Revision History
www.baculasystems.com – 23 / 23