Скрипт архивации пользовательских данных: есть многоофисная сеть (звезда) с разными каналами. Скрипт, запускается с компьютера в центральном офисе, по rsync получает измененные данные с серверов (Windows) в удаленных офисах, посредством zfs через снапшоты получается глубина архива, на пуле куда все это хозяйство льется включено сжатие и дедупликация.
Т.к. при дедупликации zfs делает хэши для каждого блока, а хранятся хэши в озу, то при включении такого режима просчитайте необходимый объем озу. Если объем небольшой - выставите меньшее значение глубины архива.
стартующий скрипт
Код: Выделить всё
cat start.sh
#!/bin/sh
log="/var/log/rsync/rsync-all.log"
config="/usr/local/etc/rsyncd/servers"
zfs_backup="zfsstripe/backup"
rootdir="/data/stripe/backup"
script_name="/usr/local/etc/rsyncd/sync.sh"
# Глубина архива 31 день
count_backup="32"
echo="/bin/echo"
date="/bin/date"
ping="/sbin/ping"
rsync="/usr/local/bin/rsync"
mkdir="/bin/mkdir"
touch="/usr/bin/touch"
rm="/bin/rm"
awk="/usr/bin/awk"
df="/bin/df -k"
zfs="/sbin/zfs"
head="/usr/bin/head"
du="/usr/bin/du -k"
wc="/usr/bin/wc"
#удаляем старый и создаем новый файл лога
$rm $log
$touch $log
$echo "`$date +%F_%H-%M-%S` Start backup" >> $log
# Получаем объем свободного места в разделе куда льется бэкап
free="`$df | grep $zfs_backup | $awk '{print $4}'`"
$echo "Free space partition $zfs_backup=`expr $free / 1048576` Gb" >> $log
# Получаем объем каталога с бэкапом
# Использую получение размера backup_size через показания df,
# т.к. du занимает много времени.
#backup_size="`$du -s $rootdir | $awk '{print $1}'`"
backup_size="`$df | grep $zfs_backup | $awk '{print $3}'`"
$echo "Backup space=`expr $backup_size / 1048576` Gb" >> $log
let bk=$backup_size*2
#Если объем свободного места меньше чем 2-х кратный объем бэкапа
#удаляем старые снапшоты
while [ $free -le $bk ]
do
last_date="`$zfs list -t snapshot | grep $zfs_backup| $awk -F@ '{print($2)}' | $awk '{print($1)}' | $head -n 1`"
$echo "No free space" >> $log
$echo "List snapshots:"
$zfs list -t snapshot >> $log
$echo "Delete the oldest snapshot $last_date" >> $log
$zfs destroy $zfs_backup@$last_date
done
# Подсчитываем глубину архива и удаляем старые снапшоты
# глубина архива задается в count_backup
k=`$zfs list -t snapshot |$wc -l`
while [$k -ge $count_backup ]
do
last_date="`$zfs list -t snapshot | grep $zfs_backup| $awk -F@ '{print($2)}' | $awk '{print($1)}' | $head -n 1`"
$echo "Delete the oldest snapshot $last_date" >> $log
$zfs destroy $zfs_backup@$last_date
k=`$zfs list -t snapshot |$wc -l`
done
$echo "===================================================================" >> $log
while read server dir speed
do
#проверяем доступность IP сервера по пингу
$ping -q -c 4 $server > /dev/null 2>&1
if [ $? -eq 0 ]; then
$echo "`$date +%F_%H-%M-%S` Server $server ping=OK" >> $log
else
$echo "`$date +%F_%H-%M-%S` WARNING!!!!! Server $server down" >> $log
exit 0;
fi
# Удаляем старые логи
$rm /var/log/rsync/rsync-$dir.log
$touch /var/log/rsync/rsync-$dir.log
#создаем каталог куда будет писать rsync
k="$rootdir/$dir/profiles"
$mkdir -p $k
#высчитываем лимит скорости для rsync, оставляем 20KBs для остального трафика
let b=$speed/8-20
sh ${script_name} $server $dir $b /var/log/rsync/rsync-$dir.log $rootdir/$dir/profiles profiles >> log 2>&1 &
if [ ${dir} = 'cp' ]; then
k="$rootdir/$dir/private"
$mkdir -p $k
sh ${script_name} $server $dir $b /var/log/rsync/rsync-$dir.log $rootdir/$dir/private private>> log 2>&1 &
fi
done < $config
$echo "===================================================================" >> $log
файл с именями серверов, название папки куда лить с данного сервера данные и скорость с которой rsync будет сливать данные с этого сервера.
Код: Выделить всё
cat servers
exvs-pnz-fl-th1 cp 102400000
exvs-pnz-fl-ar1 ar 2048
exvs-pnz-fl-sr1 sr 4096
exvs-pnz-fl-pr1 pr 2048
exvs-pnz-fl-vl2 vl 2048
exvs-pnz-fl-tr1 tr 2048
exvs-pnz-fl-yp2 yp 4096
exvs-pnz-fl-kz1 kz 2048
exvs-pnz-fl-nk1 nk 2048
exvs-pnz-fl-km1 km 1024
exvs-pnz-fl-sd1 sd 1024
exvs-pnz-fl-nl1 nl 1024
exvs-pnz-fl-zr1 zr 2048
скрипт вызова rsync
Код: Выделить всё
cat sync.sh
#!/bin/sh
#
rsync="/usr/local/bin/rsync"
echo="/bin/echo"
server=$1
dir=$2
speed=$3
log=$4
localdir=$5
source=$6
k="$rsync --archive --exclude-from=/usr/local/etc/rsyncd/exclude.txt --time-limit=600 --bwlimit=$speed --compress-level=9 --delete-after --quiet --8-bit-output $server::$source $localdir"
$echo "Start command $k" >> $log
$k >> $log 2>&1
скрипт для составления отчета и отсылки его админам
Код: Выделить всё
cat report.sh
#!/bin/sh
#
date="/bin/date"
config="/usr/local/etc/rsyncd/servers"
report="/var/log/rsync/report-`$date +%F`"
mail_to="admin@domain.local"
start_log="/var/log/rsync/rsync-all.log"
zfs_backup="zfsstripe/backup"
backup_patch="/data/stripe/backup"
mail="/usr/bin/mail"
touch="/usr/bin/touch"
rm="/bin/rm"
cat="/bin/cat"
echo="/bin/echo"
df="/bin/df"
zdb="/usr/sbin/zdb"
zpool="/sbin/zpool"
zfs="/sbin/zfs"
# Делаем снапшот.
$zfs snapshot zfsstripe/backup@`$date +%F`
#Формируем файл отчета и сливаем в него лог старта rsync
$touch $report
$echo "`$date +%F_%H-%M-%S` Start reports" >> $report
$cat $start_log>> $report
#Сливаем в файл отчета лог rsync по каждому серверу
while read server dir speed
do
$echo "Server $server"
$cat "/var/log/rsync/rsync-$dir.log" >> $report
done < $config
$zfs list -t snapshot >> $report
$zdb -DD zfsstripe >> $report
$zpool status -v >> $report
$df -h >> $report
$echo "`$date +%F_%H-%M-%S` Stop reports" >> $report
#Отсылаем репорт на почту
#$cat $report | /usr/local/bin/iconv -f UTF-8 -t MS-CYRL | $mail -s "Rsync report" $mail_to
$cat $report | $mail -s "Rsync report" $mail_to
каталог с пользовательскими данными (по состоянию на прошедшую ночь) расшарен для группы админов, с ведением лога кто куда... через самбу. Для получения данных из снапшота нужно с консоли выполнить mount -t zfs zfsstripe/backup@2013-05-27 /mnt.
Не хватает знаний для прикручевания к этому хозяйству веб интерфейса с контролем доступа.