Date: March 8, 2002
Audience Systems Administrators, DBA's.
One use for "split mirror copy" is to quickly move large amounts of data between systems on a SSA loop, SAN or equivalent. You simply vary off the volume group containing the copy and vary it on another server. It avoids the congesting the network with large file transfers, and the procedure takes only minutes.
The attached "splitmirrorvg" shell script automates the split mirror copy process. The split copy is placed into a new volume group, which can then be exported/imported onto another system on the same SSA loop or SAN.
The script illustrates many useful AIX LVM commands. It's worth a look even if you don't have a need for split mirror copy.
Acknowledgement: Thanks to Dan Braden for the shell script.
Steps: 1. create VG mkvg -y-s mkvg -f -y'splitmirrorvg' -s'8' hdisk13 hdisk14 hdisk 15 hdisk17 hdisk18 hdisk19 hdisk20 hdisk21 2. Create LV (original copy) mklv -y -e x -w n mklv -y'lvnum1' -e'x' -w'n' splitmirrorvg 18 hdisk16 hdisk17 hdisk18 3. Create first copy of LV mklvcopy 2 mklvcopy lvnum1 2 hdisk19 hdisk20 hdisk21 4. Create second copy of LV mklvcopy 3 mklvcopy lvnum1 3 hdisk13 hdisk14 hdisk15 5. List out LV map root@f1n3 > lslv -m lvnum1 lvnum1:N/A LP PP1 PV1 PP2 PV2 PP3 PV3 0001 0109 hdisk16 0109 hdisk19 0109 hdisk15 0002 0109 hdisk17 0055 hdisk20 0055 hdisk14 0003 0109 hdisk18 0055 hdisk21 0055 hdisk13 0004 0110 hdisk16 0110 hdisk19 0110 hdisk15 0005 0110 hdisk17 0056 hdisk20 0056 hdisk14 0006 0110 hdisk18 0056 hdisk21 0056 hdisk13 0007 0111 hdisk16 0111 hdisk19 0111 hdisk15 0008 0111 hdisk17 0057 hdisk20 0057 hdisk14 0009 0111 hdisk18 0057 hdisk21 0057 hdisk13 0010 0112 hdisk16 0112 hdisk19 0112 hdisk15 0011 0112 hdisk17 0058 hdisk20 0058 hdisk14 0012 0112 hdisk18 0058 hdisk21 0058 hdisk13 0013 0113 hdisk16 0113 hdisk19 0113 hdisk15 0014 0113 hdisk17 0059 hdisk20 0059 hdisk14 0015 0113 hdisk18 0059 hdisk21 0059 hdisk13 0016 0114 hdisk16 0114 hdisk19 0114 hdisk15 0017 0114 hdisk17 0060 hdisk20 0060 hdisk14 0018 0114 hdisk18 0060 hdisk21 0060 hdisk13 6. Create a filesystem for testing (for raw LVs this wouldn't be necessary) crfs -v jfs -d lvnum1 -m /tmp/fs -A yes Note that this creates a jfslog LV which we also need to mirror 7. Mirror the jfslog to (which will also be split later) mklvcopy loglv00 3 hdisk16 hdisk13 root@f1n3 > lslv -m loglv00 loglv00:N/A LP PP1 PV1 PP2 PV2 PP3 PV3 0001 0121 hdisk19 0115 hdisk16 0061 hdisk13 8. Mount the FS and put some data in there for testing # mount /tmp/fs # cd /tmp/fs # cp -R /etc/ . 9. Unmount the filesystem (i.e. stop I/O) # umount /tmp/fs 10. Split off a copy of the LVs (use hdisk13 so the split LVs are on the same set of hdisks) splitlvcopy -y lvnum2 lvnum1 2 hdisk13 (for the filesystem LV) splitlvcopy -y newloglv00 loglv00 2 hdisk13 (for the jfslog LV) root@f1n3> lslv -m lvnum2 lvnum2:N/A LP PP1 PV1 PP2 PV2 PP3 PV3 0001 0109 hdisk15 0002 0055 hdisk14 0003 0055 hdisk13 0004 0110 hdisk15 0005 0056 hdisk14 0006 0056 hdisk13 0007 0111 hdisk15 0008 0057 hdisk14 0009 0057 hdisk13 0010 0112 hdisk15 0011 0058 hdisk14 0012 0058 hdisk13 0013 0113 hdisk15 0014 0059 hdisk14 0015 0059 hdisk13 0016 0114 hdisk15 0017 0060 hdisk14 0018 0060 hdisk13 root@f1n3> lslv -m newloglv00 newloglv00:N/A LP PP1 PV1 PP2 PV2 PP3 PV3 0001 0061 hdisk13 11. Mount the original LV # mount /tmp/fs 12. Save the LV maps for newloglv00 and lonum2 Using the reformatmap script: #!/bin/ksh # reformap - script to take an LV and get it's map and create a map # that can be used by mklv # input is an LV name, output is a file of name $lvmap lv=$1 cat /dev/null > ${lv}map lslv -m $lv | grep -v ^$lv | grep -v ^LP | while read lpnum ppnum pv do echo ${pv}:$ppnum >> ${lv}map done # reformatmap lvnum2 # reformatmap newloglv00 root@f1n3 > pg lvnum2map hdisk15:0109 hdisk14:0055 hdisk13:0055 hdisk15:0110 hdisk14:0056 hdisk13:0056 hdisk15:0111 hdisk14:0057 hdisk13:0057 hdisk15:0112 hdisk14:0058 hdisk13:0058 hdisk15:0113 hdisk14:0059 hdisk13:0059 hdisk15:0114 hdisk14:0060 hdisk13:0060 root@f1n3.dsc.ibm.com (/tmp) > cat newloglv00map hdisk13:0061 13. Add entry to /etc/filesystems for new filesystem /tmp/newfs: dev = /dev/lvnum2 vfs = jfs log = /dev/newloglv00 mount = false options = rw account = false 14. Mount it and see if the data is there (make sure new mount point is there first) # mkdir /tmp/newfs # mount /tmp/newfs # find /tmp/newfs -print 15. Unmount the filesystem and remove the new LVs in preparation for creating them in a new VG on hdisk13, hdisk14 and hdisk15 Unmount # umount /tmp/newfs Remove the LVs # rmlv -f lvnum2 # rmlv -f newloglv00 16. Remove the disks from the VG Remove the disks from the VG # reducevg splitmirrorvg hdisk13 hdisk14 hdisk15 17. Create a new VG with the same partition size # mkvg -y newvg -s 8 hdisk13 hdisk14 hdisk15 18. Make the LVs using the maps we saved earlier mklv -y lvnum2 -m lvnum2map newvg 18 mklv -y newloglv00 -m newloglv00map newvg 1 Note that we used the same LVname (lvnum2) and the number of LPs (18) One can get the number of LPs from the following command: # lslv | grep ^LPs | awk '{print $2}' We also used the same LVname for the jfslog, the mount point doesn't change 19. Mount the filesystem and check it out # mount /tmp/newfs # find /tmp/newfs -print At this time, one could varyoff the VG, then import it on another machine connected to the disk.
#!/bin/ksh # splitmirrorvg # Use this script to split off a mirror copy containing all LVs in a VG. # The split off copy is placed into a new VG so that the data can be # exported/imported into another system. # # Usage: splitmirrorvg# where the listed hdisks are a set of disks that have one copy of the LVs on # them and will be put into another VG # # The new VG and LVs will be preceded by the prefix mir to # designate that it is a mirrored VG/LV. Mount points will be # . # # NOTE: NO CHECKING OF THE SETUP IS DONE. IT IS ASSUMED THAT YOUR VG IS SETUP # AND MIRRORED CORRECTLY USING SUPER STRICT COPIES (I.E. EACH COPY OF THE LVS # ARE ON DISTINCT SETS OF DISKS), and that your input is correct. # This also assumes you have 3 copies of the LVs - it won't work for 2 # This also assumes any JFS log you have is of type "jfslog" # This also assumes the VG is synced # Your LV and VG names should not exceed 12 characters # # Standard Disclaimers: backup your data, test first on a development system. #--------------------------------------------- # "Are you sure" warning message # You can erase this section between the lines tput clear echo $0 ":This script splits off the LVs in the mirror copy on " $@ echo "into a new volume group." echo "*** Caution *** This script assumes your VG is setup and mirrored " echo "correctly. See comments in this script." echo "\nContinue? (yes/no)" read if [[ ! $REPLY = yes ]] then echo "Exiting" exit fi #-------------------------------------------- # Get a list of LV, mountpoint, #LPs, and hdisk and put them in a file cat /dev/null > /tmp/splitlvdata # First get a list of the LVs in the VG lvs=`lsvg -l $1 | tail -n +3 | awk '{print $1}'` # Now we loop on the LVs for lv in ${lvs} do # determine the mount point if any associated with the LV mountpt=`lslv $lv | grep "MOUNT" | awk '{print $3}'` # Determine the number of LPs lps=`lslv $lv | grep ^LPs | awk '{print $2}'` # Determine one of the input hdisks on which the copy exists for disk in $@ do if [ "$disk" = "$1" ] then continue fi lspv -l $disk | grep ^$lv > /dev/null if [ "$?" = "0" ] then { hdisk=$disk break } fi done echo "$lv $mountpt $lps $hdisk" >> /tmp/splitlvdata done # Now for each LV, we unmount it first print "Starting to umount the filesystems" for lv in ${lvs} do # Do the umount only if it is a filesystem fs=`grep ^$lv /tmp/splitlvdata | cut -f2 -d" "` if [ "$fs" != "N/A" ] then { # Check to see if it is mounted first mount | grep " /dev/$lv " > /dev/null if [ "$?" = "0" ] then { umount $fs if [ "$?" != "0" ] then { print "Error unmounting $fs - script stopping" exit 99 } fi } fi } fi done # Now for each LV, we split it print "Starting to split the LVs" for lv in ${lvs} do hdisk=`grep ^$lv /tmp/splitlvdata | cut -f4 -d" "` splitlvcopy -y mir${lv} $lv 2 $hdisk done # Now we mount the original filesystems and assure the new mount point exists for lv in ${lvs} do mountpt=`grep ^$lv /tmp/splitlvdata | cut -f2 -d" "` if [ "$mountpt" != "N/A" ] then mount $mountpt mkdir $mountpt/mir fi done print "Application can be restarted now!" # Now we update /etc/filesystems print "Starting to update /etc/filesystems" # To do this first we need to know which is the JFS log lsvg -l $1| grep jfslog > /dev/null if [ "$?" = "0" ] then log=`lsvg -l $1 | grep jfslog | cut -f1 -d" "` fi for lv in ${lvs} do # is this lv a filesystem? mountpt=`grep ^$lv /tmp/splitlvdata | cut -f2 -d" "`/mir if [ "$mountpt" != "N/A/mir" ] then { echo " " >> /etc/filesystems echo "$mountpt:" >> /etc/filesystems echo " dev = /dev/mir${lv}" >> /etc/filesystems echo " vfs = jfs" >> /etc/filesystems echo " log = /dev/mir${log}" >> /etc/filesystems echo " mount = false" >> /etc/filesystems echo " options = rw" >> /etc/filesystems echo " account = false" >> /etc/filesystems } fi done # Now make map files for the LVs print "Starting to make map files" for lv in ${lvs} do cat /dev/null > /tmp/mir${lv}map lslv -m mir$lv | grep -v ^mir$lv: | grep -v ^LP | while read lpnum ppnum pv do echo ${pv}:$ppnum >> /tmp/mir${lv}map done done # Now remove the mirLVs print "Removing the split LVs" for lv in ${lvs} do rmlv -f mir$lv done # Now remove the input disks from the VG print "Removing the disks from the VG" disks=`echo $@ | cut -f 2- -d" "` reducevg $1 $disks # Now create the newVG print "Starting to make the new VG" # First we need the old partition size ppsize=`lsvg $1 | grep "PP SIZE" | awk '{print $6}'` mkvg -y mir$1 -s $ppsize $disks # Now create the LVs using the maps for lv in ${lvs} do lps=`grep ^$lv /tmp/splitlvdata | cut -f 3 -d" "1` mklv -y mir$lv -m /tmp/mir${lv}map mir$1 $lps done
Bruce Spencer,
baspence@us.ibm.com