====== Automatically growing LVM partitions as the data in them expands ====== We all know that the IT equivalent of [[https://en.wikipedia.org/wiki/Parkinson's_law|Parkinson's law]] is that data expands to fill slightly more than the space available. I like using [[http://www.sourceware.org/lvm2/|Logical Volume Management]] for data partitions, in order to make efficient use of disk space, with convenient facilities to add another disk, migrate partitions, and adjust the size of partitions as data fills them. I created the following script which can be run from cron (I do it every 5 or 10 minutes) to scan each volume group for logical volumes which are currently mounted, and check how full the (presumed ext2/3/4) contained file system is. If the file system is more than 95% full, the partition and the file system are grown by 10%; if the file system is between 90% and 95% full, they're grown by 5%. Anything under 90% is left as it is. In this way, provided you have sufficient spare capacity in your volume group, you can keep writing data to the file systems in the logical volumes, and never reach 100% with all the inconvenience that entails. This script makes use of the [[.localsshcron|automatic console/SSH/cron detection mechanism]] to determine the default debug level. You can override it by specifying the debug level as the first parameter on the command line. **Note:** This is indeed a very useful automated facility, but just in case something goes ballistic and starts eating up disk space faster than you can keep an eye on it, do bear in mind that once you've sorted out the runaway process and deleted whatever it created, [[.shrinkingext|shrinking]] the file system and its containing partition can take a __very long time__. It works, no problem, but it's __slow__. #!/bin/bash PATH=$PATH:/sbin [ "$TERM" = "dumb" -a ! -t 0 ] && run=cron || run=local [ "`ps --no-headers o comm $PPID`" = "sshd" ] && run=SSH debug=0 [ "$run" = "SSH" ] && debug=1 [ "$run" = "local" ] && debug=2 recipient=username # Add increment1% if we're above threshold1%, but add increment2% if we're above threshold2% full threshold1=85 increment1=5 threshold2=90 increment2=10 [ -n "$1" ] && debug=$1 # Scan for all Volume Groups vgs --noheadings | tr -s ' ' | cut -d' ' -f2 | while read vg do [ "$debug" -gt "0" ] && echo "Checking Volume Group $vg" # Scan for Logical Volumes in each Group lvs --noheadings $vg | tr -s ' ' | cut -d' ' -f2 | while read lv do [ "$debug" -gt "0" ] && echo "Checking Logical Volume $lv" # Check if LV is mounted percent=`df -h | grep "/dev/mapper/$vg-$lv " | sed 's/.* \([0-9]\+\)%.*/\1/'` if [ -n "$percent" ] # Yes we have a mounted LV then [ "$debug" -gt "0" ] && echo "Logical Volume $vg/$lv is mounted and is $percent% full" # Is it more than threshold1% full? if [ "$percent" -gt "$threshold1" ] then # Add increment1% if we're above threshold1%, but add increment2% if we're above threshold2% full incr=$increment1 [ "$percent" -gt "$threshold2" ] && incr=$increment2 if ps ax | grep -v grep | grep -q "resize2fs /dev/mapper/$vg-$lv " then echo "resize operation already running" | mail -s "Would increase /dev/$vg/$lv by $incr%" $recipient else ( time ( df -h | grep "/dev/mapper/$vg-$lv "; echo; lvextend -l +$incr%LV -r /dev/$vg/$lv 2>&1; df -h | grep "/dev/mapper/$vg-$lv "; echo; vgs ) ) |& mail -s "Increasing /dev/$vg/$lv by $incr%" $recipient fi else [ "$debug" -gt "0" ] && echo "Partition is ${percent}% full" | mail -s "/dev/$vg/$lv does not need extending at present." $recipient fi else [ "$debug" -gt "0" ] && echo "Logical Volume $vg/$lv is not mounted" fi done done Substitute the user (or external email address) you want to receive the notification emails for __username__ in the above script. ---- [[.:|Go up]]\\ Return to [[:|main index]].