LVM (Logical Volume Manager)
기존에 있던 파티션을 합쳐 새롭게 구성하는 기능이다.
컴퓨터를 사용하다 보면 데이터가 쌓이고, 새로운 프로그램을 설치하다 보면 하드디스크 공간이 부족한 경우가 생길 수 있다. fdisk(또는 cfdisk)를 사용해 한번 리눅스 파티션의 크기를 정한 후 파티션을 확장하려면 그 안의 내용을 삭제하고, 크기를 늘려야 한다. 이와 같은 구조는 서버에서는 큰 문제가 된다. 서버는 절대 정지해서는 안되는 컴퓨터이기 때문이다. 이 경우 서버가 정지하고, 서버가 멈춘다는 것은 곧 금전적인 손실과 직결된다. 이런 문제점을 해결하기 위해 유닉스에서 일찍부터 도입했던 것이 바로 lvm으로 리눅스 역시 커널 2.4부터 엔터프라이즈 기능 강화 차원에서 lvm을 새롭게 도입한 것이다.
예를 들어, 처음 설치할 때 /home 파티션에 1GB를 할당한 후 나중에 이 파티션을 늘리는 방법은 운영체제를 새로 설치, 파티션을 나누는 방법 밖에 없다. 이때 lvm을 이용, /home 파티션 크기를 10GB로 늘릴 수 있다. 반대로 10GB의 필요없는 /var라는 파티션이 있다면 이것을 줄여 다른 곳에 사용할 수 있다. 또 lvm을 이용하면 기존 하드 디스크의 /home 파티션이 꽉 차 더 이상 사용할 수 없을 때, 하드 디스크를 추가해 /home의 용량을 늘릴 수 있다. lvm은 이렇게 고무줄처럼 파티션을 늘였다 줄였다 할 수 있어 대형 서버에서 아주 유용한 기능이다.
lvm의 기본 개념
lvm을 사용하기 위해 알아야 할 기본적인 용어는 다음과 같다.
- PE(physical media) : 일반적인 물리적 하드 디스크를 말한다. /dev/hda, /dev/sda 등을 예로 들 수 있다.
- PV(Physical Volume) : 각각의 파티션을 나눈 것을 말한다(/dev/ hda1, /dev/hda2 등). 이 때 파일 타입은 lvm을 사용할 수 있게 0x 8e로 설정해야 한다.
- PE(Physical Extents) : 하드 디스크를 제어할 때 블럭(PE) 단위로 제어한다. 블럭 하나는 대개 MB 단위의 크기를 갖는다. 예를 들면 볼륨그룹 크기가 184MB이고, 기본 PE가 4MB일 때 PE의 개수는 46개가 된다. pvcrate에서 옵션으로 -l을 사용하면 PE 단위로 사용하게 된다.
- VG(Volume Group) : PV로 되어 있는 파티션을 그룹으로 설정한다. /dev/hda1을 하나의 그룹으로 만들 수도 있고, /dev/hda1 + /dev/hda2처럼 파티션 두 개를 하나의 그룹으로 만들 수 있다. 그밖에도 다양하게 그룹 설정을 할 수 있다.
- LV(Logical Volume) : 마운트 포인터로 사용할 실질적인 파티션이다. 크기를 바꿀 수 있다.
- Filesystem : ext2, reiserfs 등의 리눅스에서 사용하는 모든 파일시스템을 사용할 수 있다.
물리적 확장을 포함한, 물리적 볼륨: +-----[ Physical Volume ]------+ | PE | PE | PE | PE | PE | PE | +------------------------------+ 6개의 물리적 확장과 2개의 물리적 볼륨(PVs)를 포함한 볼륨 그룹: +------[ Volume Group ]-----------------+ | +--[PV]--------+ +--[PV]---------+ | | | PE | PE | PE | | PE | PE | PE | | | +--------------+ +---------------+ | +---------------------------------------+ 우리는 여기에 더 추가 확장을 하였다.: +------[ Volume Group ]-----------------+ | +--[PV]--------+ +--[PV]---------+ | | | PE | PE | PE | | PE | PE | PE | | | +--+---+---+---+ +-+----+----+---+ | | | | | +-----/ | | | | | | | | | | | | +-+---+---+-+ +----+----+--+ | | | Logical | | Logical | | | | Volume | | Volume | | | | | | | | | | /home | | /var | | | +-----------+ +------------+ | +---------------------------------------+
출처 <BLUESEA.name>
실제적인 작업
이제 본격적으로 LVM를 다루어 보도록 하자.
1) PV 초기화
먼저 제일 처음에 해야 할 작업이 블록 디바이스를 PV로 초기화하는 것이다. PV이 될 수 있는 장치로는, 하드 디스크 (/dev/hda, /dev/sda, …), 하드디스크의 파티션 (/dev/hda1, /dev/sda1, …), 소프트웨어 RAID 디바이스 (/dev/md0, …), Loopback 디바이스 (/dev/loop0, …) 등이 있다.
그러나 하드디스크의 경우 사전 작업을 해야 한다. 만약 파티션을 PV으로 만들 경우 그 파티션의 System ID가 0x8e 이어야 한다. 간단히 fdisk를 사용해서 /dev/hda2를 바꾼다면 다음과 같을 것이다.
# fdisk /dev/hda
Command (m for help): t
Partition number (1-6): 2
Hex code (type L to list codes): 8e
Changed system type of partition 2 to 8e (Linux LVM)
Command (m for help): w
그리고, 파티션을 나누지 않고 하드디스크 전체를 PV로 만들려고 할 때에, 파티션 정보가 기록되어 있다면 PV로 만들어지지 않을 것이다. 파티션을 fdisk등으로 전부 지워도 마찬가지인데 해결 방법은 dd등의 명령으로 파티션 정보를 깨끗히 지워주면 된다. 예를 들면 다음과 같다.
# dd if=/dev/zero of=/dev/sda bs=512 count=1
(**주의** 위의 명령은 한순간에 파티션 정보를 날리는 방법이다. 사용상의 특별한 주의가 필요하다.)
PV 를 만드는 명령은 pvcreate인데 사용법은 간단하다. 아래는 그 사용의 예이다.
# pvcreate /dev/hda2
추가적으로, 권장하는 것은 특별한 이유가 없으면 하나의 하드디스크에는 두개 이상의 PV를 만들지 않는 것이 좋다. 관리적인 면이나 효율적인 면에서 이득이 많기 때문이다.
pvcreate -- physical volume “/dev/hda2”
successfully created
2) VG 만들기, 이름 바꾸기, 지우기
만들어진 PV들을 합쳐서 하나의 VG로 만드는 명령은 vgcreate이다.
아래는 그 예이다.
# vgcreate -s 16m new_vg /dev/sda /dev/sdb /dev/sdc
위의 명령은 세개의 SCSI 디스크를 합쳐서 new_vg라는 VG를 만든다는 것이다.
옵션 ‘-s 16m’은 PE의 크기를 16MB로 정하는 것인데, 만약 옵션 ‘-s’가 생략되면 기본적으로 PE의 크기는 4MB가 된다.
VG가 만들어지면 /dev/VolumeGroupName라는 형식으로 디렉토리가 생기게 된다. 위의 예에서는 /dev/new_vg 가 될 것이다.
* 위와 같이 pv를 생성하면 최대 LV 크기가 1TB로 제한된다. 이보다 큰 용량의 LV를 생성하고자 하면 extents 값을 늘려주어야 한다. extents 값을 32로 하면 최대 LV 크기가 2TB가 된다. (default extents size 4MB에서는 256B)
# vgcreate -s 32 test_vg /dev/sd[bc]1
vgcreate -- INFO: maximum logical volume size is 2 Terabyte
vgcreate -- doing automatic backup of volume group "test_vg"
vgcreate -- volume group "test_vg" successfully created and activatedVG의 이름을 바꾸려면 vgrename 이라는 명령을 아래와 같이 쓰면 된다.
# vgrename new_vg vg00
* vg이름을 바꾸기전에 vgchange -a n vg01 으로 활성화상태의 볼륨그룹을 비활성화상태로 만들어야 됨. 바꾸고 난 뒤 다시 vgchange -a n vg01
VG에 LV가 남아있지 않고 비활성화되어 있으면 vgremove로 지울 수 있다. 비활성화시키는 방법은,
# vgchange -a n vg00
이고, 다음의 명령으로 지워진다.
# vgremove vg00
3) VG 확장시키기, 축소시키기
VG의 확장과 촉소는 PV의 추가, 제거로 이루어진다.
VG에 PV를 추가하는 명령은 vgextend인데, vg00이라는 VG에 PV인 /dev/hda2를 추가하려면 다음과 같이 실행해야 한다.
# vgextend vg00 /dev/hda2
PV를 VG에서 제거하는 명령은 vgreduce이다. 그러나 PV에 PE가 할당되어 있으면 제거되지 않는다. 그 할당된 PE를 다른 PV로 옮겨야 제거될 것이다. 빈 PV인 /dev/hda2를 vg00에서 제거하려면,
# vgreduce vg00 /dev/hda2
4) LV 만들기, 이름 바꾸기, 지우기
VG에 LV를 만들면 /dev/VolumeGroupName/LogicalVolumeName의 형식으로 블록 디바이스가 만들어진다. 이것은 일반 블록 디바이스와 다를 바 없는 용도로 쓸 수 있다.
LV 를 만드는 명령은 lvcreate인데 일반적인 예는 다음과 같다.
# lvcreate -L 4g -n data vg00
위의 명령은 4GB 크기로 vg00이라는 VG에 data라는 새로운 LV를 만드는 것이다. 옵션 ‘-L’은 LV의 크기를 지정하는 것인데, 숫자 뒤의 접미사에 따라 숫자의 단위가 달라진다. k는 KB, m은 MB, g는 GB, t는 TB를 뜻한다. 만약, 접미사가 안 붙어있으면 숫자의 단위는 MB가 된다. ‘-L’ 대신 ‘-l’를 쓸 수도 있는데, ‘-l’ 뒤에는 LE의 갯수를 쓰면 된다.
LV의 이름을 바꾸는 것은 아래의 명령처럼 간단하고,
# lvrename /dev/vg00/data /dev/vg00/db
* 바꾸기시 안되면 lvchange -a n /dev/vg00/data --> 비활성화
바꾸고 나서 lvchange -a n /dev/vg00/data --> 활성화
지우는 것 또한 간단하다.
# lcremove /dev/vg00/db
5) LV 확장시키기
LV를 확장시키는 명령은 lvextend 인데, 다음은 그 예이다.
# lvextend -L +2g /dev/vg00/db
위의 명령은 /dev/vg00/db의 크기를 2GB 만큼 늘린다. 기존의 크기가 4GB 였다면, 옵션 ‘-L 6g’를 줬어도 같은 결과를 보일 것이다. 역시 여기에서도 옵션 ‘-l’를 쓰면 LE 단위로 늘릴 수 있다.
LV의 크기가 커졌어도 파일 시스템에는 영향을 주지 않으므로 파일 시스템 고유의 툴을 이용하여 확장 해주어야 한다.
한 가지 주의해야 할 것은 이렇게 크기를 늘릴 때 순서를 뒤바꾸면 절대 안 된다는 것이다. LV 확장 다음에 파일 시스템의 확장이다.
다음은 파일 시스템 별 확장 방법이다.
* ext2 : ext2 파일 시스템의 크기를 바꿀 수 있는 명령으로는 resize2fs이 있는데, e2fsprogs 1.19버전 이상에는 기본적으로 포함되어 있다. 그 이하의 버전을 쓴다면 ext2resize라는 프로그램을 다음의 사이트에서 구할 수 있다.
http;//ext2resize.sourceforge.org
다음은 일반적인 ext2 의 확장 절차이다.
# umount /var/lib/mysql
# lvextend -L +10g /dev/databases/mysql
# resize2fs /dev/databases/mysql
# mount /dev/databases/mysql /var/lib/mysql
LVM tool에 포함되어있는 e2fsadm을 쓰면 LV 확장과 파일 시스템의 확장을 동시에 할 수 있다. 다음의 명령은,
# e2fsadm?L +10g /dev/databases/mysql
다음의 두 명령과 같다.
# lvextend -L +10g /dev/databases/mysql
# resize2fs /dev/databases/mysql
* reiserfs : reiserfs는 resize_reiserfs 라는 명령으로 크기를 바꿀 수 있다.
마운트된 상태에서도 크기를 늘릴 수 있는데, 그 예는 다음과 같다.
# lvextend -L +5g /dev/devel/cvs
# resize_reiserfs -f /dev/devel/cvs
언마운트해서 늘리려면 다음 같이 한다.
# umount /var/cvs
# lvextend -L +5g /dev/devel/cvs
# resize_reiserfs -f /dev/devel/cvs
# mount /dev/devel/cvs /var/cvs
6) LV 축소시키기
lvreduce는 LV의 크기를 줄이는데, 늘릴 때와 마찬가지로 파일 시스템과 별개로 이루어지므로 데이터를 잃어버릴 수 있으니 상당히 조심해야 한다.
작업의 순서는 확장할 때와는 반대로, 파일 시스템의 축소 다음에 LV의 축소이다.
각 파일 시스템 별 축소 방법이다.
* ext2 : e2fsadm 을 쓰는 것이 간단하다.
# umount /home
# e2fsadm -L -2g /dev/vg00/home
# mount /dev/vg00/home /home
* reiserfs : 크기를 늘릴 때와는 달리 마운트 된 상태에서는 줄일 수 없다.
# umount /usr
# resize_reiserfs -s -1g /dev/vg00/usr
# lvreduce -L -1g /dev/vg00/usr
# mount /dev/vg00/usr /usr
7) 설정의 백업과 복구
LVM Tool들은 기본적으로 몇몇을 제외하고 동작 전의 설정상태를 자동으로 백업해둔다.(절대 데이터의 백업이 아니다!) 그 백업파일들은 /etc/lvmconf 라는 디렉토리에 VolumeGroupName.conf{,.[0-9].old}라는 이름으로 만들어진다. 뒤에 번호가 붙어있지 않은 것은 현재의 설정 내용이고, 그 번호가 클수록 오래된 내용이다. 그러므로 바로 전의 설정 내용을 담고 있는 파일에는 이름 뒤에는 .1.old가 붙어있다.
먼저 설정 백업 파일의 내용을 보려면 다음과 같이 한다.
# vgcfgrestore -f /etc/lvmconf/vg00.conf.1.old -ll -n vg00
이 파일을 이용해 설정을 복구하려면 다음과 같이 한다.
# vgchange -a n vg00
# vgcfgrestore -f /etc/lvmconf/vg00.conf.1.old -n vg00
# vgchange -a y vg00
활용
몇 가지 유용한 활용 예를 보이겠다.
1) 두개의 ide disk를 하나의 striped mapping LV로 묶기
80GB 짜리(실제는 약 76.1GB) IDE 하드디스크 두 개를 striped mapping LV 로 묶는 과정이다.
먼저 블록 디바이스 이름이 /dev/hde, /dev/hdf 인 디스크들을 PV로 만든다.
# pvcreate /dev/hde /dev/hdf
그렇게 만든 PV들을 합쳐서 VG를 만든다.
# vgcreate vg00 /dev/hde /dev/hdf
이제 VG에 LV를 만든다.
# lvcreate -i 2 -I 4 -L 152g -n striped_lv vg00
위의 명령으로 152GB 짜리 striped mapping LV가 만들어진 것이다. 옵션을 설명하면 ‘-i 2’는 두개의 PV를 striped 하는데 쓰고, ‘-I 4’는 PE를 4KB로 쪼개서 PV들에게 저장한다는 것이다. ‘-I’ 옵션에는 2^n (0 <= n <= 7), 즉 1, 2, 4, 8, 16, 32, 64, 128 의 숫자를 쓸 수 있다.
파일 시스템을 만들고, 마운트를 해서,
# mkreiserfs /dev/vg00/striped_lv
# mount /dev/vg00/striped_lv /mnt
bonnie++ 등의 벤치마킹 프로그랭으로 시험해본 결과, linear mapping LV보다 약 1.5배에서 1.8배까지 속도의 차이가 있었다. 물론 억세스가 많아지면 어떻게 되는지는 필자도 시험을 못했다.
2) 세로운 디스크로 PV 교체하기
하드디스크를 확장하면서 기존에 있는 하드디스크를 제거해야 할 때는 다음과 같은 과정을 거치면 된다.
환경은 /dev/hdd, /dev/sda, /dev/sdb가 vg01에 속해있는데, 그중에서 /dev/hdd를 빼고 /dev/sdc를 더하는 과정이다.
먼저 /dev/sdc 를 PV 로 만들고,
# pvcreate /dev/sdc
/dev/sdc를 vg01에 추가한 후에,
# vgextend vg01 /dev/sdc
/dev/hdd의 PE 들을 /dev/sdc로 옮긴다.
# pvmove /dev/hdd /dev/sdc
성공적으로 옮겨졌으면 vg01에서 /dev/hdd를 제거한다.
# vgreduce vg01 /dev/hdd
3) snapshot LV를 만들어서 안전한 백업하기
데이터의 변동이 많은 /var등의 디렉토리는 백업 도중에 데이터가 엉키는 수가 있다. 그것을 방지하기 위해서, snapshot LV를 만들어 데이터를 고정시킨 후 백업을 하면 된다.
일단 snapshot LV 를 만든다.(한 줄로)
# lvcreate -s -L 5g -n mysqlbackup /dev/vg01/mysql
위의 명령은 /dev/vg01/mysql에 대한 snapshot LV인 /dev/vg01/mysqlbackup를 만든다. 옵션 ‘-s’는 만들어질 LV가 snapshot 형식임을 정해주고 있다. 옵션 ‘-L’ 는 LV 의 최대 크기를 정해준다. 대게 원본 LV와 크기를 같게 하는 것이 좋다. 사실 snapshot LV는 원본이 갱신되는 부분만 고정시키려고 데이터를 가져와 LE에 할당하기 때문에 많은 LE가 필요하지 않다.
이제 만든 LV 를 마운트 시킨 후
# mount /dev/vg01/mysqlbackup /mnt
백업을 하면 된다.
# tar cf /dev/rmt0 /mnt
백업을 마쳤으면 언마운트시킨 후에 snapshot LV 을 지운다.
# mount /mnt# lvremove /dev/vg01/mysqlbackup