Difference between revisions of "LVM Fun"
(→Extending the LV and its filesystem) |
(→Extending the LV and its filesystem) |
||
| Line 658: | Line 658: | ||
=== Extending the LV and its filesystem === | === Extending the LV and its filesystem === | ||
| − | Bringing new LV would demonstrate nothing more nevertheless extending our existing LVs is much more interesting. How can we use our 2GB extra space? | + | Bringing new LV would demonstrate nothing more nevertheless extending our existing LVs is much more interesting. How can we use our 2GB extra free space? We can, for example, split it in two allocating a 50% to our first (lvdata01) and third (lvdata03) LV adding 1GB of space to both. The best of the story is that operation is very simple and is realized with a command named '''lvextend''': |
| + | |||
| + | <pre> | ||
| + | # lvextend vgdata/lvdata01 -l +50%FREE | ||
| + | Extending logical volume lvdata01 to 3.00 GiB | ||
| + | Logical volume lvdata01 successfully resized | ||
| + | # lvextend vgdata/lvdata03 -l +50%FREE | ||
| + | Extending logical volume lvdata03 to 1.10 GiB | ||
| + | Logical volume lvdata03 successfully resized | ||
| + | </pre> | ||
== Shrinking a storage space == | == Shrinking a storage space == | ||
Revision as of 20:26, 30 December 2011
Contents |
Introduction
LVM (Logical Volume Management) offers a great flexibility in managing your storage and significantly reduces server downtimes by allowing on-line disk space management: The great idea beneath LVM is to make the data and its storage loosely coupled through several layers of abstraction. You (the system administrator) have the hand of each of those layers making the entire space management process extremely simple and flexible though various set of coherent commands.
Several other well-known binary Linux distributions makes an aggressive use of LVM and several Unices including HP-UX, AIX and Solaris offers since a while a similar functionality modulo the commands to be used. LVM is not mandatory but its usage can bring you additional flexibility and make your everyday life much more simpler.
Concepts
As usual having a good idea of the concepts lying beneath is mandatory. LVM is not very complicated but it is easy to become confused especially because it is multi-layered system, however LVM designers had the good idea of keeping the command names consistent between all LVM command sets making your life easier.
LVM consists of, mainly, three things:
- Physical volumes (or PV): nothing more than a physical storage space. A physical volume can by anything like a partition on a local hard disk, a partition located on a remote SAN disk, a USB key or whatever else that could offer a storage space (so yes, technically it could be possible to use an optical storage device accessed in packet writing mode). The storage space on a physical volumes is divided (and managed) in small units called Physical Extents (or PE). Just to give an analogy if you are a bit familiar with RAID, PE are a bit like RAID stripes.
- Volume Groups (or VG): a group of at least one PV. VG are named entities and will appear in the system via the device mapper as /dev/volume-group-name.
- Logical Volumes (or LV): a named division of a volume group in which a filesystem is created and that can be mounted in the VFS. Just for the record, just as for the PE in PV, a LV is managed as chucks known as Logical Extents (or LE). Most of the time those LE are hidden to the system administrator due to a 1:1 mapping between them and the PE lying be just beneath but a cool fact to know about LEs is that they can be spread over PV just like RAID stripes in a RAID-0 volume. However, researches done on the Web tends to demonstrate system administrators prefer to build RAID volumes with mdadm then use LVM over them for performance reasons.
In short words: LVM logical volumes (LV) are containers that can hold a single filesystem and which are created inside a volume group (VG) itself composed by an aggregation of at least one physical volumes (PV) themselves stored on various media (usb key, harddisk partition and so on). The data is stored in chunks spread over the various PV.
Retain what PV, VG and LV means as we will use those abbreviations in the rest of this article.
Your first tour of LVM
Physical volumes creation
We give the same size to all volumes for the sake of the demonstration. This is not mandatory and be possible to have mixed sizes PV inside a same VG.
To start with, just create three raw disk images:
# dd if=/dev/zero of=/tmp/hdd1.img bs=2G count=1 # dd if=/dev/zero of=/tmp/hdd2.img bs=2G count=1 # dd if=/dev/zero of=/tmp/hdd3.img bs=2G count=1
and associate them to a loopback device:
# losetup -f /dev/loop0 # losetup /dev/loop0 /tmp/hdd1.img # losetup /dev/loop1 /tmp/hdd2.img # losetup /dev/loop2 /tmp/hdd3.img
Okay nothing really exciting there, but wait the fun is coming! First check that sys-fs/lvm2 is present on your system and emerge it if not. At this point, we must tell you a secret: although several articles and authors uses the taxonomy "LVM" it denotes "LVM version 2" or "LVM 2" nowadays. You must know that LVM had, in the old good times (RHEL 3.x and earlier), a previous revision known as "LVM version 1". LVM 1 is now considered as an extincted specie and is not compatible with LVM 2, although LVM 2 tools maintain a backward compatibility.
The very frst step in LVM is to create the physical devices or PV. "Wait create what?! Aren't the loopback devices present on the system?" Yes they are present but they are empty, we must initialize them some metadata to make them usable by LVM. This is simply done by:
# pvcreate /dev/loop0 Physical volume "/dev/loop0" successfully created # pvcreate /dev/loop1 Physical volume "/dev/loop1" successfully created # pvcreate /dev/loop2 Physical volume "/dev/loop2" successfully created
It is absolutely normal that nothing in particular is printed at the output of each command but we assure you: you have there LVM PVs. You can check them by issuing:
# pvs PV VG Fmt Attr PSize PFree /dev/loop0 lvm2 a- 2.00g 2.00g /dev/loop1 lvm2 a- 2.00g 2.00g /dev/loop2 lvm2 a- 2.00g 2.00g
Some good information there:
- PV: indicates the physical path the PV lies on
- VG indicates the VG the PV belongs to. At this time, we didn't created any VG yet and the column remains empty.
- Fmt: indicates the format of the PV (here it says we have a LVM version 2 PV)
- Attrs: indicates some status information, the 'a' here just says that the PV is accessible.
- PSize and PFree: indicates the PV size and the amount of remaining space for this PV. Here we have three empty PV so it bascially says "2 gigabytes large, 2 out of gigabytes free"
It is now time to introduce you to another command: pvdisplay. Just run it without any arguments:
pvdisplay "/dev/loop0" is a new physical volume of "2.00 GiB" --- NEW Physical volume --- PV Name /dev/loop0 VG Name PV Size 2.00 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID b9i1Hi-llka-egCF-2vU2-f7tp-wBqh-qV4qEk "/dev/loop1" is a new physical volume of "2.00 GiB" --- NEW Physical volume --- PV Name /dev/loop1 VG Name PV Size 2.00 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID i3mdBO-9WIc-EO2y-NqRr-z5Oa-ItLS-jbjq0E "/dev/loop2" is a new physical volume of "2.00 GiB" --- NEW Physical volume --- PV Name /dev/loop2 VG Name PV Size 2.00 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID dEwVuO-a5vQ-ipcH-Rvlt-5zWt-iAB2-2F0XBf
The third three lines of each PV shows:
- what is the storage device beneath a PV
- the VG it is tied to
- the size of this PV.
Allocatable indicates whether the PV is used to store data. As the PV is not a member of a VG, it cannot not be used (yet) hence the "NO" shown. Another set of information is the lines starting with PE. PE stands for Physical Extents (data stripe) and is the finest granularity LVM can manipulate. The size of a PE is "0" here because we have a blank PV however it typically holds 32 MB of data. Following PE Size are Total PE which show the the total number of PE available on this PV and Free PE the number of PE remaining available for use. Allocated PE just show the difference between Total PE and Free PE.
The latest line (PV UUID) is a unique identifier used internally by LVM to name the PV. You have to know that it exists because it is sometimes useful when having to recover from corruption or do weird things with PV however most of the time you don't have to worry about its existence.
It is possible to force how LVM handles the alignments on the physical storage. This is useful when dealing with 4K sectors drives that lies on their physical sectors size. Refer to the manual page.
Volume group creation
We have the blank PV at this time but to make them a bit more usable for storage we must tell to LVM how they are grouped to form a VG (storage pool) where LV will be created. A nice aspect of VGs resides in the fact that they are not "written in the stone" once created: you can still add, remove or exchange PV (in the case the device the PV is stored on fails for example) inside a VG at a later time. To create our first volume group named vgtest:
# vgcreate vgtest /dev/loop0 /dev/loop1 /dev/loop2 Volume group "vgtest" successfully created
Just like we did before with PV, we can get a list of what are the VG known by the system. This is done through the command vgs:
# vgs VG #PV #LV #SN Attr VSize VFree vgtest 3 0 0 wz--n- 5.99g 5.99g
vgs show you a tabluar view of information:
- VG: the name of the VG
- #PV: the number of PV composing the VG
- #LV: the number of logical volumes (LV) located inside the VG
- Attrs: a status field. w, z and n here means that VG is:
- w: writable
- z: resizable
- n: using the allocation policy normal (tweaking allocation policies is beyond the scope of this article, we will use the default value normal in the rest of this article)
- VSize and VFree gives statistics on how full a VG is versus its size
Note the dashes in Attrs, they mean that the attribute is not active:
- First dash (3rd position) indicates if the VG would have been exported (a 'x' would have been showed at this position in that case).
- Second dash (4th position) indicates if the VG would have been partial (a 'p' would have been showed at this position in that case).
- Third dash (rightmost position) indicates if the VG is a clustered (a 'c' would have been showed at this position in that case).
Exporting a VG and clustered VG are a bit more advanced aspects of LVM and won't be covered here especially the clustered VGs which are used in the case of a shared storage space used in a cluster of machines. Talking about clustered VGs management in particular would require and entire article in itself. For now the only detail you have to worry about those dashes in Attrs is to see a dash at the 4th position of Attrs instead of a p. Seeing p there would be a bad news: the VG would have missing parts (PV) making it not usable.
In the exact same manner you can see a detailed information about physical volumes with pvdisplay, you can see detailed information of a volume group with vgdisplay. We will demonstrate that latter command in the next paragraphs.
Before leaving the volume group aspect, do you remember the pvs command shown in the previous paragraphs? Try it gain:
# pvs PV VG Fmt Attr PSize PFree /dev/loop0 vgtest lvm2 a- 2.00g 2.00g /dev/loop1 vgtest lvm2 a- 2.00g 2.00g /dev/loop2 vgtest lvm2 a- 2.00g 2.00g
Now it shows the VG our PVs belong to :-)
Logical volumes creation
Now the final steps: we will create the storage areas (logical volumes or LV) inside the VG where we will then create filesystems on. Just like a VG has a name, a LV has also a name which is unique in the VG.
Two LV can be given the same name as long as they are located on a different VG.
To divide our VG like below:
- lvdata1: 2 GB
- lvdata2: 1 GB
- lvdata3 : 10% of the VG size
- lvdata4 : All of remaining free space in the VG
We use the following commands (notice the capital 'L' and the small 'l' to declare absolute or relative sizes):
# lvcreate -n lvdata1 -L 2GB vgtest Logical volume "lvdata1" created # lvcreate -n lvdata2 -L 1GB vgtest Logical volume "lvdata2" created # lvcreate -n lvdata3 -l 10%VG vgtest Logical volume "lvdata2" created
What is going on so far? Let's check with the pvs/vgs counterpart known as lvs:
# lvs LV VG Attr LSize Origin Snap% Move Log Copy% Convert lvdata1 vgtest -wi-a- 2.00g lvdata2 vgtest -wi-a- 1.00g lvdata3 vgtest -wi-a- 612.00m #
Notice the size of lvdata3, it is roughly 600MB (10% of 6GB). How much free space remains in the VG? Time to see what vgs and vgdisplay returns:
# vgs VG #PV #LV #SN Attr VSize VFree vgtest 3 3 0 wz--n- 5.99g 2.39g # vgdisplay --- Volume group --- VG Name vgtest System ID Format lvm2 Metadata Areas 3 Metadata Sequence No 4 VG Access read/write VG Status resizable MAX LV 0 Cur LV 3 Open LV 0 Max PV 0 Cur PV 3 Act PV 3 VG Size 5.99 GiB PE Size 4.00 MiB Total PE 1533 Alloc PE / Size 921 / 3.60 GiB Free PE / Size 612 / 2.39 GiB VG UUID baM3vr-G0kh-PXHy-Z6Dj-bMQQ-KK6R-ewMac2
Basically it say we have 1533 PE (chunks) available for a total size of 5.99 GiB. On those 1533, 921 are used (for a size of 3.60 GiB) and 612 remains free (for a size of 2.39 GiB). So we expect to see lvdata4 having an approximative size of 2.4 GiB. Before creating it, have a look at some statistics at the PV level:
# pvs PV VG Fmt Attr PSize PFree /dev/loop0 vgtest lvm2 a- 2.00g 0 /dev/loop1 vgtest lvm2 a- 2.00g 404.00m /dev/loop2 vgtest lvm2 a- 2.00g 2.00g # pvdisplay --- Physical volume --- PV Name /dev/loop0 VG Name vgtest PV Size 2.00 GiB / not usable 4.00 MiB Allocatable yes (but full) PE Size 4.00 MiB Total PE 511 Free PE 0 Allocated PE 511 PV UUID b9i1Hi-llka-egCF-2vU2-f7tp-wBqh-qV4qEk --- Physical volume --- PV Name /dev/loop1 VG Name vgtest PV Size 2.00 GiB / not usable 4.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 511 Free PE 101 Allocated PE 410 PV UUID i3mdBO-9WIc-EO2y-NqRr-z5Oa-ItLS-jbjq0E --- Physical volume --- PV Name /dev/loop2 VG Name vgtest PV Size 2.00 GiB / not usable 4.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 511 Free PE 511 Allocated PE 0 PV UUID dEwVuO-a5vQ-ipcH-Rvlt-5zWt-iAB2-2F0XBf
Quite interesting! Did you notice? The first PV is full, the second is more or less full and the third is empty. This is due to the allocation policy used for the VG: it fills its first PV then its second PV and then its third PV (this, by the way, gives you a chance to recover from a dead physical storage if by luck none of your PE was present on it).
It is now time to create our last LV, again notice the small 'l' to specify a relative size:
# lvcreate -n lvdata4 -l 100%FREE vgtest Logical volume "lvdata4" created # lvs LV VG Attr LSize Origin Snap% Move Log Copy% Convert lvdata1 vgtest -wi-a- 2.00g lvdata2 vgtest -wi-a- 1.00g lvdata3 vgtest -wi-a- 612.00m lvdata4 vgtest -wi-a- 2.39g
Now the $100 question: if pvdisplay and vgdisplay commands exist, does command named lvdisplay exist as well? Yes absolutely! Indeed the command sets are coherent between abstraction levels (PV/VG/LV) and they are named in the exact same manner modulo their first 2 letters:
- PV: pvs/pvdisplay/pvchange....
- VG: vgs/vgdisplay/vgchange....
- LG: lvs/lvdisplay/lvchange....
Back to our lvdisplay command, here is how it shows up:
# lvdisplay --- Logical volume --- LV Name /dev/vgtest/lvdata1 VG Name vgtest LV UUID fT22is-cmSL-uhwM-zwCd-jeIe-DWO7-Hkj4k3 LV Write Access read/write LV Status available # open 0 LV Size 2.00 GiB Current LE 512 Segments 2 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:0 --- Logical volume --- LV Name /dev/vgtest/lvdata2 VG Name vgtest LV UUID yd07wA-hj77-rOth-vxW8-rwo9-AX7q-lcyb3p LV Write Access read/write LV Status available # open 0 LV Size 1.00 GiB Current LE 256 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:1 --- Logical volume --- LV Name /dev/vgtest/lvdata3 VG Name vgtest LV UUID ocMCL2-nkcQ-Fwdx-pss4-qeSm-NtqU-J7vAXG LV Write Access read/write LV Status available # open 0 LV Size 612.00 MiB Current LE 153 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:2 --- Logical volume --- LV Name /dev/vgtest/lvdata4 VG Name vgtest LV UUID iQ2rV7-8Em8-85ts-anan-PePb-gk18-A31bP6 LV Write Access read/write LV Status available # open 0 LV Size 2.39 GiB Current LE 612 Segments 2 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:3
Nothing extremely useful to comment for an overview beyond showing at the exception of two things:
- LVs are accessed via the device mapper (see the lines starting by LV Name and notice how the name is composed). So lvdata1 will be accessed via /dev/vgtest/lvdata1, lvdata2 will be accessed via /dev/vgtest/lvdata2 and so on.
- just like PV are managed in sets of data chunks (the so famous Physical Extents or PEs), LVs are managed in a set of data chunks known as Logical Extents or LEs. Most of the time you don't have to worry about the existence of LEs because they fits withing a single PE although it is possible to make them smaller hence having several LE within a single PE. Demonstration: if you consider the first LV, lvdisplay says it has a size of 2 GiB and holds 512 logical extents. Dividing 2GiB by 512 gives 4 MiB as the size of a LE which is the exact same size used for PEs as seen when demonstrating the pvdisplay command some paragraphs above. So in our case we have a 1:1 match between a LE and the underlying PE.
Oh another great point to underline: you can display the PV in relation with a LV :-) Just give a special option to lvdisplay:
# lvdisplay -m
--- Logical volume ---
LV Name /dev/vgtest/lvdata1
VG Name vgtest
(...)
Current LE 512
Segments 2
(...)
--- Segments ---
Logical extent 0 to 510:
Type linear
Physical volume /dev/loop0
Physical extents 0 to 510
Logical extent 511 to 511:
Type linear
Physical volume /dev/loop1
Physical extents 0 to 0
--- Logical volume ---
LV Name /dev/vgtest/lvdata2
VG Name vgtest
(...)
Current LE 256
Segments 1
(...)
--- Segments ---
Logical extent 0 to 255:
Type linear
Physical volume /dev/loop1
Physical extents 1 to 256
--- Logical volume ---
LV Name /dev/vgtest/lvdata3
VG Name vgtest
(...)
Current LE 153
Segments 1
(...)
--- Segments ---
Logical extent 0 to 152:
Type linear
Physical volume /dev/loop1
Physical extents 257 to 409
--- Logical volume ---
LV Name /dev/vgtest/lvdata4
VG Name vgtest
(...)
Current LE 612
Segments 2
(...)
--- Segments ---
Logical extent 0 to 510:
Type linear
Physical volume /dev/loop2
Physical extents 0 to 510
Logical extent 511 to 611:
Type linear
Physical volume /dev/loop1
Physical extents 410 to 510
To go one step further let's analyze a bit how the PE are used: the first LV has 512 LEs (remember: one LE fits within one PE here so 1 LE = 1 PE). Amongst those 512 LEs, 511 of them (0 to 510) are stored on /dev/loop0 and the 512th LE is on /dev/loop1. Huh? Something seems to be wrong here, pvdisplay said that /dev/loop0 was holding 512 PV so why an extent has been placed on the second storage device? Indeed its not a misbehaviour and absolutely normal: LVM uses some metadata internally with regards the PV, VG and LV thus making some of storage space unavailable for the payload. This explains why 1 PE has been "eaten" to store that metadata. Also notice the linear allocation process: /dev/loop0 has been used, then when being full /dev/loop1 has also been used then the turn of /dev/loop2 came.
Now everything is in place, if you want just check again with vgs/pvs/vgdisplay/pvdisplay and will notice that the VG is now 100% full and all of the underlying PV are also 100% full.
Filesystems creation and mounting
Now we have our LVs it could be fun if we could do something useful with them. In the case you missed it, LVs are accessed via the device mapper which uses a combination of the VG and LV names thus:
- lvdata1 is accessible via /dev/vgtest/lvdata1
- lvdata2 is accessible via /dev/vgtest/lvdata2
- and so on!
Just like any traditional storage device, the newly created LVs are seen as block devices as well just as if they were a kind of harddisk (don't worry about the "dm-..", it is just an internal block device automatically allocated by the device mapper for you):
# ls -l /dev/vgtest total 0 lrwxrwxrwx 1 root root 7 Dec 27 12:54 lvdata1 -> ../dm-0 lrwxrwxrwx 1 root root 7 Dec 27 12:54 lvdata2 -> ../dm-1 lrwxrwxrwx 1 root root 7 Dec 27 12:54 lvdata3 -> ../dm-2 lrwxrwxrwx 1 root root 7 Dec 27 12:54 lvdata4 -> ../dm-3 # ls -l /dev/dm-[0-3] brw-rw---- 1 root disk 253, 0 Dec 27 12:54 /dev/dm-0 brw-rw---- 1 root disk 253, 1 Dec 27 12:54 /dev/dm-1 brw-rw---- 1 root disk 253, 2 Dec 27 12:54 /dev/dm-2 brw-rw---- 1 root disk 253, 3 Dec 27 12:54 /dev/dm-3
So if LVs are block device a filesystem can be created on them just like if they were a real harddisk or hardisk partitions? Absolutely! Now let's create ext4 filesystems on our LVs:
# mkfs.ext4 /dev/vgtest/lvdata1
mke2fs 1.42 (29-Nov-2011)
Discarding device blocks: done
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
131072 inodes, 524288 blocks
26214 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
# mkfs.ext4 /dev/vgtest/lvdata1
(...)
# mkfs.ext4 /dev/vgtest/lvdata2
(...)
# mkfs.ext4 /dev/vgtest/lvdata3
(..)
Once the creation ended we must create the mount points and mount the newly created filesystems on them:
# mkdir /mnt/data-01 # mkdir /mnt/data-02 # mkdir /mnt/data-03 # mkdir /mnt/data-04 # mount /dev/vgtest/lvdata1 /mnt/data01 # mount /dev/vgtest/lvdata2 /mnt/data02 # mount /dev/vgtest/lvdata3 /mnt/data03 # mount /dev/vgtest/lvdata4 /mnt/data04
Finally we can check that everything is in order:
# df -h Filesystem Size Used Avail Use% Mounted on (...) /dev/mapper/vgtest-lvdata1 2.0G 96M 1.9G 5% /mnt/data01 /dev/mapper/vgtest-lvdata2 1022M 47M 924M 5% /mnt/data02 /dev/mapper/vgtest-lvdata3 611M 25M 556M 5% /mnt/data03 /dev/mapper/vgtest-lvdata4 2.4G 100M 2.2G 5% /mnt/data04
Did you notice the device has changed? Indeed everything is in order, mount just uses another set of symlinks which point to the exact same block devices:
# ls -l /dev/mapper/vgtest-lvdata[1-4] lrwxrwxrwx 1 root root 7 Dec 28 20:12 /dev/mapper/vgtest-lvdata1 -> ../dm-0 lrwxrwxrwx 1 root root 7 Dec 28 20:13 /dev/mapper/vgtest-lvdata2 -> ../dm-1 lrwxrwxrwx 1 root root 7 Dec 28 20:13 /dev/mapper/vgtest-lvdata3 -> ../dm-2 lrwxrwxrwx 1 root root 7 Dec 28 20:13 /dev/mapper/vgtest-lvdata4 -> ../dm-3
Renaming a volume group and its logical volumes
So far we have four LVs named lvdata1 to lvdata4 mounted on /mnt/data01 to /mnt/data04. It would be more adequate to :
- make the number in our LV names being like "01" instead of "1"
- rename our volume groupe to "vgdata" instead of "vgtest"
To show how dynamic is the LVM world, we will rename our VG and LV on the fly using two commands: vgrename for acting at the VG level and its counterpart lvrename to act at the LV level. Starting by the VG or the LVs makes strictly no difference, you can start either way and get the same result. In our example we have chosen to start with the VG:
# vgrename vgtest vgdata Volume group "vgtest" successfully renamed to "vgdata" # lvrename vgdata/lvdata1 vgdata/lvdata01 Renamed "lvdata1" to "lvdata01" in volume group "vgdata" # lvrename vgdata/lvdata2 vgdata/lvdata02 Renamed "lvdata2" to "lvdata02" in volume group "vgdata" # lvrename vgdata/lvdata3 vgdata/lvdata03 Renamed "lvdata3" to "lvdata03" in volume group "vgdata" # lvrename vgdata/lvdata4 vgdata/lvdata04 Renamed "lvdata4" to "lvdata04" in volume group "vgdata"
What happened? Simple:
# vgs VG #PV #LV #SN Attr VSize VFree vgdata 3 4 0 wz--n- 5.99g 0 # lvs LV VG Attr LSize Origin Snap% Move Log Copy% Convert lvdata01 vgdata -wi-ao 2.00g lvdata02 vgdata -wi-ao 1.00g lvdata03 vgdata -wi-ao 612.00m lvdata04 vgdata -wi-ao 2.39g
Sounds good, our VG and LVs have been renamed! What a command like mount will say?
# mount (...) /dev/mapper/vgtest-lvdata1 on /mnt/data01 type ext4 (rw) /dev/mapper/vgtest-lvdata2 on /mnt/data02 type ext4 (rw) /dev/mapper/vgtest-lvdata3 on /mnt/data03 type ext4 (rw) /dev/mapper/vgtest-lvdata4 on /mnt/data04 type ext4 (rw) #
Ooops... It is not exactly a bug, mount still shows the symlinks used at the time the LVs were mounted in the VFS and has not updated its information. However once again everything is correct because the underlying block devices (/dev/dm-0 to /dev/dm-3) did not changed at all. To see the right information the LVs must be unmounted and mounted again:
# umount /mnt/data01 (...) # umount /mnt/data04 # mount /dev/vgdata/lvdata01 /mnt/data01 (...) # mount /dev/vgdata/lvdata04 /mnt/data04 # mount /dev/mapper/vgdata-lvdata01 on /mnt/data01 type ext4 (rw) /dev/mapper/vgdata-lvdata02 on /mnt/data02 type ext4 (rw) /dev/mapper/vgdata-lvdata03 on /mnt/data03 type ext4 (rw) /dev/mapper/vgdata-lvdata04 on /mnt/data04 type ext4 (rw)
Using /dev/volumegroup/logicalvolume or /dev/volumegroup-logicalvolume makes no difference at all, those are two sets of symlinks pointing on the exact same block device.
Expanding and shrinking the storage space
Did you notice in the previous section we have never talked on topic like "create this partition at the beginning" or "allocate 10 sectors more". In LVM you do not have to worry about that kind of problematics: your only concern is more "Do I have the space to allocate a new LV or how can I extend an existing LV?". LVM takes cares of the low levels aspects for you, just focus on what you want to do with your storage space.
The most common problem with computers is the shortage of space on a volume, most of the time production servers can run months or years without requiring a reboot for various reasons (kernel upgrade, hardware failure...) however they regularly requires to extend their storage space because we do generate more and more data as the time goes. With "traditional" approach like fiddling directly with hard drives partitions, storage space manipulation can easily become a headache mainly because it requires coherent copy to be made and thus application downtimes. Don't expect the situation to be more enjoyable with a SAN storage rather a directly attached storage device... Basically the problems remains the same.
Expanding a storage space
The most common task for a system administrator is to expand the available storage space. In the LVM world this implies:
- Creating a new PV
- Adding the PV to the VG (thus extending the VG capacity)
- Extending the existing LVs or create new ones
- Extending the structures of the filesystems located on a LV in the case a LV is extended (Not all of the filesystems around support that capability).
Bringing a new PV in the VG
In the exact same manner we have created our first PV, let's create our additional storage, associate it to a loopback device and then create a PV on it:
# dd if=/dev/zero of=/tmp/hdd4.img bs=2G count=1 # losetup /dev/loop3 /tmp/hdd4.img # pvcreate /dev/loop3
A pvs should report the new PV:
# pvs PV VG Fmt Attr PSize PFree /dev/loop0 vgdata lvm2 a- 2.00g 0 /dev/loop1 vgdata lvm2 a- 2.00g 0 /dev/loop2 vgdata lvm2 a- 2.00g 0 /dev/loop3 lvm2 a- 2.00g 2.00g
Excellent! The next step consist of adding this newly created PV inside our VG vgdata, here is where the vgextend command comes at our rescue:
# vgextend vgdata /dev/loop3 Volume group "vgdata" successfully extended # vgs VG #PV #LV #SN Attr VSize VFree vgdata 4 4 0 wz--n- 7.98g 2.00g
Notice that our VG vgdata is now 8 GB large instead of 6 GB and have 2 GB of free space to allocate to either new LVs either existing LVs.
Extending the LV and its filesystem
Bringing new LV would demonstrate nothing more nevertheless extending our existing LVs is much more interesting. How can we use our 2GB extra free space? We can, for example, split it in two allocating a 50% to our first (lvdata01) and third (lvdata03) LV adding 1GB of space to both. The best of the story is that operation is very simple and is realized with a command named lvextend:
# lvextend vgdata/lvdata01 -l +50%FREE Extending logical volume lvdata01 to 3.00 GiB Logical volume lvdata01 successfully resized # lvextend vgdata/lvdata03 -l +50%FREE Extending logical volume lvdata03 to 1.10 GiB Logical volume lvdata03 successfully resized