LVM Snapshots rotate scripts
snapstats
#!/bin/sh
lvs -o vg_name,lv_name,lv_size,snap_percent
snapshots
#!/bin/bash
# $Id: snapshots,v 1.3 2011-04-09 15:18:24 cbellot Exp $
export PATH=$PATH:/sbin
# rotate function
function rotate() {
name=$1
nb=`printf "%.02d" $2`
# List of LV for that name
lvdisplay -C 2>/dev/null|grep "$name"|awk '{print $1}'>/tmp/snapshots.tmp
# If a LV named LV-snapNB-hour exists, we remove it
for last in `grep $name$nb- /tmp/snapshots.tmp`
do
if [ "$last" != "" ]
then
if [ "$debug" = "1" ]
then
echo "DEBUG: lvremove -f $VG/$last"
else
if lvremove -f $VG/$last >/dev/null 2>&1
then
logger -p local1.info "lvmsnapshot($$) Removing $last: OK"
else
logger -p local1.info "lvmsnapshot($$) Removing $last: ERROR"
fi
fi
fi
done
# For all the others
nb=`expr $nb - 1`
nb=`printf "%.02d" $nb`
while [ $nb != 00 ]
do
nnb=`expr $nb + 1`
nnb=`printf "%.02d" $nnb`
# Is there a LV named LV-snap[hd]-$nb ?
if grep -q $name$nb- /tmp/snapshots.tmp
then
for cur in `grep $name$nb- /tmp/snapshots.tmp`
do
if [ "$cur" != "" ]
then
# We rename it with NB-1
lasth=${cur##*-}
new=$name$nnb-$lasth
if [ "$debug" = "1" ]
then
echo "DEBUG: lvrename $VG $cur $new"
else
if lvrename $VG $cur $new >/dev/null 2>&1
then
logger -p local1.info "lvmsnapshot($$) Renaming $cur to $new : OK"
else
logger -p local1.info "lvmsnapshot($$) Renaming $cur to $new : ERROR"
fi
fi
fi
done
fi
nb=`expr $nb - 1`
nb=`printf "%.02d" $nb`
done
}
# snap function
function snap() {
name=$1
size=$2
date=``
if [ "$debug" = "1" ]
then
echo "DEBUG: lvcreate --size $size --snapshot --name $name $VG/$LV"
else
if lvcreate --size $size --snapshot --name $name $VG/$LV >/dev/null 2>&1
then
logger -p local1.info "lvmsnapshot($$) Snapshoting to $name: OK"
else
logger -p local1.info "lvmsnapshot($$) Snapshoting to $name: ERROR"
fi
fi
}
# Args
MAX=$2
VG=$3
LV=$4
SNAPSIZE=$5
if [ "$2" = "" ] || [ "$3" = "" ] || [ "$4" = "" ] || [ "$5" = "" ]
then
exit 1
fi
if [ "$6" = "DEBUG" ]
then
debug=1
fi
# Mode (hourly/daily)
case $1 in
hourly)
hour=$(date +%H)h
logger -p local1.info "lvmsnapshot($$) RUNNING IN $1 MODE; $VG $LV, $MAX, $SNAPSIZE $6"
rotate $LV-snaph $MAX
snap $LV-snaph01-$hour $SNAPSIZE
logger -p local1.info "lvmsnapshot($$) DONE"
;;
daily)
day=$(date +%a)
logger -p local1.info "lvmsnapshot($$) RUNNING IN $1 MODE; $VG $LV, $MAX, $SNAPSIZE $6"
rotate $LV-snapd $MAX
snap $LV-snapd01-$day $SNAPSIZE
logger -p local1.info "lvmsnapshot($$) DONE"
;;
weekly)
week=$(date +%U)
logger -p local1.info "lvmsnapshot($$) RUNNING IN $1 MODE; $VG $LV, $MAX, $SNAPSIZE $6"
rotate $LV-snapw $MAX
snap $LV-snapw01-w$week $SNAPSIZE
logger -p local1.info "lvmsnapshot($$) DONE"
;;
*)
exit 1
;;
esac
snapshots-expand
#!/bin/bash
# $Id: snapshots-expand,v 1.2 2011-04-09 15:18:24 cbellot Exp $
# Expand snapshots size if they reach a limit
export PATH=/sbin:/usr/sbin:$PATH
lvdisplay -C 2>/dev/null | grep -v "^ LV" | while read line
do
cur=`echo $line|awk '{print $1}'`
VG=`echo $line|awk '{print $2}'`
cursize=`echo $line|awk '{printf("%d",$4)}'`
curunit=`echo $line|awk '{printf(substr($4,length($4),1))}'`
curusage=`echo $line|awk '{printf("%d",$6)}'`
#echo "$cur $curusage% ($cursize$curunit)"
if [ $curusage -gt 85 ] && [ $curusage -lt 100 ]
then
# Expand to 1.2*size
newsize=`expr $cursize \* 120 / 100`
#echo " resize to : $newsize$curunit"
if lvresize $VG/$cur -L $newsize$curunit >/dev/null 2>&1
then
logger -p local1.info "snapshot-expand($$) Expanding $cur from $cursize to $newsize : OK"
else
logger -p local1.info "snapshot-expand($$) Expanding $cur from $cursize to $newsize : ERROR"
fi
fi
if [ $curusage -eq 100 ]
then
if lvremove -f $VG/$cur >/dev/null 2>&1
then
logger -p local1.info "snapshot-expand($$) Removing $cur (Full) : OK"
else
logger -p local1.info "snapshot-expand($$) Removing $cur (Full) : ERROR"
fi
fi
done
Cron samples
# -- ROOT (system is on LV sys1/root ) --
01 * * * * root /opt/app/bin/snapshots hourly 1 sys1 root 500M
31 4 * * * root /opt/app/bin/snapshots daily 1 sys1 root 800M
31 5 * * 7 root /opt/app/bin/snapshots weekly 1 sys1 root 900M
# -- MAIL (date is on LV data/mail) --
03 * * * * root /opt/app/bin/snapshots hourly 2 data mail 100M
33 4 * * * root /opt/app/bin/snapshots daily 2 data mail 200M
33 5 * * 7 root /opt/app/bin/snapshots weekly 2 data mail 200M