Jump to content
warmbowski

Example LVM Backup Script (external scripting)

Recommended Posts

So now that we got it all sorted out as to how to set up external scripting for a Linux client, I wanted to make sure to post the script that I needed to create.

 

This script is for backing up Zimbra Collaboration Suite on a Logical Volume, though I am sure it can be adapted to other apps that need to be backed up with minimal downtime. In my case the /opt folder is a unique logical volume and contains my Zimbra install that I need to backup (as well as some other apps). Since Zimbra is fairly self contained, all I need to do is backup this folder to get a backup of the app and data. But before I back it up, I need to make sure that the database has flushed all tables to disk and nothing is changing during that time (i.e. maintain state). I do this by having retrospect stop Zimbra before taking the snapshot and then restarting it. Then retrospect backs up the snapshot. Downtime is about 3 min (which is ostensibly the time it takes to restart zimbra).

 

To do this, you need to make sure you have some unused partition space on your volume group (in my case 3GB), usually about 10% of the size of the volume to be backed up (I'm backing up ~40GB currently). Then put the code below in a file called /etc/retroeventhandler and make it executable and tweak the variables to suite you.

 

This code is pretty much the verbatim code for lvm backup from the Zimbra wiki, but split up to execute the relevant parts before and after the backup.

 

#!/bin/bash
#
# Retrospect Client retroeventhandler script
# 
# Contact Information 
# 
# EMC Corporation 
# 3003 Oak Road, 3rd Floor 
# Walnut Creek, CA 94597 
# 800.225.4880 or 925.948.9000
# customer_service@dantz.com
# 
# Copyright 2000-2005 EMC Corporation 
#
#
# How to use this script
# 
# Any executable with pathname /etc/retroeventhandler will be run 
# at the beginning and end of each source in a scripted backup. 
# The executable is passed one of the following parameter arrays:
#
#  StartSource, Script name(string), Source path(string),
#  Source name(string), Client name(string), Err file(empty)
#
#  EndSource, Script name(string), Source path(string),
#  Source name(string), Client name(string), KB stored(int),
#  Files stored(int), Duration in seconds(int), Source
#  start(date string), Source end(date string), 
#  Script start(date string), Backup set(string), 
#  Backup type(string), Source parent(string),
#  Errors(int), Fatal errors(int), Result(string)
#
# If a non-zero exit code is encountered for an execution trig-
# gered by the StartSource event, that backup source will 
# be skipped.
#
# Notes
# 1. The Source path is non-intuitive for mount points; it shows 
#    the Retrospect object path rather than the Linux or Unix path. For 
#    example, on client Bongo Fury  with an external drive mounted 
#    to /mnt/ext, the source path is "Backup Clients/Bongo Fury/ext", 
#    while the source name is "/mnt/ext".
#
# 2. Parameters 2 through 17 are passed double-quoted, so you
#    have to include the double quotes in your string for exact
#    pattern matching in tests (e.g. $X = [ "\"ScriptName\"" ])
#
# This sample script appends a timestamp and the arguments it 
# receives to a log file.
LOGFILE=/var/log/retro-events.log
date >>$LOGFILE
for X in "$@"; do
   echo $X >>$LOGFILE
done
# This sample script prevents a script named Invasive from
# backing up the /mnt/ext mountpoint.
#if [ $2 = "\"Invasive\"" ] && [ $4 = "\"/mnt/ext\"" ]; then
#	exit 1
#fi





###################################################################################
# 
#    Script to backup a Zimbra installation (open source version)
#    by installing the Zimbra on a separate LVM Logical Volume,
#    taking a snapshot of that partition after stopping Zimbra,
#    restarting Zimbra services, , then using retrospect to backup the snapshot.
#
#    This script was originally based on a script found on the Zimbra wiki
#    http://wiki.zimbra.com/index.php?title=Open_Source_Edition_Backup_Procedure
#    and totally rewritten since then.
#
#    Copyright (C) 2007 Serge van Ginderachter 
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 2 as 
#    published by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    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 this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#    Or download it from http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
####################################################################################

#### Modify the following variables according to your installation

# backup_dir - directory to backup to 
zm_backup_path=/home/zbackup

# zm_lv - the Logical Volume that contains /opt/zimbra - /opt mount point expected
zm_lv=LogVol00

# vol_group - the Volume Group that contains $zm_lv
zm_vg=VolGroup01

# zimbra_path - the path beneath the Logical Volume $zm_lv that needs to be synced
zm_path=zimbra

# zm_lv_fs - the file system type (ext3, xfs, ...) in /opt/zimbra
zm_lv_fs=ext3

# lvcreate lvremove - path and command for the lvm logical volume creation and deletion command
LVCREATE=/usr/sbin/lvcreate
LVREMOVE=/usr/sbin/lvremove

#### Modify the following variables according to your taste and needs

# zmsnapshot - the snapshot volume name for $zm_lv
zm_snapshot=zbackup

# zmsnapshot_size - size avalable for growing the snapshot
zm_snapshot_size=3GB

# zm_snapshot_mnt - zimbra snapshot mount point
zm_snapshot_path=/mnt/zbackup


#### Following parameters probably shouldn't need to be changed

log_facility=daemon
log_facility_mail=mail
log_level=notice
log_level_err=error
log_tag="$0"


say() { 
MESSAGE_PREFIX="zimbra backup:"
MESSAGE="$1"
TIMESTAMP=$(date +"%F %T")
echo -e "$TIMESTAMP $MESSAGE_PREFIX $MESSAGE"
logger -t $log_tag -p $log_facility.$log_level "$MESSAGE" 
logger -t $log_tag -p $log_facility_mail.$log_level "$MESSAGE"
}

error ()  {
MESSAGE_PREFIX="zimbra backup:"
       MESSAGE="$1"
TIMESTAMP=$(date +"%F %T")
echo -e $TIMESTAMP $MESSAGE >&2
logger -t $log_tag -p $log_facility.$log_level_err "$MESSAGE"
logger -t $log_tag -p $log_facility_mail.$log_level_err "$MESSAGE"
exit
}


##########################################
# Create and mount snapshot prior to retrospect backup
##########################################

if [ $1 = "StartSource" ] && [ $4 = "\"/mnt/zbackup/\"" ]; then

# load kernel module to enable LVM snapshots
/sbin/modprobe dm-snapshot || error "Error loading dm-snapshot module"

# Output date
say "$2 backup started"

# Stop the Zimbra services
say "stopping the Zimbra services, this may take some time"
/etc/init.d/zimbra stop || error "error stopping Zimbra" 
kill -9 $(ps -u zimbra -o "pid=") #|| error "Error stopping Zimbra" #added as a workaround to zimbra bug 18653

# Create a logical volume called ZimbraBackup
say "creating a LV called $zm_snapshot"
$LVCREATE -L $zm_snapshot_size -s -n $zm_snapshot /dev/$zm_vg/$zm_lv  || error "error creating snapshot, exiting" 

# Start the Zimbra services
say "starting the Zimbra services in the background....."
(/etc/init.d/zimbra start && say "services background startup completed") || error "services background startup FAILED" &

# Mount the logical volume snapshot to the mountpoint
say "mounting the snapshot $zm_snapshot"
mount -t $zm_lv_fs -o ro /dev/$zm_vg/$zm_snapshot $zm_snapshot_path

# Create the current backup
say "snapshot ready for retrospect backup"

fi



##########################################
# Unmount and remove snapshot after retrospect backup
##########################################

if [ $1 = "EndSource" ] && [ $4 = "\"/mnt/zbackup/\"" ]; then

# Unmount $zm_snapshot from $zm_snapshot_mnt
say "unmounting the snapshot"
umount $zm_snapshot_path || error "error unmounting snapshot"

# Remove the snapshot volume
# https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.15/+bug/71567
say "pausing 1s and syncing before removing the snapshot from LVM"
sleep 1 ; sync                 
say "removing the snapshot"
$LVREMOVE --force /dev/$zm_vg/$zm_snapshot  || say "error removing the snapshot"

# Done!
say "$2 backup ended: ${17} ($6 KB - $7 Files - $8 Folders)"

fi


 

Automating the backup with this code has worked out well, although I have yet to do a test restore. I will post more about restore upon completing it.

 

Enjoy

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×