]> git.pld-linux.org Git - packages/bacula-backup-mysql.git/blob - bacula-backup-mysql
e41b5f8fd9fb63da0dff96c5599661306f5d7dd5
[packages/bacula-backup-mysql.git] / bacula-backup-mysql
1 #!/usr/bin/perl -w
2 use strict;
3 use POSIX qw(setuid setgid);
4
5 use DBI;
6 use File::Temp qw(tempdir);
7 use File::Path qw(rmtree);
8 use delfi::mycnf;
9
10 # path to ini-style config
11 my $config = '/etc/bacula/backup-mysql.conf';
12 my $c = new delfi::mycnf($config);
13 # force reading config file before we switch user
14 $c->get("");
15
16 # how change to user mysql after we've read config
17 unless ($<) {
18         my $uid = getpwnam('mysql');
19         my $gid = getgrnam('mysql');
20         die "Can't find user/group mysql\n" unless $uid or $gid;
21
22         $) = "$gid $gid";
23         $( = $gid;
24         $> = $< = $uid;
25 }
26
27 # setup tmpdir
28 my $backup_dir = $c->get('options', 'outdir') or die "'outdir' not defined in config\n";
29 my $tmpdir = $c->get('options', 'tmpdir')  or die "'tmpdir' not defined in config\n";
30
31 if (!-d $backup_dir && !mkdir($backup_dir) && !-d $backup_dir) {
32         die "backup dir '$backup_dir' not present and can't be created\n";
33 }
34 if (!-d $tmpdir && !mkdir($tmpdir) && !-d $tmpdir) {
35         die "tmpdir '$tmpdir' not present and can't be created\n";
36 }
37
38 # process each cluster
39 for my $cluster ($c->get('clusters', 'cluster')) {
40         print ">>> $cluster\n";
41         backup_cluster($cluster);
42         print "<<< $cluster\n";
43 }
44
45
46 # Usage: mysqlhotcopy $CLUSTER $DATABASE $USERNAME $PASSWORD $SOCKET
47 #
48 sub mysqlhotcopy {
49         my ($cluster, $database, $user, $password, $socket) = @_;
50
51         my $dstdir = tempdir("bbm.XXXXXX", DIR => $tmpdir);
52
53         # make backup with mysqlhotcopy
54         my @shell = ('mysqlhotcopy');
55         push(@shell, '-u', $user) if $user;
56         push(@shell, '-p', $password) if $password;
57         push(@shell, '-S', $socket) if $socket;
58         push(@shell, $database, $dstdir);
59         system(@shell) == 0 or die "mysqlhotcopy failed: $?\n";
60
61         # put it to "production dir"
62         my $cluster_dir = "$backup_dir/$cluster";
63         if (!-d $cluster_dir && !mkdir($cluster_dir) && !-d $cluster_dir) {
64                 die "cluster dir '$cluster_dir' not present and can't be created\n";
65         }
66
67         my $dirname = "$backup_dir/$cluster/$database";
68         if (-d $dirname) {
69                 rmtree($dirname);
70         }
71
72         my $srcdir= "$dstdir/$database";
73         rename($srcdir, $dirname) or die "Rename '$srcdir'->'$dirname' failed: $!\n";
74
75         rmdir($dstdir) or warn $!;
76 }
77
78 sub backup_cluster {
79         my ($cluster) = @_;
80
81         # get db connection info
82         my $user = $c->get($cluster, 'user') || $c->get('client', 'user');
83         my $password = $c->get($cluster, 'password') || $c->get('client', 'password');
84         my $socket = $c->get($cluster, 'socket') || $c->get('client', 'socket');
85
86         # get databases to backup
87         my @dbs;
88
89         my @include = $c->get($cluster, 'include_databases');
90         my @exclude = $c->get($cluster, 'exclude_databases');
91         if (@exclude or !@include) {
92                 my $dbh = new DB($user, $password, $socket);
93                 my $sth = $dbh->prepare("show databases");
94                 $sth->execute();
95                 while (my($dbname) = $sth->fetchrow_array) {
96                         next if lc($dbname) eq 'information_schema';
97                         push @dbs, $dbname unless grep { m{^\Q$dbname\E$} } @exclude;
98                 }
99                 undef $dbh;
100         }
101
102         # now do the backup
103         foreach my $db (@dbs) {
104                 mysqlhotcopy($cluster, $db, $user, $password, $socket);
105         }
106 }
107
108 package DB;
109
110 # DB class for simple Database connection
111 sub new {
112         my $self = shift;
113         my $class = ref($self) || $self;
114
115         my ($user, $password, $socket) = @_;
116         my $dsn = '';
117         $dsn .= "mysql_socket=$socket" if $socket;
118         my $dbh = DBI->connect("DBI:mysql:$dsn", $user, $password, { PrintError => 0, RaiseError => 1 });
119         return $dbh;
120 }
This page took 0.066949 seconds and 3 git commands to generate.