]> git.pld-linux.org Git - packages/bacula-backup-mysql.git/blame - bacula-backup-mysql
- add performance_schema for mysql 5.5 to default exclude list
[packages/bacula-backup-mysql.git] / bacula-backup-mysql
CommitLineData
1d217da6 1#!/usr/bin/perl -ws
46478424
ER
2# This program is free software; you can redistribute it and/or modify
3# it under the terms of the GNU General Public License as published by
4# the Free Software Foundation; either version 2 of the License, or
5# (at your option) any later version.
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with this program; if not, write to:
14#
15# Free Software Foundation, Inc.
16# 59 Temple Place - Suite 330
17# Boston, MA 02111-1307, USA.
18
1d217da6
ER
19# Rudimentary switch parsing. Must be in main package.
20our $cleanup;
21
38d6af1e 22package BBM;
44be95f6
ER
23use strict;
24use POSIX qw(setuid setgid);
44be95f6
ER
25use DBI;
26use File::Temp qw(tempdir);
27use File::Path qw(rmtree);
44be95f6 28
1d217da6 29
947fde71
ER
30# path to Apache HTTPd-style config
31my $config = '/etc/bacula/backup-mysql.conf';
38d6af1e 32my $c = new BBM::Config($config);
44be95f6 33
7b895eeb 34# now change to user mysql after we've read config
44be95f6
ER
35unless ($<) {
36 my $uid = getpwnam('mysql');
37 my $gid = getgrnam('mysql');
38 die "Can't find user/group mysql\n" unless $uid or $gid;
39
1d217da6
ER
40 # CWD could not be accessible for mysql user
41 chdir("/");
42
44be95f6
ER
43 $) = "$gid $gid";
44 $( = $gid;
45 $> = $< = $uid;
46}
47
48# setup tmpdir
49my $backup_dir = $c->get('options', 'outdir') or die "'outdir' not defined in config\n";
50my $tmpdir = $c->get('options', 'tmpdir') or die "'tmpdir' not defined in config\n";
51
52if (!-d $backup_dir && !mkdir($backup_dir) && !-d $backup_dir) {
53 die "backup dir '$backup_dir' not present and can't be created\n";
54}
55if (!-d $tmpdir && !mkdir($tmpdir) && !-d $tmpdir) {
56 die "tmpdir '$tmpdir' not present and can't be created\n";
57}
58
59# process each cluster
60for my $cluster ($c->get('clusters', 'cluster')) {
61 print ">>> $cluster\n";
1d217da6
ER
62 if ($cleanup) {
63 cleanup_cluster($cluster);
64 } else {
65 backup_cluster($cluster);
66 }
44be95f6
ER
67 print "<<< $cluster\n";
68}
69
46478424 70#
44be95f6
ER
71# Usage: mysqlhotcopy $CLUSTER $DATABASE $USERNAME $PASSWORD $SOCKET
72#
73sub mysqlhotcopy {
74 my ($cluster, $database, $user, $password, $socket) = @_;
75
62f7c875
ER
76 print ">>>> mysqlhotcopy $database\n";
77
44be95f6
ER
78 my $dstdir = tempdir("bbm.XXXXXX", DIR => $tmpdir);
79
80 # make backup with mysqlhotcopy
81 my @shell = ('mysqlhotcopy');
82 push(@shell, '-u', $user) if $user;
83 push(@shell, '-p', $password) if $password;
84 push(@shell, '-S', $socket) if $socket;
85 push(@shell, $database, $dstdir);
86 system(@shell) == 0 or die "mysqlhotcopy failed: $?\n";
87
88 # put it to "production dir"
89 my $cluster_dir = "$backup_dir/$cluster";
90 if (!-d $cluster_dir && !mkdir($cluster_dir) && !-d $cluster_dir) {
49da4557 91 rmtree($dstdir);
44be95f6
ER
92 die "cluster dir '$cluster_dir' not present and can't be created\n";
93 }
94
95 my $dirname = "$backup_dir/$cluster/$database";
96 if (-d $dirname) {
97 rmtree($dirname);
98 }
99
49da4557
ER
100 my $srcdir = "$dstdir/$database";
101 unless (rename($srcdir, $dirname)) {
102 rmtree($dstdir);
103 die "Rename '$srcdir'->'$dirname' failed: $!\n";
104 }
44be95f6
ER
105
106 rmdir($dstdir) or warn $!;
62f7c875
ER
107
108 print "<<<< mysqlhotcopy $database\n";
44be95f6
ER
109}
110
1d217da6
ER
111sub cleanup_cluster {
112 my ($cluster) = @_;
113 my $cluster_dir = "$backup_dir/$cluster";
114 print ">>>> cleanup $cluster_dir\n";
115 rmtree($cluster_dir);
116 print "<<<< cleanup $cluster_dir\n";
117}
118
44be95f6
ER
119sub backup_cluster {
120 my ($cluster) = @_;
121
122 # get db connection info
123 my $user = $c->get($cluster, 'user') || $c->get('client', 'user');
124 my $password = $c->get($cluster, 'password') || $c->get('client', 'password');
125 my $socket = $c->get($cluster, 'socket') || $c->get('client', 'socket');
126
127 # get databases to backup
38d6af1e
ER
128 my @include = $c->get($cluster, 'include_database');
129 my @exclude = $c->get($cluster, 'exclude_database');
44be95f6 130
38d6af1e
ER
131 # start with include list
132 my %dbs = map { $_ => 1 } @include;
62f7c875 133
44be95f6 134 if (@exclude or !@include) {
38d6af1e 135 my $dbh = new BBM::DB($user, $password, $socket);
44be95f6
ER
136 my $sth = $dbh->prepare("show databases");
137 $sth->execute();
138 while (my($dbname) = $sth->fetchrow_array) {
139 next if lc($dbname) eq 'information_schema';
949a3e79 140 next if lc($dbname) eq 'performance_schema';
38d6af1e 141 $dbs{$dbname} = 1;
44be95f6
ER
142 }
143 undef $dbh;
144 }
145
38d6af1e
ER
146 # remove excluded databases
147 delete @dbs{@exclude};
148
44be95f6 149 # now do the backup
38d6af1e 150 foreach my $db (keys %dbs) {
44be95f6
ER
151 mysqlhotcopy($cluster, $db, $user, $password, $socket);
152 }
153}
154
38d6af1e
ER
155package BBM::DB;
156use strict;
44be95f6
ER
157
158# DB class for simple Database connection
159sub new {
160 my $self = shift;
161 my $class = ref($self) || $self;
162
163 my ($user, $password, $socket) = @_;
164 my $dsn = '';
165 $dsn .= "mysql_socket=$socket" if $socket;
166 my $dbh = DBI->connect("DBI:mysql:$dsn", $user, $password, { PrintError => 0, RaiseError => 1 });
167 return $dbh;
168}
38d6af1e
ER
169
170package BBM::Config;
171use strict;
172use Config::General;
173
174sub new {
175 my $self = shift;
176 my $class = ref($self) || $self;
177 my $file = shift;
178
179 my $config = new Config::General(-ConfigFile => $file, -LowerCaseNames => 1);
180 my $this = { $config->getall() };
181 bless($this, $class);
182}
183
184sub get {
185 my ($self, $section, $key) = @_;
186 my $h = $self;
187
188 # descend to [cluster] if $section not present in root tree
189 unless (exists $h->{$section}) {
190 $h = $h->{cluster};
191 }
192
193 # pay attention if callee wanted arrays
194 return wantarray ? () : undef unless exists $h->{$section};
195 return wantarray ? () : undef unless exists $h->{$section}->{$key};
62f7c875
ER
196
197 # deref if wanted array and is arrayref
198 return @{$h->{$section}->{$key}} if wantarray && ref $h->{$section}->{$key} eq 'ARRAY';
199
38d6af1e
ER
200 return $h->{$section}->{$key};
201}
46478424
ER
202
203
204__END__
205
206=head1 NAME
207
208bacula-backup-mysql - A hook for Bacula to backup mysql databases using mysqlhotcopy.
209
210=head1 SYNOPSIS
211
212 Job {
213 Name = "example.org-mysql"
214 ...
72b32af8 215 # This prepares the backup
46478424
ER
216 Client Run Before Job = "/usr/sbin/bacula-backup-mysql"
217 # This deletes the copy of the catalog
218 Client Run After Job = "/usr/sbin/bacula-backup-mysql -cleanup"
219 }
220
221=head1 DESCRIPTION
222
223This is a script to be setup as C<Client Run Before Job> in Bacula.
224
225=head1 AUTHOR
226
949a3e79 227Copyright (C) 2009-2011, Elan RuusamE<auml>e <glen@delfi.ee>
46478424
ER
228
229=head1 SEE ALSO
230
231http://www.bacula.org/
232
233=cut
This page took 0.095028 seconds and 4 git commands to generate.