aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2014-03-18 23:17:42 +0200
committerSergey Poznyakoff <gray@gnu.org>2014-03-18 23:33:29 +0200
commit10d30373c6fdf0dd23f16251fa2302c18b7eef97 (patch)
tree5a87a201d719266e6917758f1325f2b8820ce81b
parentb731a0350721ec4a11959446fac93962394711b3 (diff)
downloadbeam-10d30373c6fdf0dd23f16251fa2302c18b7eef97.tar.gz
beam-10d30373c6fdf0dd23f16251fa2302c18b7eef97.tar.bz2
Allow for dumping each MySQL database into a separate file.
* lib/beam/common.in (load_config): Set beam_rsh and backup_local_archive_dir. (beam_exec): New function. * lib/beam/mysql.sh (dump_mysql_db) (restore_mysql_db): New functions. (mysql_backup,mysql_restore): Dump databases individually, depending on the value of <item>_alldb variable. * restore.in: Use beam_exec to run find. * doc/beam.conf.5in: Document changes.
-rw-r--r--doc/beam.conf.5in15
-rw-r--r--lib/beam/common.in23
-rwxr-xr-xlib/beam/mysql.sh215
-rw-r--r--restore.in10
4 files changed, 175 insertions, 88 deletions
diff --git a/doc/beam.conf.5in b/doc/beam.conf.5in
index 69277a7..9462035 100644
--- a/doc/beam.conf.5in
+++ b/doc/beam.conf.5in
@@ -1,8 +1,8 @@
.\" This file is part of BEAM -*- nroff -*-
-.\" Copyright (C) 2012 Sergey Poznyakoff
+.\" Copyright (C) 2012-2014 Sergey Poznyakoff
.\"
.\" BEAM is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
.\" the Free Software Foundation; either version 3, or (at your option)
.\" any later version.
.\"
@@ -11,13 +11,13 @@
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with BEAM. If not, see <http://www.gnu.org/licenses/>.
.\"
-.TH BEAM.CONF 5 "October 30, 2012" "BEAM" "BEAM User Reference"
+.TH BEAM.CONF 5 "March 18, 2014" "BEAM" "BEAM User Reference"
.SH NAME
beam.conf \- configuration file for
.B BEAM
.SH DESCRIPTION
The \fBbeam.conf\fR file defines what data are to be included in the
backup, what backup methods to use and where to store the resulting
@@ -297,12 +297,23 @@ The
.B mysql
backup type creates a dump of a MySQL database and archives it with
.BR tar (1).
The database to dump and access credentials are specified using the
following variables:
.TP
+.BR \fIitem\fB_alldb = single | monolithic | split | individual
+Determines how to dump databases if the \fIitem\fB_database\fR
+(see below) variable is not set. The value \fBsingle\fR or
+\fBmonolithic\fR means dump all databases to a single file named
+after the \fIitem\fR. This is the default. The value \fBsplit\fR
+or \fBindividual\fR instructs \fBbeam\fR to dump each database into
+a separate file, named
+.nh
+\fIitem\fB-\fIdbname\fB-\fIweek\fB-\fIround\fB-\fIlevel\fB.\fIsuffix\fR
+.hy
+.TP
.BR \fIitem\fB_database = \fISTRING\fR
The database name. If this variable is empty, all databases will be
dumped.
.TP
.BR \fIitem\fB_defaults_file = \fIFILE\fR
A full pathname of the MySQL defaults file which contains credentials for
diff --git a/lib/beam/common.in b/lib/beam/common.in
index e99433e..4f2184b 100644
--- a/lib/beam/common.in
+++ b/lib/beam/common.in
@@ -1,9 +1,9 @@
#! /bin/sh
# This file is part of BEAM
-# Copyright (C) 2012 Sergey Poznyakoff
+# Copyright (C) 2012-2014 Sergey Poznyakoff
#
# BEAM is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
@@ -73,13 +73,13 @@ tarcode() {
*) logit "unexpected error code $1"
tarerror=$((tarerror + 1));
esac
}
load_config() {
- local delayed_exit
+ local delayed_exit remote
test -z "$BEAM_CONFIG" && BEAM_CONFIG=@SYSCONFDIR@/beam.conf
if [ -r $BEAM_CONFIG ]; then
. $BEAM_CONFIG
else
abend 1 "configuration file $BEAM_CONFIG does not exist or is unreadable"
@@ -127,12 +127,31 @@ $type"
tar_suffix=${backup_suffix:-.tar}
if [ -n "$backup_bucket_name" ]; then
. @LIBDIR@/beam/s3.sh
prologue_hook="s3_mount $prologue_hook"
fi
+
+ remote=${backup_archive_dir%%:*}
+ if [ "$remote" != "$backup_archive_dir" ]; then
+ beam_rsh="${backup_rsh:-ssh} $remote"
+ backup_local_archive_dir=${backup_archive_dir#*:}
+ else
+ beam_rsh=
+ backup_local_archive_dir=$backup_archive_dir
+ fi
+}
+
+beam_exec() {
+ if [ -z "$beam_rsh" ]; then
+ set -- $(echo "$@" | sed 's/\\\\\([bcfnrtv0]\)/\\\1/g')
+ "$@"
+ else
+ set -- $(echo "$@" | sed 's/\\\\\([bcfnrtv0]\)/\\\1/g;s/[]\[\\\*]/\\&/g')
+ $beam_rsh "$@"
+ fi
}
runhook() {
local hook_list
eval hook_list=\$$1
diff --git a/lib/beam/mysql.sh b/lib/beam/mysql.sh
index 185fa48..e8ec32c 100755
--- a/lib/beam/mysql.sh
+++ b/lib/beam/mysql.sh
@@ -1,9 +1,9 @@
#! /bin/sh
# This file is part of BEAM
-# Copyright (C) 2012 Sergey Poznyakoff
+# Copyright (C) 2012-2014 Sergey Poznyakoff
#
# BEAM is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
@@ -14,105 +14,162 @@
#
# You should have received a copy of the GNU General Public License
# along with BEAM. If not, see <http://www.gnu.org/licenses/>.
# Configuration keywords:
#
-# item_type=mysql [mandatory]
-# item_database=STRING [optional]
-# item_defaults_file=STRING [optional]
+# item_type=mysql [mandatory]
+# item_database=STRING [optional]
+# item_defaults_file=STRING [optional]
+# item_alldb=single|monolithic|split|individual [optional]
#
# mysql_check item
mysql_check() {
- return 0
+ return 0
}
# mysql_list item prefix
mysql_list() {
- local database
-
- eval database=\$${1}_database
- if [ -z "$database" ]; then
- echo "${2}all MySQL databases"
- else
- echo "${2}MySQL database $database"
- fi
+ local database
+
+ eval database=\$${1}_database
+ if [ -z "$database" ]; then
+ echo "${2}all MySQL databases"
+ else
+ echo "${2}MySQL database $database"
+ fi
}
-# mysql_backup item
-mysql_backup() {
- local database
+# dump_mysql_db cmd stem
+dump_mysql_db() {
+ if [ -z "$dry_run" ]; then
+ $1 $db > $backup_tmp_dir/$2-$week-$round-$level
+ else
+ echo "$1 $db > $backup_tmp_dir/$2-$week-$round-$level"
+ fi
- eval database=\$${1}_database
- if [ -z "$database" ]; then
- logit "backing up all MySQL databases"
- else
- logit "backing up MySQL database $database"
- fi
- cmd="mysqldump"
- eval defaults_file=\$${1}_defaults_file
- if [ -n "$defaults_file" ]; then
- cmd="$cmd --defaults-file=$defaults_file"
- fi
- cmd="$cmd --add-drop-database"
- if test -z "$database"; then
- cmd="$cmd --all-databases"
- else
- cmd="$cmd --databases"
- fi
- if [ -z "$dry_run" ]; then
- $cmd $database > $backup_tmp_dir/$1-$week-$round-$level
- else
- echo "$cmd $database > $backup_tmp_dir/$1-$week-$round-$level"
- fi
+ if [ $? -ne 0 ]; then
+ tarerror=$((tarerror + 1))
+ logit "failed"
+ else
+ logit "creating $2-$week-$round-$level.$tar_suffix"
+ $dry_run tar $verbose $taroptions \
+ -f $backup_archive_dir/$2-$week-$round-$level.$tar_suffix \
+ -C $backup_tmp_dir $2-$week-$round-$level
+ tarcode $?
+ $dry_run rm $backup_tmp_dir/$2-$week-$round-$level
+ fi
+}
- if [ $? -ne 0 ]; then
- tarerror=$((tarerror + 1))
- logit "failed"
- else
- logit "creating $1-$week-$round-$level.$tar_suffix"
+restore_mysql_db() {
+ local u
+
+ logit "restoring MySQL database $1"
+ u=$(umask)
+ trap "umask $u" 1 2 3 13 15
+ umask 077
$dry_run tar $verbose $taroptions \
- -f $backup_archive_dir/$1-$week-$round-$level.$tar_suffix \
- -C $backup_tmp_dir $1-$week-$round-$level
- tarcode $?
- $dry_run rm $backup_tmp_dir/$1-$week-$round-$level
- fi
+ -f $backup_archive_dir/$1-$week-$round-$level.$tar_suffix
+ e=$?
+ tarcode $e
+ if [ $e -eq 0 ]; then
+ logit "restoring database from the dump"
+ # Stupid lossage: cannot give -A option here, because with it mysql
+ # refuses to understand defaults-file.
+ cmd="mysql"
+ eval defaults_file=\$${1}_defaults_file
+ if [ -n "$defaults_file" ]; then
+ cmd="$cmd --defaults-file=$defaults_file"
+ fi
+ if [ -n "$dry_run" ]; then
+ echo "$cmd < $1-$week-$round-$level"
+ elif [ -r $1-$week-$round-$level ]; then
+ $cmd < $1-$week-$round-$level > db-$1.log
+ if grep ERROR db-$1.log >/dev/null; then
+ error "errors occurred during restore; see db-$1.log for details"
+ error "dump preserved in file $1-$week-$round-$level"
+ tarerror=$((tarerror + 1))
+ else
+ rm $1-$week-$round-$level
+ fi
+ fi
+ fi
+ umask $u
+ trap - 1 2 3 13 15
}
-mysql_restore() {
- local u database
+# mysql_backup item
+mysql_backup() {
+ local creds cmd database alldb db stem
- eval database=\$${1}_database
- logit "restoring MySQL database $database"
- u=$(umask)
- trap "umask $u" 1 2 3 13 15
- umask 077
- $dry_run tar $verbose $taroptions \
- -f $backup_archive_dir/$1-$week-$round-$level.$tar_suffix
- e=$?
- tarcode $e
- if [ $e -eq 0 ]; then
- logit "restoring database from the dump"
- # Stupid lossage: cannot give -A option here, because with it mysql
- # refuses to understand defaults-file.
- cmd="mysql"
+ eval database=\$${1}_database
+ if [ -z "$database" ]; then
+ logit "backing up all MySQL databases"
+ else
+ logit "backing up MySQL database $database"
+ fi
+ cmd="mysqldump"
eval defaults_file=\$${1}_defaults_file
if [ -n "$defaults_file" ]; then
- cmd="$cmd --defaults-file=$defaults_file"
+ creds="--defaults-file=$defaults_file"
+ cmd="$cmd $creds"
fi
- if [ -n "$dry_run" ]; then
- echo "$cmd < $1-$week-$round-$level"
- elif [ -r $1-$week-$round-$level ]; then
- $cmd < $1-$week-$round-$level > db-$1.log
- if grep ERROR db-$1.log >/dev/null; then
- error "errors occurred during restore; see db-$1.log for details"
- error "dump preserved in file $1-$week-$round-$level"
- tarerror=$((tarerror + 1))
- else
- rm $1-$week-$round-$level
- fi
+ cmd="$cmd --add-drop-database"
+ cmd="$cmd --single-transaction"
+
+ if test -z "$database"; then
+ eval alldb=\$${1}_alldb
+ case $alldb in
+ single|monolithic)
+ cmd="$cmd --all-databases";;
+ split|individual)
+ alldb=split
+ cmd="$cmd --databases"
+ database=$(mysql $creds -e "show databases" -B --skip-column-names);;
+ "") cmd="$cmd --all-databases";;
+ *) error "unknown value: ${1}_alldb=$alldb, assuming 'single'"
+ cmd="$cmd --all-databases";;
+ esac
+ else
+ cmd="$cmd --databases"
+ fi
+
+ if [ -z "$database" ]; then
+ dump_mysql_db "$cmd" "$1"
+ else
+ for db in $database
+ do
+ if [ "$alldb" = split ]; then
+ stem=$1-$db
+ logit "dumping $db"
+ else
+ stem=$1
+ fi
+ dump_mysql_db "$cmd" "$stem"
+ done
fi
- fi
- umask $u
- trap - 1 2 3 13 15
}
+
+mysql_restore() {
+ local database dbname remote
+
+ eval database=\$${1}_database
+ if test -z "$database"; then
+ eval alldb=\$${1}_alldb
+ case $alldb in
+ split|individual)
+ beam_exec find $backup_local_archive_dir \
+ -name $1-'*'-$week-$round-$level.$tar_suffix \
+ -printf '%f\\n' | \
+ while read file
+ do
+ restore_mysql_db $(expr "$file" : "$1-\(.[^-]*\)-.*")
+ done
+ ;;
+ *) restore_mysql_db $1
+ esac
+ else
+ restore_mysql_db $database
+ fi
+}
+
diff --git a/restore.in b/restore.in
index 16a5430..c1dc0c6 100644
--- a/restore.in
+++ b/restore.in
@@ -1,9 +1,9 @@
#! /bin/sh
# This file is part of BEAM
-# Copyright (C) 2012 Sergey Poznyakoff
+# Copyright (C) 2012-2014 Sergey Poznyakoff
#
# BEAM is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
@@ -118,25 +118,25 @@ if [ -z "$week" ]; then
else
week=$(date -d yesterday +%U)
fi
fi
if [ -z "$round" ]; then
- round=$(find $backup_archive_dir \
+ round=$(beam_exec find $backup_local_archive_dir \
-regex '.*-'$week'-[0-9][0-9]*-[0-9][0-9]*\..*' \
- -printf '%f\n' |
+ -printf '%f\\n' |
sed 's/.*-'$week'-\([0-9][0-9]*\)-[0-9][0-9]*\..*/\1/' |
sort +0 -1 |
tail -1)
test -z "$round" && abend 1 "cannot determine last round number"
fi
if [ -z "$level" ]; then
- level=$(find $backup_archive_dir \
+ level=$(beam_exec find $backup_local_archive_dir \
-regex '.*-'$week-$round'-[0-9][0-9]*\..*' \
- -printf '%f\n' |
+ -printf '%f\\n' |
sed 's/.*-'$week-$round'-\([0-9][0-9]*\)\..*/\1/' |
sort +0 -1 |
tail -1)
test -z "$level" && abend 1 "cannot determine last level number"
fi

Return to:

Send suggestions and report system problems to the System administrator.