Open Source Edition Backup Procedure: Difference between revisions
Line 754: | Line 754: | ||
and kill any left over processes such as the log. | and kill any left over processes such as the log. | ||
Alternatively you could run the following command to kill all Zimbra user owned processes instantly (use wisely): | Alternatively as root you could run the following command to kill all Zimbra user owned processes instantly (use wisely): | ||
>ps auxww | awk '{print $1" "$2}' | grep zimbra | kill -9 `awk '{print $2}'` | >ps auxww | awk '{print $1" "$2}' | grep zimbra | kill -9 `awk '{print $2}'` |
Revision as of 01:50, 29 November 2007
If you wish to have a more automated backup feature, you should try the [Network Version of Zimbra.]
Backup Scripts
Backup Using LVM
If you have your Zimbra installation on its own logical volume, you can use this script:
#!/bin/bash time=`date +%Y-%m-%d_%H-%M-%S` # Modify the following variables according to your installation ######################################### # backup_dir - directory to backup to backup_dir=/path/to/backups/$time # vol_group - the Volume Group that contains $zimbra_vol vol_group=PUT_VOL_GROUPNAME_HERE # zimbra_vol - the Logical Volume that contains /opt/zimbra zimbra_vol=PUT_ZIMBRA_VOLNAME_HERE # Do not change anything beyond this point ######################################### # Test for an interactive shell if [[ $- != *i* ]] then say() { echo -e $1; } # Colors, yo! GREEN="\e[1;32m" RED="\e[1;31m" CYAN="\e[1;36m" PURPLE="\e[1;35m" else say() { true; } # Do nothing fi # Output date say $GREEN"Backup started at "$RED"`date`"$GREEN"." # Stop the Zimbra services say $CYAN"Stopping the Zimbra services..." say $PURPLE" This may take several minutes." /etc/init.d/zimbra stop # Create a logical volume called ZimbraBackup say $GREEN"Creating a LV called ZimbraBackup:"$PURPLE /usr/sbin/lvcreate -L1000M -s -n ZimbraBackup /dev/$vol_group/$zimbra_vol # Create a mountpoint to mount the logical volume to say $GREEN"Creating a mountpoint for the LV..." mkdir -p /tmp/ZimbraBackup # Mount the logical volume to the mountpoint say $GREEN"Mounting the LV..." mount /dev/$vol_group/ZimbraBackup /tmp/ZimbraBackup/ # Start the Zimbra services say $CYAN"Starting the Zimbra services..." /etc/init.d/zimbra start & # For testing only #say $RED"Press Enter to continue...\e[0m" #read input # Create the current backup say $GREEN"Creating the backup directory and backup..." mkdir -p $backup_dir tar zcvf $backup_dir/zimbra.backup.tar.gz /tmp/ZimbraBackup/zimbra/ 2&> /dev/null # Unmount /tmp/ZimbraBackup and remove the logical volume say $GREEN"Unmounting and removing the LV."$PURPLE umount /tmp/ZimbraBackup/ /usr/sbin/lvremove --force /dev/$vol_group/ZimbraBackup # Done! say $GREEN"Zimbra backed up to "$CYAN$backup_dir$GREEN"!" say $GREEN"Backup ended at "$RED"`date`"$GREEN".\e[0m"
More elaborated script, using LVM and rsync
See also https://support.ginsys.be/files Download most recent version of this script Send feedback to Serge van Ginderachter <svg@ginsys.be>
#!/bin/bash # # 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 rsyncing the snapshot to a # separate backup point. # 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 <svg@ginsys.be> # # 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=/opt.bak # zimbra_vol - the Logical Volume that contains /opt/zimbra - /opt mount point expected zm_lv=opt # vol_group - the Volume Group that contains $zimbra_vol zm_vg=data # zimbra_path - the path beneath the Logical Volume $zimbra_col that needs to be synced zm_path= # lvcreate lvremove - path and command for the lvm logical volume creation and deletion command LVCREATE=/sbin/lvcreate LVREMOVE=/sbin/lvremove #### Modify the following variables according to your taste and needs # zmsnapshot - the snapshot volume name for $zm_vol zm_snapshot=opt-snapshot # zmsnapshot_size - size avalable for growing the snapshot zm_snapshot_size=1GB # zm_snapshot_mnt - zimbra snapshot mount point zm_snapshot_path=/tmp/opt-snapshot # rsync verbose set to "v" # V=v V= #### 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" ########################################## # Do not change anything beyond this point ########################################## say() { MESSAGE_PREFIX="zimbra backup:" MESSAGE="$1" TIMESTAMP=$(date +"%F %T") echo -e "$TIMESTAMP $MESSAGE_PREFIX $MESSAGE" logger -t $log_tag -p $facility.$level "$MESSAGE" logger -t $log_tag -p $facility_mail.$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 } # load kernel module to enable LVM snapshots modprobe dm-snapshot # Output date say "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" # 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 "Zimbra: Services background startup completed") || error "services background startup FAILED" & # Create a mountpoint to mount the logical volume to say "creating mountpoint for the LV" mkdir -p $zm_snapshot_path || error "error creating snapshot mount point $zm_snapshot_path" # Mount the logical volume snapshot to the mountpoint say "mounting the snapshot $zm_snapshot" mount /dev/$zm_vg/$zm_snapshot $zm_snapshot_path -t ext3 # Create the current backup say "rsyncing the snapshot to the backup directory $backup_dir" rsync -a$V --delete $zm_snapshot_path/$zm_path $zm_backup_path || say "error during rsync but continuing the backup script" # Unmount $zm_snapshot from $zm_snapshot_mnt say "unmounting the snapshot" umount $zm_snapshot_path || error "error unmounting snapshot" # Delete the snapshot mount dir rmdir $zm_snapshot_path # Remove the snapshot volume # https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.15/+bug/71567 say "pausing and syncing before removing the snapshot from LVM" sleep 1; sync; sleep 1; sync ; sync say "removing the snapshot" $LVREMOVE --force /dev/$zm_vg/$zm_snapshot || say "error removing the snapshot" # Done! say "backup $backup_dir ended" date >$backup_dir/lastsync
The Perl way of doing it (without LVM)
ZCS Tools currently contains a Cold Backup script written in Perl. It also supports backup rotation. This script does not use LVM.
Currently: zimbraColdBackup-Ver0.02beta
#!/usr/bin/perl use strict; use warnings; use POSIX; use IO::Scalar; # for building up output on a string use Proc::ProcessTable; # for killing processes use File::Path; # for removing directories use File::Rsync; # for syncing using rsync use Mail::Mailer; # for sending email ############################################################################# # Please make changes below to suit your system and requirements # absolute path to'rsync' on your system my $rsync = '/usr/bin/rsync'; # absolute path to zimbra directory my $zimbra = '/opt/zimbra'; # absolute path to backup directory. ensure that it exists! my $backup_dir = '/backup'; # do you want to rotate backups? my $rotate_bak = 1; # 1 = yes, 0 = no # if yes, after how many days? # make sure that you don't specify '0'. Specifying zero will delete even # the latest backup - that is, the backup taken today and you will end up # with no data! my $rotate_days = 7; # do you want to send the backups to a remote location? (using rsync) my $send_remote = 0; # 1 = yes, 0 = no # if you would like to use Rsync to send to remote location: # please enter the destination server below # (before using the script make sure that you have password-less and # passphrase-less SSH login setup using private / public cryptography # this script will neither provide SSH password nor the passphrase my $ssh_server = 'host.domain.com'; # SSH server IP or hostname my $remote_path = '/backups'; # path on remote server to send backup # Finally: # Do you want to have the results of backup emailed? my $send_result = 1; # 1 = yes, 0 = no # if yes, to whom whould it be emailed? my $to_email = 'smile@sis.net.in'; # CC email (optional: you can leave this empty) my $cc_email = ''; # BCC email (optional: you can leave this empty) my $bcc_email = ''; # Sender / From email (it will look like the email arrive from this person) my $from_email = 'root@localhost'; # That's it! # Don't edit below this line unless you know what you're doing ############################################################################# my $zimbra_user = 'zimbra'; my $prog_name = $0; # properties of this program # name of program my $progname = "zimbraColdBackup"; # version number my $version = "0.2Beta"; # revision number (independent of version number) my $revision = "30"; # license under which distributed my $license = qq( ############################################################################# # Program Name $progname # # Program Version $version # # Program Revision $revision # # # # This script can be used to backup Zimbra Collaboration Suite 4.0.0 GA # # # # Most recent version of this script can be downloaded from: # # http://sourceforge.net/projects/zcstools/ # # # # Copyright (C) 2006 Chintan Zaveri # # E-mail: smile\@sis.net.in # # # # 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., # # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # ############################################################################# ); # usage text my $usage = qq( Usage: zimbraColdBackup OPTION help|usage|?|--help|--usage All of these options, or providing no options will print this text about usage. overview|--overview What this script does. install|installation|--install|--installation These options will display a text on installation of this script. confirm|--confirm These options will run the backup procedure. version|--version These options will print the Name, Version and Revision Number for this script. license|licence|lisense|lisence|--license|--licence|--lisense|--lisence These options will print the License under which this program is distributed. ); # overview text my $overview = qq( Overview: This script can be used to take off-line backup of Zimbra Collaboration Suite. The following is the series of actions undertaken by this script: 1. Stop Zimbra 2. Backup Zimbra in the specified local directory using Rsync 3. Start Zimbra Optionally, if you specified, this script will also do the following: 1. Rotate the backups 2. Send the backup to another system using Rsync 3. Email the results of backup ); # installation text my $installation = qq( Installation: It is fairly easy to install this script. The installation requires you to do the following: 1. Install all required Perl modules 2. Configure this script 3. Run it once - Test it! 4. Schedule it using crontab 1. Install all required Perl modules The best way to do this is by running the script. Once you run the script, you would receive an error message similar to the following: Can't locate Mail/Mailer.pm in \@INC (\@INC contains: /usr/lib/perl5/5.8.5/i386-linux-thread-multi /usr/lib/perl5/5.8.5 /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.4/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.3/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.2/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.1/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl/5.8.4 /usr/lib/perl5/site_perl/5.8.3 /usr/lib/perl5/site_perl/5.8.2 /usr/lib/perl5/site_perl/5.8.1 /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.4/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.3/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.2/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.1/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl/5.8.4 /usr/lib/perl5/vendor_perl/5.8.3 /usr/lib/perl5/vendor_perl/5.8.2 /usr/lib/perl5/vendor_perl/5.8.1 /usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl .) at ./ZimbraColdBackup.pl line 9. BEGIN failed--compilation aborted at ./zimbraColdBackup.pl line 9. In the first line you can see that it is unable to locate Mail/Mailer.pm To install this module, just type the following: perl -MCPAN -e 'install Mail::Mailer' This command will install the Mail::Mailer module. Remember, the "/" must be converted to "::" when providing the command and the ".pm" must be removed. You may receive such errors for a few times. Just install the relevant modules. 2. Configure the script Once the modules are installed, you need to open this script in a text editor, such as "vi" or "nano". Please enter correct values against the variables at the top of the script. Once you open it in a text editor, it will become self-explanatory. 3. Run it once - Test it! Just say: "./zimbraColdBackup confirm" after you have configured it. It should run and do as promised. If it doesn't just let me know, or ensure that it has been properly configured. 4. Schedule it using crontab Create a cron job using the command 'crontab -e' to run the script at fixed intervals. ); # parse the arguments # if there are no arguments print usage and die die $usage, @_ if ( $#ARGV + 1 < 1 ); # what was the argument? (ignore more than one arguments...) my $option = $ARGV[0]; # select action if ( ( $option =~ /^(--)?help$/ ) || ( $option =~ /^(--)?usage$/ ) || ( $option =~ /^\?$/) ) { die $usage, @_; } elsif ( $option =~ /^(--)?overview$/ ) { die $overview, @_; } elsif ( $option =~ /^(--)?install(ation)?$/ ) { die $installation, @_; } elsif ( $option =~ /^(--)?confirm$/ ) { 1; # go ahead and run the script } elsif ( $option =~ /^(--)?version$/) { die $progname, " Ver. ", $version, " Rev. ", $revision, "\n", @_; } elsif ( $option =~ /^(--)?li[sc]en[sc]e$/ ) { die $license, @_; } else { die "Invalid option: Please try again", $usage, @_; } # going ahead and running the script :-) # check inputs if ( ( $rsync eq "" ) || ( $rsync !~ /^\// ) ) { die "Please provide an absolute path to 'rsync'", "\n", @_; } if (! ( -d $zimbra ) ) { die "Please provide an absolute path to 'zimbra' directory", "\n", @_; } if (! ( -d $backup_dir ) ) { die "Please provide an absolute path to backup directory", "\n", @_; } if ( $send_remote =~ /\D/ ) { die "Please enter either '1' or '0' in \$send_remote", "\n", @_; } if ( $send_remote ) { # check ssh params if ( $ssh_server eq "" ) { die "Please enter valid SSH server to rsync to.", "\n", @_; } } if ( $rotate_bak =~ /\D/ ) { die "Please enter either '1' or '0' in \$rotate_bak", "\n", @_; } if ( $rotate_days =~ /\D/ ) { die "Please enter either '1' or '0' in \$rotate_days", "\n", @_; } if ( $send_result =~ /\D/ ) { die "Please enter either '1' or '0' in \$send_result", "\n", @_; } if ( $send_result ) { if ( ! $to_email ) { die "Please enter valid email in \$to_email", "\n", @_; } if ( ! $from_email ) { die "Please enter valid email in \$from_email", "\n", @_; } } # if you reach here, everything is valid, please proceed my $result = ''; my $res_fh = IO::Scalar->new ( \$result ); # now whatever output we want to build up, we will print to $res_fh print $res_fh "Date: ", POSIX::strftime ( '%m-%d-%Y, %A, %H:%M', localtime ( time ) ), " Hours\n"; # current day, date, month, time, ... my $current_time = POSIX::strftime ( '%m-%d-%Y-%A-%H-%M', localtime ( time ) ); my $since_epoch = time ( ); # seconds since epoch my $bak_dir = $backup_dir; # we want to use the backup dir path later $backup_dir .= '/'.$current_time.'-'.$since_epoch; # Stop Zimbra my $zmstopstat = system ( "su - zimbra -c '$zimbra/bin/zmcontrol stop'" ); if ( $zmstopstat ) { print $res_fh "Stopping Zimbra: Some Problem Occurred. Please check.\n"; } else { print $res_fh "Stopping Zimbra: Success\n"; } # Kill all lingering Zimbra processes my $zimbra_uid = getpwnam ( $zimbra_user ); my $process_table = Proc::ProcessTable->new; # Gracefully kill lingering processes: kill -15, sleep, kill -9 foreach my $process ( @{$process_table->table} ) { if ( ( $process->uid eq $zimbra_uid ) || ( ( $process->cmndline =~ /$zimbra_user/ ) && ( $process->cmndline !~ /$prog_name/ ) ) ) { kill -15, $process->pid; # thanks, merlyn sleep 10; # not sure if there'll be buffering. kill -9, $process->pid; } } # Backup Zimbra using "rsync" my $rsync_obj = File::Rsync->new ( { 'rsync-path' => $rsync, 'archive' => 1, 'recursive' => 1, 'links' => 1, 'hard-links' => 1, 'keep-dirlinks' => 1, 'perms' => 1, 'owner' => 1, 'group' => 1, 'devices' => 1, 'times' => 1 } ); my $zmrsyncstat = $rsync_obj->exec ( { src => "$zimbra/", dest => "$backup_dir" } ); if ( $zmrsyncstat ) { print $res_fh "Rsync Zimbra: Successfully created $backup_dir\n"; } else { print $res_fh "Rsync Zimbra: Some Problem Occurred. Please check.\n"; } # Now that backup is done, start Zimbra my $zmstartstat = system ( "su - zimbra -c '$zimbra/bin/zmcontrol start'" ); if ( $zmstartstat ) { print $res_fh "Starting Zimbra: Some Problem Occurred. Please check.\n"; } else { print $res_fh "Starting Zimbra: Success\n"; } print $res_fh "Zimbra was off-line for: ", time ( ) - $since_epoch, " seconds\n"; # Rotate backups if ( $rotate_bak ) { # should we rotate backups? # get a list of all files from the backup directory opendir ( DIR, $bak_dir ) or die "can't opendir $bak_dir: $!"; while ( defined ( my $filename = readdir ( DIR ) ) ) { # if $filename is . or .. do not remove it if ( $filename !~ /\./ ) { # if this isn't there, you're dead # if $filename is older than $rotation_days then delete it my @filename_parts = split ( "-", $filename ); # to get epoch sec # allowed age of backups my $allowed_age = $since_epoch - ( 60 * 60 * 24 * $rotate_days ); # if the last part of $filename < allowed age if ( ( $filename_parts[6] < $allowed_age ) && ($filename ne "") ) { # delete it my $zmrmtreestat = rmtree ( "$bak_dir/$filename" ); # print the status of removing if ( $zmrmtreestat ) { print $res_fh "Rotating Backup: Removed $bak_dir/$filename\n"; } else { print $res_fh "Rotating Backup: Can't delete $filename\n"; } } } } closedir ( DIR ); } # Send to remote system if ( $send_remote ) { # Backup Zimbra using "rsync" my $rem_rsync_obj = File::Rsync->new ( { 'rsync-path' => $rsync, 'archive' => 1, 'recursive' => 1, 'links' => 1, 'hard-links' => 1, 'keep-dirlinks' => 1, 'perms' => 1, 'owner' => 1, 'group' => 1, 'devices' => 1, 'times' => 1 } ); my $destination = $ssh_server.':'.$remote_path.'/'.$current_time.'-'.$since_epoch; my $zmremrsyncstat = $rem_rsync_obj->exec ( { src => "$backup_dir/", dest => "$destination" } ); if ( $zmremrsyncstat ) { print $res_fh "Remote Rsync: Successfully created $destination\n"; } else { print $res_fh "Remote Rsync: Some Problem Occurred. Please check.\n"; } } print $res_fh "The backup took: ", time ( ) - $since_epoch, " seconds\n"; # Send email report if ( $send_result ) { # send results by email my $mailer = Mail::Mailer->new ( "sendmail" ); $mailer->open( { 'From' => $from_email, 'To' => $to_email, 'Cc' => $cc_email, 'Bcc' => $bcc_email, 'Subject' => 'Result of zimbraColdBackup' } ) or die "Can't open: $!\n"; print $mailer $result; $mailer->close(); } # print results on std output print $result;
A Simple Shell Script Method
The following script can be called from the command line or crontab, and relies only on rsync, tar, and a scriptable ftp client. I used ncftp but you can use others and modify the syntax accordingly. This script was written and tested in Ubuntu 6.06 LTS server. I cannot confirm if it requires any modification to work in other distros but would appreciate feedback if necessary to make it more general.
#!/bin/bash # Zimbra Backup Script # Requires ncftp to run # This script is intended to run from the crontab as root # Free to use and free of any warranty! Daniel W. Martin, 9 Sept 2007 # Live sync before stopping Zimbra to minimize sync time with the services down # Comment out the following line if you want to try single cold-sync only rsync -avHK -e --delete /opt/zimbra/ /backup/zimbra
# Stop Zimbra Services sudo -u zimbra /opt/zimbra/bin/zmcontrol stop sleep 15 # Sync to backup directory rsync -avHK -e --delete /opt/zimbra/ /backup/zimbra # Restart Zimbra Services sudo -u zimbra /opt/zimbra/bin/zmcontrol start # Create archive of backed-up directory for offsite transfer # cd /backup/zimbra tar -zcvf /tmp/mail.backup.gz -C /backup/zimbra . # Transfer file to backup server ncftpput -u <username> -p <password> <ftpserver> /<desired dest. directory> /tmp/mail.backup.gz
One further note: I have observed some odd behavior in this and other scripts that, when run from the command line work flawlessly, but when run from crontab the script may get ahead of itself and, for example, try to ftp the file before tar is done creating it; resulting in a useless backup. Loading the script into crontab with the parameters to create a log file, for example
. /etc/zimbra.backup > /temp/zbackup.log 2>&1
seems to solve this problem (while creating the log, or showing the output on the screen, the script seems to follow the sequence more carefully), while giving you a line-by-line record of the backup procedure. In my installation with just over 3GB backed up, the logfile is 2.5 mb and is overwritten each night.
NB You may find that using sudo on your operating system has problems and some services don't start correctly. If that's the case use 'su -' in the following format for the commands:
su - zimbra -c "zmcontrol start"
Emergency Repairs
Preparing to Back Up
Before we begin, make sure that you are logged in as a user that can perform the tasks outlined here.
It is always good practice to backup your copy of Zimbra in the event of unforeseen circumstances.
To prevent changes to any Zimbra databases during the backup processes you may wish to use:
>su zimbra
>zmcontrol stop
to terminate Zimbra.
If you get some kind of error, you may want to make sure that Zimbra has completly stopped by running:
>ps auxww | grep zimbra
and kill any left over processes such as the log.
Alternatively as root you could run the following command to kill all Zimbra user owned processes instantly (use wisely):
>ps auxww | awk '{print $1" "$2}' | grep zimbra | kill -9 `awk '{print $2}'`
Backing Up
Make sure that the copy location has enough space to support your backup copy (i.e. the /tmp folder probably isn't the best location).
Since all of the components Zimbra needs are stored in the Zimbra folder itself, you can simply copy the folder to a safe location.
It may be possible to create a cron job to do these tasks automatically.
Copy Command: cp -rp /opt/zimbra [location path]
Depending on your hardware and the amount of data contained in your Zimbra installation, this process can take a while.
Note: It is a very good idea to tag your installation with the version/build of zimbra that will be backed up (ie 3.0.0_GA_156) and the date of backup. You'll need this later.
Restoring
Before restoring, you should make sure that all of the processes accociated with the damaged/failed Zimbra installation are terminated. Failure to terminate all of the processes could have dire consquences. See "Preparing to Backup" for additional info.
====Rename your "broken" Zimbra installation.'
You may be able to scavenge data, if needed. If you simply do not want the old data, you can skip this part.
>[insert command for renaming here]
You may want to move it completly out of the /opt folder just to be safe.
Copy your backup Zimbra installation to the /opt folder and name it "zimbra".
>cp -rp [location of backup] /opt
>[insert command for renaming here]
Restore to Existing/Backup Zimbra Server
In the event of a failure, you can either restore your /opt/zimbra folder to a server that is not currently running Zimbra and download a dummy copy of Zimbra and run an upgrade in order to clean everything up and make it run correctly again (see next section), or you may restore the backup to an existing Zimbra server. This will only work if the existing server is running the EXACT SAME VERSION of Zimbra as the backup you want to restore. Also, this has been tested and seems to work well with CE 4.5.8, but did not work with 4.5.7. This may be, for example, a backup email server that you want to always keep current with last night's backup, so it can replace the production server on short notice in the event of a disaster.
Simply set up your backup server identical to your production server (preferably the same OS, but necessarily the exact same version of Zimbra). Any modifications you made or packages you added for your production server with regards to extra anti-spam protection, etc., should also be added to this server. Shut down Zimbra on the backup server. Copy /opt/zimbra from your backup to the backup server.
chown -R zimbra:zimbra /opt/zimbra /opt/zimbra/libexec/zmfixperms
Start Zimbra. Everything should work. The advantage to this method is that you can retain all your customizations (anti-spam modifications, for example) that would otherwise have been lost in the "upgrade" method. Also, this allows you to use a script to keep a backup server current without having to reinstall Zimbra after each time the backup server is made current, or before putting the backup server into production in the event of a failure.
Downloading a Dummy Copy of Zimbra
Now, we need to know what build/version of zimbra you were running. If you followed the backup instructions above, then the backup folder should be tagged with the version/build you have backed up.
You need to download the full install of the Zimbra version you were running. You may find all Zimbra releases at: Sourceforge.
If you don't know your version number, you can find it by:
Method 1 - view install_history file.
cat /opt/zimbra/.install_history
Method 2 - dont think this will work unless you did a bunch of chroots.
zmcontrol -v
Both of the above listed methods were from this forum post
Installing the Dummy Copy of Zimbra
Once you have downloaded the tar file, you will need to uncompress it by:
>tar -xvzf [name of file].tgz
This will create a folder in the directory named "zcs", cd to it and run the install script:
>cd zcs
>./install.sh
WARNING: Do not run the script with the -u option. You will remove all of your backup data & you must run the script as root, NOT ZIMBRA.
The script will remove the existing packages, and install them again. The script will attempt to stop Zimbra Services and "UPGRADE FAILED - exiting". This is okay, simply rerun the script, and it will install normally.
If you experence error 389, -1, connection refused errors, please search the Forums. These errors are covered extensivly.
Resetting Permissions
If you are up and running now, you may have one more hurdle to overcome: permissions.
You may need to reset the permissions on the message store by running the following:
>/opt/zimbra/libexec/zmfixperms
This is potentially a dangerous suggestion, but if you have trouble getting tomcat to start even after you run zmfixperms, try running (worked for ZCS 4.5.7 CE)
chown -R zimbra:zimbra /opt/zimbra
Of course, you must run
/opt/zimbra/libexec/zmfixperms
again after that. It appears that zmfixperms is supposed to chown zimbra:zimbra on something, but it misses it. This way, you chown EVERYTHING zimbra:zimbra, and zmfixperms puts back things that need to be owned as root, postfix, etc.