Unix

LVM 실험

ForceCore 2009. 2. 21. 18:04
LVM을 하기 전에 LVM에 대한 분노... 를 읽어볼 것 ㅠㅠ;; 쳐발렸다 ㅠㅠ
http://forcecore.tistory.com/1093
system-config-lvm 패키지를 설치해서 GUI로 다루는 것 추천.

개념원리


LVM 개념부터 공부해야 하는데... 알고 써야지 된다. 모르고 쓰다 발리면 곤란하다 -_-
용어가 많이 등장하는데 그다지... 와닿게 설명해놓은 글을 별로 못 본듯 하다.
http://imgun.com/bbs/board.php?bo_table=linux&wr_id=86 : 가장 간단히 설명함.
http://wiki.kldp.org/wiki.php/DocbookSgml/LVM-HOWTO : LVM1 howto 번역글
http://tldp.org/HOWTO/LVM-HOWTO/ : LVM2 howto 오리지널 영어 문서

필자가 이해한 바로는:

Volume Group (VG): 우리가 원하는, 통째로 묶어준 것. LVM이 관리하는 가상 디스크라고 생각할 수 있다. 여러 디스크를 묶은 것이라 용량이 크겠죠...a

Physical Volume: 하드디스크이거나, 이미 하드디스크를 raid같은 것으로 한번 묶었든 어쨌든, 진짜 하드디스크처럼 보이는 것. 파티션도 PV에 들어간다. LVM의 먹이로 주어지는, 가상화되지 않은 용량 제공자들.

Logical Volume (LV): Volume Group이 가상 "디스크"이기 때문에, 진짜 디스크처럼 "파티션"으로 쪼갤 수 있다. 그 파티션 하나하나가 각각 LV이다.

Physical Extent & Logical Extent : 메모리 관리에서 "페이지"라고 들어봤는지 모르겠다. 그 기법하고 유사한 것 같다. 가상메모리와 실제 메모리(=하드디스크의 swap + 메모리)의 관계와 같이 LVM을 받아들여보자. 가상디스크와 실제 디스크로 나뉘어졌다고 보는 것이다. 가상메모리를 운영하기 위해서, "페이지"란 단위로 메모리를 관리하듯이, LVM도 "Extent"라는 것을 쓴다. 진짜 디스크 단위를 일정 크기의 Extent로 쪼갠 뒤(이들이 PE), 이들을 LVM의 적당한 논리적 Extent(LE)와 대응 관계를 짜면서 LVM을 유지하는 것이다.

공식 문서가 가장 정확하고(영어지만) 직관적인데, 비슷한 다른 개념을 예로 들어 설명하지 않아서 좀 어려웠다. 아마 필자가 이해한 바가 맞을 것이다 ㅡ,.ㅡ; 단순히, "LV와 PV는 extent라는 것으로 쪼개져 있다. 이 둘은 같은 크기를 갖는다"라고 적혀있기만 하면, 그게 서로 대응되는 관리 단위라는 것을 누가 이해하겠나 -_-;; 용량이 같다는 점에서 아마 이럴 것이다라고 필자가 page처럼 이해했다.

So...
VG는 그냥 디스크같이 다루면 된다는 것이군 어쨌든 -_-; LV는 "파티션"이기 때문에 ext3, ext4와 같은 파일시스템으로 "포멧"될 수 있다.

이제 실제로 두들겨보자.

진짜 디스크를 가지고 실험적인 "뻑내기"등을 해보기엔 무리가 있다. Virtual Box를 사용하고, 1GB 가상디스크 두개를 생성하여 실험을 진행했다. 운영체제는 40GB짜리 가상디스크에서 따로 놀도록 했다 -_-

Debian 5에서 시도해봤다.
# apt-get install lvm2
로 LVM 패키지를 설치했다. 설치할 때, 워낙 minimal 설치로 해서 이것도 없었음.

우선은, 파티션/디스크를(=PV) 잘게 쪼개서 LVM이 먹기 좋게 해줘야 하겠다. 그게 pvcreate 명령어이다.
# pvcreate /dev/hdb
# pvcreate /dev/hdd
디스크를 통째로 줘봐야겠다. 이미 파티션이 존재하면, 안 통한다. 디스크를 통짜로 주려면, 디스크에 파티션이 전혀 없어야만 한다. 그러나 LVM2 문서에 의하면, 디스크 전체를 파티션 없이 PV로 쓰지 말라고 한다. 왜? LVM을 지원 안하는 시스템이 이 디스크를 보면 아무것도 없는 줄 알기 때문이다. 그냥 거대한 파티션 하나만 만들고 들어가자. 다시했다.
pvremove /dev/hdb
pvremove /dev/hdd
이렇게 하면 pvcreate로 생성된 정보가 없어진다. fdisk로 디스크를 통째로 먹는 파티션을 만들고, 거기에 pvcreate를 했다.
pvcreate /dev/hdb1
pvcreate /dev/hdd1

생성했으니까... 이를 가상화 해보자 :D
# vgcreate ftp_volume /dev/hdb1 /dev/hdd1
이렇게 +_+; ftp_volume 이라는 볼륨의 이름에서 알 수 있듯이, FTP로 쓸 거대 volume이다... 비록 모의실험이지만 -_-

우선은 논리 파티션을, 마운트까지 해보자..
그런데 이렇게 처음부터 디스크를 다 LVM에 줘버리면, 실험이 재미없다고 생각한다. 우선은 디스크 한개만 줘보자.
# vgcreate ftp_volume /dev/hdb1
만들어졌다. 없애는 법도 매뉴얼에 있는데, 웬만해선 없앨 일이 없으니 따로 실험하진 않겠다;;

이제 이 가상디스크를 "포멧"해야지 쓸 수 있겠다. 포멧하기전에, "파티션"부터 만들어야 한다. lvcreate를 하자.
# lvcreate -L 1500 -n ftp_lv ftp_volume
이렇게 하면 ftp_volume에서 용량을 취해 ftp_lv라는 파티션(?)이 만들어진다. 비유와 LVM의 개념을 잘 대응시켜, 헷갈리지 않고 이 글을 보기 바란다. 제발; 용량은 1500MB이다. 용량을 몽땅 취하는 명령어는 없나...?

http://www.centos.org/docs/5/html/Cluster_Logical_Volume_Manager/LV_create.html
-L 15G 하면 15GB짜리.
-l 을 하면 percentage로 할당 가능.

lvcreate -l 100%FREE -n ftp_lv ftp_volume

이렇게 해도 되고,
# vgdisplay ftp_volume
... 생략 ...
Total PE 255
... 생략 ...
# lvcreate -l 255 -n ftp_lv ftp_volume
Total PE라는 항목이 있으니 그것을 읽어서 써도 된다. (디스크 조각(=extent) 255개...)

주의: 이렇게 만든 LV는 "Linear"하다. Stripe된 것을 만들려면 다른 매뉴얼을 보기 바란다. Stripe된 것은 필자가 원하는 사양이 아니다. 디스크가 박살날 수 있는 상황에서는 부적합하다. (파일 하나를, 여러 디스크에 분산저장하는 것이므로...)

lv도 없앨 수 있는데, 역시 필자의 환경에선 그럴 리 없으니 넘어간다.
아니다... create 방법을 달리 해보느라고 해봤다.
# lvremove /dev/ftp_volume/ftp_lv
이렇게 했다.

만들기는 했는데 mount도 하고, 쓰고싶다. -ㅠ-;; 그래야 실험이 진행이 되지.

mkfs로 하면 되나 -_-??!! 포멧부터 해야지 마운트가 되니까.
mkfs.ext4 /dev/ftp_volume/ftp_lv
ext4가 개발을 마치고... 2008년 크리스마스 기준으로 커널에 ext4가 들어갔다. 그리고 stable상태라고 함. 이 문서도 정말 따끈따근 하구만! 그리고 ext4로 전환하길 권장하는 단계까지 갔다. -_-; ext3보다 좀 빠르다고 한다. 안 해봐서 모르겠는데 (이 문서가 필자가 ext4를 처음 써본 것임)
그래서 ext4로 mkfs했다... 잘 된다 +_+;;

이제 마운트 단계.
# mkdir /mnt/ftproot
# mount /dev/ftp_volume/ftp_lv /mnt/ftproot
안 된다!!
mount: unknown filesystem type 'ext4'
라고 하소연한다... 커널엔 드갔고, mkfs.ext4도 있는데 마운트가 안 된다니, 이게 무슨 소리야? ... 2.6.28 커널부터 되는 사항이다. Debian 5에 있는 것은 2.6.26. 아직 조금 기다려야 되겠군. 물론 커널을 컴파일 하면 되지만, 패키지주의자인 필자가 그런 짓을 할 리 없다. 그냥 ext3로 하고, ext4가 되는 커널이 나오면, promote해야겠다. ext3로 mkfs한다음 다시 mount를 하니 잘 된다.

/etc/fstab에 평소 하드 추가하듯이 한 줄 적으면 잘 되더라. 재부팅해도...
재부팅하면, 이 만든 volume이 보이지 않아서 다시 activate해야 한다는데...
# vgchange -a y ftp_volume
비록 매뉴얼엔 이렇게 하라고 되어 있긴 하지만 말이다...;

디스크를 추가해 용량을 확장!
이제 이 디스크를 꽉 차게 만들 것이다. 1GB라 금방 채울 수 있다 -_- 영화 조금 저장하면 금방 꽉찬다. 음, 필자는 동영상 여러개를 용량 딱 맞게 올리기 귀찮아서,
cat 동영상 >> /mnt/ftproot/rnd
이렇게 했다. 꽉 찰때까지.
(1GB하드라니 1997년도 정도 하드가 이 정도 되려나? 그 이전에도 있던가;;)

이제 새 하드를 달아서 ㅋ_ㅋ 하드 공간을 확충해보자.
우선은 volume group에 디스크를 새로 달아서, 가상 디스크 용량 자체를 늘리고,
lv도 늘려서 파티션을 늘려야겠고, 늘어난 파티션에 맞게 파일시스템도 좀 변화시켜야 하겠다.

# pvcreate /dev/hdd1
근데 이건, hdd1 파티션임. 이미 된 과정이다. 이제 이것을 가상디스크에 추가하자.
# vgextend ftp_root /dev/hdd1
잘 되는구만.

이제 lv를 늘린다. 아까 쓴 수법임...
# vgdisplay ftp_volume
... 생략 ...
  Total PE              510
  Alloc PE / Size       255 / 1020.00 MB
  Free  PE / Size       255 / 1020.00 MB
... 생략... 여기서 255개의 PE가 남아도는걸 확인했음. 이것을 이미 있는 volume에 던져주자.

매뉴얼에 의하면, 마운트를 해제하고 작업하길 권한다. 특히나 ext시리즈의 파일시스템이면.
# umount 마운트한 디렉토리
# lvextend -l+255 /dev/ftp_volume/ftp_lv
-l뒤의 +옵션을 안 쓰면, 절대적 크기가 255 extend 단위로 된다는 것이다. 255가 추가되어 510 ext가 되는게 아니라 딱 255 ext가 되어버린다 ㅡ,.ㅡ;;

"파티션"이 크기 조절이 되긴 했으나 아직 df -h로 보면, 티가 안 난다. 파일시스템도 resize를 해줘야지 비로소 확장된 용량이 사용가능해지는 것이다. ext3나 ext2가 호환되기 때문에, resize2fs 이걸로 resize하게 된다 ㅋ_ㅋ;; 매뉴얼에 의하면, fsck를 한번 돌리고 하라고 권장하던데, 권장이 아니라, resize2fs가 강제로 시킨다 -_-;;; 체크해줄까? y/n 으로 묻는 것도 아니고, 이런 명령어를 쳐서 체크하라고 알려준다 -_-;;

# e2fsck -f /dev/ftp_volume/ftp_lv
# resize2fs /dev/ftp_volume/ftp_lv
그리고 다시 마운트.
# mount 어쩌구저쩌구
$ df -h
/dev/mapper/ftp_volume-ftp_lv
                      2.0G 1005M  902M  53% /mnt/ftproot
2GB로 불어났다. w00t +_+
디스크를 덧다는 실험은 성공으로 끝났다. +_+

파일도 무사히 다 있고...
lvm이 숨기고 있긴 하지만... 디스크 하나는  이미 가득찬 상태다. 이제 나머지 절반을 채우자.
현재는
영화1.avi
rnd ( 영화1의 일부로 찬 파일)
이렇게 있다. 영화1.avi외 다른걸 업로드 하기 귀찮...; 영화1을 복사해서 영화2.avi로 이름짓는다.
그리고, 영화2.avi의 내용용을, 아까 만든 rnd에 덧붙인다 (!)
cat 영화2.avi >> rnd
즉,,. rnd파일은 양쪽 디스크에 다 걸친 한 개의 파일이고, 영화1은 디스크 한개에, 영화2는 다른 디스크에 있는 파일아다. 이제 용량도 꽉 찼다...

단순히 디스크 늘리는 것은 이미 끝났고, 고장나면 어떻게 되나 체크해보자.
가상디스크를 제거하는 것이다. 후훗.

디스크 교체 실험.

영문 매뉴얼의 Removing an Old disk를 참고.

아... 망가뜨리는 실험을 하기 전에, 좀 얌전한 실험을 해보자. 이쯤에서, Virtual Box 스냅샷으로 실험 전의 모습을 저장해 두기로 했다. 디스크가 망가진 상황과, 교체하는 실험은 다른 상황인지라...

디스크 교체실험은 그냥 디스크가 낡아서, "갈아치울 때가 되었네" 하는 때에, 디스크를 한개씩 갈아끼우는 실험이다. 관리자가 감이 좋고 부지런하다면 이렇게 하겠지... 허나 돈이 많지 않은 서버에선 잘 안 되는 상황설정이기도 하다. (ㅋㅋ)

Virtual Box OSE로는 디스크가 3개까지만 되기 때문에, OS가 있는 디스크의 비OS 파티션까지 동원해야만 가능하다. -_-...; 필자는 OSE가 아닌 버전으로, 디스크를 하나 더 끼워서 실험.

새 디스크도 pvcreate로 준비하고, vgextend로 VG로 쓸 수 있는 놈이라고 신호를 준다.
vgdisplay로 보았을 때, free인 extent가 충분히 있어야함. 대체하려는 디스크의 extent 이상 필요하다.

새 디스크를 초기화하고, ftp_volume으로 쓸 수 있도록 던져준다.
# pvcreate /dev/sda1
# vgextend ftp_volume /dev/sda1
# vgdisplay
... 생략 ...
Free PE / Size 511
... 생략 ...
새로 단 디스크는 2GB짜리다 -_- 주로, 대체되는 디스크는 용량이 같다기 보단, 크지 않은가? 시간이 지난 후 디스크 교체가 일어나니깐. 이제, 디스크 hdd를 대체하려면... free extent쪽으로 자료를 이전하라는 명령을 내려야 하겠다.

# pvmove /dev/hdd1
hdd1의 자료가 이동되는 것이다!!! 디스크 전체의 자료를 다른 곳으로 이사시키는 것이니 당연히, 오래 걸린다 -_-;; 1GB의 소용량으로 테스트 하는게 다 이유가 있는 것이지. 자료를 이사시켰으면, 디스크도 volume에서 제거한다.
# vgreduce ftp_volume /dev/hdd1
을 하면 디스크가 volume에서 빠져나간다. vgdisplay로 확인해보면, Total PE도 줄어들어 있다 -_-;; 당연하다.

토탈 용량은 3GB여야 하는데, 여전히 ftproot는 2GB이다. 위의 용량 늘리기 작업을 하면 다시 늘어나니 걱정 말자. lvextend한 뒤 resize2fs 하는거...

디스크 고장 실험
디스크가 고장난 뒤, 소잃고 외양간 고치는 실험이다. 자료는 어느정도 날아가지만, 고장난 디스크 이외의 자료는 살아있어야 한다. 필자가 원하는 바가 이것임;

디스크 한 개가 고장나고, 그 고장난 한 개를, 조금 더 큰 디스크로 교체하는 상황을 해보자.

Virtual Box에서, 고장난 디스크를 simulate하기 위해, 디스크 하나를 구성에서 빼버린다. 첫번째로 단 디스크 말고, 두번째로 단 디스크를 죽였다. 그러면 원래 있던 영화1.avi는 멀쩡해야 된다. rnd는... 양 디스크에 있으니 죽을테고, 영화2.avi는 당연히 손실되어야하겠다.

하드웨어를 좀 방법했으니 이제 SW가 어떻게 대응하는지, 부팅을 해본다. 당연히, /mnt/ftproot엔 아무것도 없다. 왜냐면, 디스크가 빠져서, LV자체가, 현재는 error로 마킹 되어서, 마운트되지 아니하였기 때문이다.

# vgdisplay
  Couldn't find device with uuid 'H7ZZ5i-tAyM-Tnfw-12Wq-AJwL-SMYc-zKdr4A'.
  Couldn't find all physical volumes for volume group ftp_volume.
  Couldn't find device with uuid 'H7ZZ5i-tAyM-Tnfw-12Wq-AJwL-SMYc-zKdr4A'.
  Couldn't find all physical volumes for volume group ftp_volume.
  Volume group "ftp_volume" not found
이제 다음단계. 있는 자료라도 mount하게...

http://www.novell.com/coolsolutions/appnote/19386.html
Disk Permanently Removed
이런 상황이다. 훗.

해결책은... 없다는 UUID의 PV를 pvcreate로 만들어줘서 교체할 놈으로 던져주는 것이다.
# pvcreate --uuid H7ZZ5i-tAyM-Tnfw-12Wq-AJwL-SMYc-zKdr4A /dev/sda1
만들었으니... vgdisplay가 통하긴 한다. 자료가 온전한지는 다른 문제.

# vgcfgbackup
매일매일, vgcfgbackup으로 백업을 해두고 있었다고 가정한다. ㅠㅠ.. 이걸 안 하면 좀 곤란한 모양이다? 다른 parameter도 필요 없으니 제발 실행해두라 규칙적으로. cron 같은 것으로. LVM metadata가 뭣에 쓰는지 테크니컬한 자료는 못 찾겠다 -_- 역시 개념 공부를 좀 하고 싶은데...

# vgcfgrestore ftp_volume (백업해둔 meta data를 다시 restore시킨다)
# vgscan (스캔 돌려주고)
# vgchange -ay ftp_volume (activate시킨다. /dev/ftp_volume이 보이도록 한다)

파일시스템도 체크해야 한다.
# fsck -y /dev/ftp_volume/ftp_lv
됐다. 어느정도 살아날 것이다...

무서운 것은. 영화2.avi가 보이긴 한다는 것이다. 용량도 있을대로 다 있다. 하지만... 재생이 안 된다(=손상되었다). 무엇이 손상되고, 무엇이 아닌지 모른다는게 가장 무서운 듯 하다. 아무래도, 평소에 모든 파일에 대한 체크섬이라도 두어서, corrupt되었는지 안 되었는지 나중에 대조할 수 있게 하는 것이 좋을 듯 하다.

metadata를 저장하지 않고 하면 어떻게 되지 -_-? 그래도 비슷한 결과가 나온다. /etc/lvm/ 의 어딘가에 백업되어서 흐음... 백업을 안 했으면 vgcfgrestore만 생략하면 된다. (backup을 안 했으니 restore할 것도 없으니)