View Single Post
  #83 (permalink)  
Old 09-15-2006, 05:00 PM
czaveri czaveri is offline
Former Zimbran
 
Posts: 294
Default Hot backup!?

... ideas on this script (zimbraBackup.pl) or this method? It's an outcome of the attempts to learn Perl, and evaluation of Zimbra and my first Trac installation and Open Source ...

I haven't experimented with it yet and it might just blow out anything/everything/nothing... or might work!?

Code:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX;

###########################################################################
# Program Name: zimbraBackup v0.01                                        #
#                                                                         #
# This script can be used to backup, individually, all accounts in the    #
# Zimbra Collaboration Suite 4.0.0 GA                                     #
#                                                                         #
# 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.             #
###########################################################################

#################### CHANGE THE VARIABLES BELOW THIS!! ####################

# Change this to the correct admin password. This is the password used by you to enter the Admin section.
my $admin_password = 'youradminpassword';

# Auth method (http/https)
my $auth_method = 'http';

# Change this to the correct port number on which Zimbra is accessible
my $zimbra_port = "80";

# Change this path to your backup directory. Enter Only Absolute Path else unexpected things may happen.
my $backup_directory = '/backup';

# Change this path to the one for mysqldump. Enter Only Absolute Path else unexpected things may happen.
my $mysqldump = '/usr/bin/mysqldump';

# Change this path to the one for rsync. Enter Only Absolute Path else unexpected things may happen.
my $rsync = '/usr/bin/rsync';

# Change this path to one for wget. Enter Only Absolute Path else unexpected things may happen.
my $wget = '/usr/bin/wget';

#################### DON'T CHANGE ANYTHING BELOW THIS! ####################

# Current date and time
my $current_time = POSIX::strftime('%A-%B-%d-%Y-%H-%M', localtime(time));

# Get hostname
my $hostname = `hostname`;
chop($hostname);

# Get all accounts
my $all_accounts = `/opt/zimbra/bin/zmprov gaa`;
chop($all_accounts);
my @all_accounts = split("\n",$all_accounts);

# MySQL root user
my $mysql_root_user = 'root';

# Get password for MySQL root user
my $mysql_root_password = `/opt/zimbra/bin/zmlocalconfig -s | grep mysql_root_password`;
chop($mysql_root_password);
$mysql_root_password =~ s/mysql_root_password = //;

# Setting up backup directories
if (!(-e $backup_directory)) {
        mkdir($backup_directory, 0755) || die "Cannot create directory $backup_directory : $!";
}

if (!(-e "$backup_directory/$current_time")) {
        mkdir("$backup_directory/$current_time", 0755) || die "Cannot create directory $backup_directory/$current_time : $!";
}

if (!(-e "$backup_directory/$current_time/mysql")) {
        mkdir("$backup_directory/$current_time/mysql", 0755) || die "Cannot create directory $backup_directory/$current_time/mysql : $!";
}

if (!(-e "$backup_directory/$current_time/store")) {
        mkdir("$backup_directory/$current_time/store", 0755) || die "Cannot create directory $backup_directory/$current_time/store : $!";
}

if (!(-e "$backup_directory/$current_time/index")) {
        mkdir("$backup_directory/$current_time/index", 0755) || die "Cannot create directory $backup_directory/$current_time/index : $!";
}

if (!(-e "$backup_directory/$current_time/wget")) {
        mkdir("$backup_directory/$current_time/wget", 0755) || die "Cannot create directory $backup_directory/$current_time/wget : $!";
}

# Backup every account
foreach my $account (@all_accounts) {
        if ($account) { # Backup only if $account is not empty, that is, it should contain an e-mail address
                # Get mailbox Id
                my $id = `/opt/zimbra/bin/zmprov gmi $account | grep mailboxId`;
                chop($id); # remove trailing 0
                $id =~ s/mailboxId: //; # remove the term "mailboxId: " from the line and leave only the actual mailbox id

                # Get quota Used
                my $used = `/opt/zimbra/bin/zmprov gmi $account | grep quotaUsed`;
                chop($used); # remove trailing 0
                $used =~ s/quotaUsed: //; # remove the term "quotaUsed: " from the line and leave only the actual quota used

                if ($used) { # Only if there is anything in the account, backup, else don't
                        # Put the account in Maintenance Mode
                        exec ("/opt/zimbra/bin/zmprov ma $account zimbraAccountStatus maintenance");

                        # Use "mysqldump" to backup mailbox database corresponding to the id
                        exec ("$mysqldump --port=7306 --socket=/opt/zimbra/db/mysql.sock --user=$mysql_root_user --password=$mysql_root_password mailbox$id > $backup_directory/$current_time/mysql/$account.mailbox$id.sql");

                        # Use "rsync" to backup "/opt/zimbra/store/0/5" directory where '5' is the mailbox Id
                        exec ("$rsync -avrlHKpogDt /opt/zimbra/store/0/$id/ $backup_directory/$current_time/store/$account.mailbox$id");

                        # Use "rsync" to backup "/opt/zimbra/index/0/5" directory where '5' is the mailbox Id
                        exec ("$rsync -avrlHKpogDt /opt/zimbra/index/0/$id/ $backup_directory/$current_time/index/$account.mailbox$id");

                        # Use "wget" to backup all contacts from the REST URL "http://server/zimbra/home/user@domain.com/contacts.csv"
                        if (($zimbra_port == 80) || ($zimbra_port == 443)) {
                        exec ("cd $backup_directory/$current_time/wget/ && $wget --user admin\@$hostname --password $admin_password $auth_method://$hostname/zimbra/home/$account/contacts.csv");
                        } else {
                        exec ("cd $backup_directory/$current_time/wget/ && $wget --user admin\@$hostname --password $admin_password $auth_method://$hostname:$zimbra_port/zimbra/home/$account/contacts.csv");
                        }

                        # Use "wget" to backup all appointments from the REST URL "http://server/zimbra/home/user@domain.com/calendar.ics"
                        if (($zimbra_port == 80) || ($zimbra_port == 443)) {
                        exec ("cd $backup_directory/$current_time/wget/ && $wget --user admin\@$hostname --password $admin_password $auth_method://$hostname/zimbra/home/$account/calendar.ics");
                        } else {
                        exec ("cd $backup_directory/$current_time/wget/ && $wget --user admin\@$hostname --password $admin_password $auth_method://$hostname:$zimbra_port/zimbra/home/$account/calendar.ics");
                        }

                        # Remove the account from Maintenance Mode and make it Active
                        exec ("/opt/zimbra/bin/zmprov ma $account zimbraAccountStatus active");
                }
        }
}
=> A SAMPLE BACKUP STRATEGY FOR ZCS 4.0.0 GA <=
SAVE THE ZCS BINARY
The first step is to save the ZCS binary, you used to install or upgrade Zimbra, in a safe place.

COLD OR OFF-LINE BACKUP
Now, do a "cold" or "off-line" backup of Zimbra, following the following steps:
1) su - zimbra
2) zmcontrol stop
3) exit
4) kill -9 `ps -U zimbra|grep [0-9]|awk '{print $1}'` > /dev/null
4) rsync -avrlHKpogDt /opt/zimbra/ /backup/zimbra_cold
5) su - zimbra
6) zmcontrol start

Schedule weekly cold-backups.

HOT BACKUP
After doing the cold backup, put the "zimbraBackup.pl" as a cron job scheduled every 12 or 24 hours. (Please edit it to suit your preferred paths before assigning to cron)

Advice: If you don't frequently add new accounts (less than twice a week), you must do the cold backup every time you add new account(s).

This way, at any point of time, we have full ZCS backup, and, we have copies of individual accounts' daily backups. In short, in case of any failure, you will have close to all data in ZCS.

Limitation: Even if you follow this strategy you may lose upto 12 or 24 hours of data depending upon when the last hot backup was taken.

=> A SAMPLE RESTORE PLAN FOR ZCS 4.0.0 GA <=
To Restore the system, follow the following steps:

1. If your system was not formatted you must uninstall ZCS first. Use the stored ZCS binary for this. If your system was formatted, you don't need to uninstall ZCS, because it is not there.
2. Do a fresh install of Zimbra using this binary
3. Move the "/opt/zimbra" directory to some other place (temporarily and after all's well - delete it!)
4. Move the last Cold backup to "/opt/zimbra"
5. Restore the last Hot Backup created by "zimbraBackup.pl" using standard tools, such as, mysql, mv, cp, rm, ... etc.
6. Check how much you lost!
7. Done!
__________________
Regards,

Chintan Zaveri
(Yet another ZIMBRAN!)

"Dhundhne par Bhagwan bhi ..."
Reply With Quote