← สารบัญบทเรียน M9 · Storage 2 — LVM
M9 · หัวข้อสอบ

Storage 2 — LVM ที่ขยายได้ตามใจ

พาร์ติชันธรรมดาในบท M8 เหมือนกล่องที่ตอกตะปูปิดตาย — อยากเพิ่มที่ทีหลังลำบากมาก บทนี้จะสอน LVM ระบบที่ออกแบบมาให้ “ขยาย/ย่อพื้นที่ได้ตลอด” แม้ตอนเครื่องกำลังทำงานอยู่ และนี่คือหัวใจของข้อสอบ storage

🌱 ต่อจาก M8 — ถ้ายังไม่รู้จัก partition แนะนำให้อ่าน M8 ก่อน

1ทำไมต้องมี LVM?

ในบท M8 เราสร้าง พาร์ติชันธรรมดา ขึ้นมา — มันทำงานได้ดี แต่มีปัญหาใหญ่อยู่อย่างหนึ่ง: ขยายยากมาก สมมุติคุณแบ่งพาร์ติชันไว้ 10 GB แล้ววันหนึ่งข้อมูลเต็ม อยากเพิ่มเป็น 15 GB... พาร์ติชันธรรมดามักจะติดตรงที่ว่าพื้นที่ว่างที่เหลือไม่ได้ “อยู่ติดกัน” กับพาร์ติชันเดิมพอดี ทำให้ขยายไม่ได้ง่ายๆ บางทีต้องลบแล้วสร้างใหม่ ซึ่งเสี่ยงข้อมูลหาย

LVM (Logical Volume Manager) เกิดมาเพื่อแก้ปัญหานี้โดยเฉพาะ มันใส่ “ชั้นกลาง” คั่นระหว่างดิสก์จริงกับพื้นที่ที่เราเอาไปใช้ ทำให้:

🎯 ทำไมเรื่องนี้สำคัญกับข้อสอบ

โจทย์ storage ของ RHCSA ชอบสั่งให้ “สร้าง logical volume ขนาด X แล้ว mount ที่ Y” และที่ออกบ่อยกว่านั้นคือ “ขยาย logical volume เดิมให้ใหญ่ขึ้น” — ถ้าคุณทำ LVM คล่อง คะแนนส่วน storage แทบจะอยู่ในกระเป๋าแล้ว

23 ชั้นของ LVM: PV → VG → LV

LVM ฟังดูซับซ้อน แต่จริงๆ มีแค่ 3 ชั้น ที่ต้องเข้าใจ ขอให้จำลำดับนี้ให้ขึ้นใจ เพราะทุกคำสั่งในบทนี้จะวนอยู่กับ 3 ตัวนี้:

PV
Physical Volume = ดิสก์หรือพาร์ติชัน “ดิบ” ที่เราเอามาขึ้นทะเบียนเข้าระบบ LVM (เช่น /dev/sdb1)
VG
Volume Group = เอา PV หลายก้อนมารวมเป็น “สระน้ำ” ก้อนใหญ่ก้อนเดียว
LV
Logical Volume = ตักพื้นที่จากสระมาทำเป็น “ถังย่อย” ที่เราเอาไป mkfs แล้ว mount ใช้งานจริง
💡 เปรียบเทียบ: ถังน้ำ → สระ → แก้ว

นึกภาพระบบน้ำในบ้านแบบนี้:

PV = ถังน้ำหลายใบ ที่คุณซื้อมา แต่ละใบคือดิสก์/พาร์ติชัน 1 ก้อน
VG = สระรวม ที่คุณเทน้ำจากทุกถังลงไป — ตอนนี้น้ำทั้งหมดกองรวมเป็นก้อนเดียว ไม่สนแล้วว่ามาจากถังไหน
LV = แก้วน้ำ ที่คุณตักจากสระมาใช้ดื่ม (เอาไป mkfs + mount)

จุดเด็ดอยู่ตรงนี้: คุณขยายแก้วให้ใหญ่ขึ้นได้เรื่อยๆ ตราบใดที่สระยังมีน้ำเหลือ และถ้าสระเริ่มจะหมด ก็แค่ซื้อถังใบใหม่ (ดิสก์ใหม่) มาเทเติมลงสระ — ง่ายแค่นั้นเอง

📐 ภาพรวม 3 ชั้น เรียงจากล่างขึ้นบน
  LV  lvdata (2G)   LV  lvweb (3G)    ← ถังย่อยที่เอาไปใช้จริง (mkfs+mount)
  ─────────────────────────────────
         VG  vgdata               ← สระรวม (พื้นที่กองรวมกัน)
  ─────────────────────────────────
  PV /dev/sdb1      PV /dev/sdc1   ← ดิสก์/พาร์ติชันดิบ

อ่านจากล่างขึ้นบน: ดิสก์ดิบ (PV) → เทรวมเป็นสระ (VG) → ตักออกมาเป็นถัง (LV) เวลาทำงานจริงเราก็สร้างเรียงตามลำดับนี้พอดี

3สร้าง LVM ทีละขั้น

สมมุติเรามีดิสก์ลูกใหม่ และทำพาร์ติชัน /dev/sdb1 ไว้แล้ว (จากบท M8) ตอนนี้จะเปลี่ยนมันเป็น LVM ที่ใช้งานได้จริง ทำตามลำดับ PV → VG → LV → mkfs → mount

ขั้น 1: pvcreate — ขึ้นทะเบียนดิสก์เป็น PV

⌨️ สร้าง Physical Volume
[root@server1 ~]# pvcreate /dev/sdb1
  Physical volume "/dev/sdb1" successfully created.

บอก LVM ว่า “เอาก้อนนี้มาเป็นถังน้ำของเรานะ” — ตอนนี้ /dev/sdb1 พร้อมเข้าสระแล้ว

ขั้น 2: vgcreate — สร้างสระแล้วเทถังลงไป

⌨️ สร้าง Volume Group ชื่อ vgdata
[root@server1 ~]# vgcreate vgdata /dev/sdb1
  Volume group "vgdata" successfully created
vgdataชื่อสระที่เราตั้งเอง (จะเรียกชื่อนี้ตลอดบทนี้)
/dev/sdb1PV ที่จะเทลงสระ — ใส่ได้หลายก้อน เว้นวรรคคั่น

ขั้น 3: lvcreate — ตักน้ำจากสระมาเป็นถังย่อย

⌨️ สร้าง Logical Volume ขนาด 2G
[root@server1 ~]# lvcreate -L 2G -n lvdata vgdata
  Logical volume "lvdata" created.
-L 2Gขนาดที่ต้องการ (L ใหญ่ = ระบุเป็น “หน่วยขนาด” เช่น 2G, 500M)
-n lvdataชื่อของ LV ที่เราตั้ง
vgdataตักมาจากสระไหน (ต้องบอกชื่อ VG เสมอ)
💡 -L กับ -l ต่างกันนะ (สังเกตตัวพิมพ์ใหญ่/เล็ก)

-L (ใหญ่) = ระบุ “ขนาดจริง” เช่น -L 2G
-l (เล็ก) = ระบุ “เปอร์เซ็นต์หรือจำนวน extent” เช่น -l 50%FREE (เอา 50% ของพื้นที่ว่าง) หรือ -l 100%FREE (เอาที่เหลือทั้งหมด) — มีประโยชน์มากตอนสอบเมื่อโจทย์บอกเป็นเปอร์เซ็นต์

ขั้น 4: mkfs — สร้างระบบไฟล์ลงในถัง

⌨️ ฟอร์แมตเป็น XFS
[root@server1 ~]# mkfs.xfs /dev/vgdata/lvdata
meta-data=/dev/vgdata/lvdata  isize=512  ...
...

สังเกต path ของ LV: /dev/ชื่อVG/ชื่อLV = /dev/vgdata/lvdata — จำรูปแบบนี้ให้ขึ้นใจ (มี path อีกแบบคือ /dev/mapper/vgdata-lvdata ซึ่งหมายถึงอันเดียวกัน)

ขั้น 5: mkdir + mount

⌨️ สร้างจุด mount แล้วเอาไปแขวน
[root@server1 ~]# mkdir /data
[root@server1 ~]# mount /dev/vgdata/lvdata /data
[root@server1 ~]# df -h /data
Filesystem                  Size  Used Avail Use% Mounted on
/dev/mapper/vgdata-lvdata   2.0G   47M  2.0G   3% /data

ตอนนี้ /data ใช้งานได้แล้ว! แต่ mount แบบนี้หายเมื่อ reboot — ต้องใส่ลง /etc/fstab ด้วย (ดูข้อ 9)

4ดูสถานะ: pvs / vgs / lvs

แต่ละชั้นมีคำสั่งดูสถานะของตัวเอง จำง่ายๆ ว่า ลงท้ายด้วย s = ดูแบบ สรุปสั้น (ใช้บ่อยสุด) ส่วนลงท้ายด้วย display = ดูแบบ ละเอียดเต็ม

⌨️ ดูทั้ง 3 ชั้นแบบสรุป
[root@server1 ~]# pvs
  PV         VG     Fmt  Attr PSize  PFree
  /dev/sdb1  vgdata lvm2 a--  <5.00g <3.00g

[root@server1 ~]# vgs
  VG     #PV #LV #SN Attr   VSize  VFree
  vgdata   1   1   0 wz--n- <5.00g <3.00g

[root@server1 ~]# lvs
  LV     VG     Attr       LSize
  lvdata vgdata -wi-ao---- 2.00g
pvsดู PV ทั้งหมด — คอลัมน์ PFree = พื้นที่ว่างในดิสก์ก้อนนั้น
vgsดู VG — คอลัมน์ VFree = น้ำที่เหลือในสระ (สำคัญตอนจะขยาย LV!)
lvsดู LV — คอลัมน์ LSize = ขนาดถังตอนนี้
💡 lsblk เห็นภาพทั้งต้นไม้

lsblk แสดงดิสก์ → พาร์ติชัน → LVM ซ้อนกันเป็นชั้นๆ ทำให้เห็นภาพรวมว่าอะไรซ้อนอยู่บนอะไร ลองพิมพ์ดูบ่อยๆ จะเข้าใจโครงสร้างเร็วขึ้นมาก ส่วน pvdisplay / vgdisplay / lvdisplay ใช้เมื่ออยากดูรายละเอียดลึกของแต่ละชั้น

5ขยาย LV — ข้อนี้ออกสอบบ่อยที่สุด!

นี่คือหัวใจที่แท้จริงของบทนี้ โจทย์มักจะให้ “ขยาย logical volume เดิมให้ใหญ่ขึ้น” การขยายมี 2 ขั้นตอนที่ต้องทำทั้งคู่ — และมือใหม่มักลืมขั้นที่ 2 จนพื้นที่ไม่เพิ่มจริง

💡 ทำไมต้อง 2 ขั้น

นึกภาพ ถังน้ำที่หุ้มด้วยพลาสติกแร็ป — การ lvextend = ขยาย “ตัวถัง” ให้ใหญ่ขึ้น แต่พลาสติกแร็ปที่หุ้มอยู่ (ตัว filesystem) ยังเท่าเดิม! คุณต้อง “ขยายแร็ปตามไปด้วย” ระบบไฟล์ถึงจะใช้พื้นที่ใหม่ได้จริง

ขั้น 1: lvextend — ขยายตัว LV

⌨️ เพิ่มอีก 1G (มีเงื่อนไข: สระต้องมีน้ำเหลือ)
[root@server1 ~]# lvextend -L +1G /dev/vgdata/lvdata
  Size of logical volume vgdata/lvdata changed from 2.00 GiB to 3.00 GiB.
  Logical volume vgdata/lvdata successfully resized.
-L +1Gมีเครื่องหมาย + = “เพิ่มอีก 1G จากของเดิม” (เดิม 2G → เป็น 3G)
-L 5Gไม่มี + = “ตั้งขนาดใหม่ให้เป็น 5G” (ระบุปลายทางตรงๆ)
-l +100%FREEดูดน้ำที่เหลือในสระทั้งหมดมาใส่ถังนี้

ขั้น 2: ขยาย filesystem — อย่าลืมเด็ดขาด!

ขั้นนี้ คำสั่งต่างกันตามชนิด filesystem ดูให้ดี:

⌨️ ถ้าเป็น XFS — ใช้ xfs_growfs กับ “จุด mount”
[root@server1 ~]# xfs_growfs /data
data blocks changed from 524288 to 786432

XFS ขยายโดยอ้าง จุด mount (/data) ไม่ใช่ path ของ device — และ XFS ขยายได้อย่างเดียว ย่อไม่ได้

⌨️ ถ้าเป็น ext4 — ใช้ resize2fs กับ “path ของ device”
[root@server1 ~]# resize2fs /dev/vgdata/lvdata
Resizing the filesystem on /dev/vgdata/lvdata to 786432 (4k) blocks.

ext4 ขยายโดยอ้าง path ของ device ไม่ใช่จุด mount — สลับกับ XFS พอดี ระวังสับสน

⚡ ทางลัดที่ควรจำขึ้นใจ: lvextend -r

option -r (resize filesystem) จะทำ ทั้งสองขั้นในคำสั่งเดียว — LVM ดูเองว่าเป็น XFS หรือ ext4 แล้วเรียกคำสั่งขยาย filesystem ที่ถูกต้องให้อัตโนมัติ:

[root@server1 ~]# lvextend -r -L +1G /dev/vgdata/lvdata

ในห้องสอบ ใช้ -r ทุกครั้งจะปลอดภัยที่สุด เพราะลืมขั้นที่ 2 ไม่ได้เลย — คำสั่งเดียวจบ

📌 ตรวจงานเสมอด้วย df -h

หลังขยายเสร็จ พิมพ์ df -h /data ดูว่าตัวเลข Size โตขึ้นจริง ถ้า lvs บอกว่า LV ใหญ่ขึ้นแล้วแต่ df ยังเท่าเดิม = คุณลืมขยาย filesystem (ขั้นที่ 2)

6VG เต็ม? เติมดิสก์ใหม่เข้าไป

ถ้าจะขยาย LV แต่ vgs บอกว่า VFree เหลือ 0 (น้ำในสระหมด) คุณต้อง เติมดิสก์ใหม่ลงสระก่อน ทำ 2 ขั้น: สร้าง PV ใหม่ แล้วเทเข้า VG เดิม

⌨️ เพิ่มดิสก์ /dev/sdc1 เข้าสระ vgdata
[root@server1 ~]# pvcreate /dev/sdc1
  Physical volume "/dev/sdc1" successfully created.
[root@server1 ~]# vgextend vgdata /dev/sdc1
  Volume group "vgdata" successfully extended
[root@server1 ~]# vgs
  VG     #PV #LV #SN Attr   VSize   VFree
  vgdata   2   1   0 wz--n- <10.00g 7.00g
pvcreateขึ้นทะเบียนดิสก์ก้อนใหม่ (เหมือนข้อ 3 ขั้น 1)
vgextendเทถังใหม่ลงสระเดิม — สังเกต VFree เพิ่มขึ้น และ #PV เป็น 2

พอสระมีน้ำแล้ว ก็กลับไปทำ lvextend -r (ข้อ 5) ขยายถังได้ตามปกติ

7PE คืออะไร (รู้ไว้สั้นๆ พอ)

เวลาดู vgdisplay จะเจอคำว่า PE ย่อมาจาก Physical Extent = หน่วยก้อนเล็กที่สุดที่ LVM ใช้แบ่งพื้นที่ ค่ามาตรฐานคือ 4 MB ต่อ 1 extent

💡 เปรียบเทียบ

PE เหมือน “อิฐก้อนมาตรฐาน” — น้ำในสระจริงๆ ถูกหั่นเป็นอิฐก้อนละ 4 MB เวลาตักไปทำถัง (LV) ก็คือเอาอิฐมาเรียงต่อกัน ตอนสอบไม่ต้องคำนวณ PE เอง แค่รู้ว่ามันคือหน่วยย่อยของ LVM ก็พอ (นั่นคือเหตุผลที่ -l ระบุเป็น “จำนวน extent” ได้)

8swap บน LVM

คุณเอา LV ไปทำเป็น swap (พื้นที่ช่วยจำเมื่อ RAM เต็ม) ได้ด้วย ขั้นตอนคล้ายเดิม แค่เปลี่ยนจาก mkfs เป็น mkswap

⌨️ สร้าง LV แล้วทำเป็น swap
[root@server1 ~]# lvcreate -L 1G -n lvswap vgdata
[root@server1 ~]# mkswap /dev/vgdata/lvswap
[root@server1 ~]# swapon /dev/vgdata/lvswap
[root@server1 ~]# swapon --show
NAME                  TYPE      SIZE USED PRIO
/dev/dm-1             partition 1024M   0B   -2
mkswapฟอร์แมต LV ให้เป็นรูปแบบ swap
swaponเปิดใช้งาน swap ก้อนนี้ทันที
📌 swap ก็ต้องใส่ fstab เหมือนกัน

เพื่อให้ swap เปิดเองหลัง reboot ต้องเพิ่มบรรทัดใน /etc/fstab โดยใช้คอลัมน์ที่ 2 เป็น swap และคอลัมน์ที่ 3 เป็น swap เช่นกัน:

/dev/vgdata/lvswap   none   swap   defaults   0 0

9ทำให้อยู่ถาวรหลัง reboot (สำคัญที่สุด)

คำสั่ง mount ที่เราพิมพ์มือ หายหมดเมื่อ reboot — เหมือนบท M8 เป๊ะ LV ที่สร้างต้องถูกบันทึกลง /etc/fstab ด้วย ไม่งั้นพอเครื่องรีสตาร์ตในห้องสอบ งานคุณจะหายและได้ 0 คะแนน

⌨️ เพิ่มบรรทัดใน /etc/fstab
# ใช้ path ของ LV (อ่านง่าย แนะนำสำหรับ LVM)
/dev/vgdata/lvdata   /data   xfs   defaults   0 0

# หรือจะใช้ UUID ก็ได้ (หาด้วย: blkid /dev/vgdata/lvdata)
UUID=abc123...   /data   xfs   defaults   0 0

สำหรับ LVM การใช้ path /dev/vgdata/lvdata ใน fstab ทำได้และอ่านง่าย (ต่างจากพาร์ติชันธรรมดาที่แนะนำ UUID) เพราะชื่อ VG/LV ไม่เปลี่ยนเหมือนชื่อ /dev/sdb

🎯 ขั้นตอนทดสอบที่ห้ามข้าม — ทำก่อน reboot เสมอ

หลังแก้ /etc/fstab ให้ umount /data แล้วพิมพ์ mount -a (mount ทุกอย่างใน fstab) ถ้า ไม่มี error = บรรทัดของคุณถูกต้อง พิมพ์ df -h /data ยืนยันอีกที

ถ้าพิมพ์ผิดใน fstab แล้วไม่ทดสอบ เครื่องอาจ บูตไม่ขึ้น ทำ mount -a เพื่อจับ error ตั้งแต่ตอนนี้เสมอ — นี่คือนิสัยที่ช่วยชีวิตในห้องสอบ

10ข้อผิดพลาดที่ทำสอบตก

11สรุปคำสั่งบทนี้ (Cheat Sheet)

คำสั่งทำอะไร
pvcreate /dev/sdb1ขึ้นทะเบียนดิสก์/พาร์ติชันเป็น PV
vgcreate vgdata /dev/sdb1สร้าง VG (สระ) จาก PV
vgextend vgdata /dev/sdc1เติม PV ใหม่ลง VG เดิม (สระน้ำเพิ่ม)
lvcreate -L 2G -n lvdata vgdataสร้าง LV ขนาด 2G ชื่อ lvdata
lvcreate -l 50%FREE -n lvx vgdataสร้าง LV เอา 50% ของพื้นที่ว่าง
mkfs.xfs /dev/vgdata/lvdataฟอร์แมต LV เป็น XFS
mount /dev/vgdata/lvdata /dataเอา LV ไป mount (ชั่วคราว)
pvs / vgs / lvsดูสถานะแต่ละชั้นแบบสรุป
lsblkดูภาพรวมดิสก์ → พาร์ติชัน → LVM
lvextend -r -L +1G /dev/vgdata/lvdataขยาย LV + filesystem ในคำสั่งเดียว
xfs_growfs /dataขยาย filesystem XFS (อ้างจุด mount)
resize2fs /dev/vgdata/lvdataขยาย filesystem ext4 (อ้าง device)
mkswap + swaponทำ LV เป็น swap แล้วเปิดใช้
mount -aทดสอบ /etc/fstab (ทำก่อน reboot เสมอ)
✅ จบบทนี้คุณควรทำได้

สร้าง LVM จากศูนย์ได้ครบลำดับ (pvcreatevgcreatelvcreatemkfs → mount) → ขยาย LV พร้อม filesystem ได้ด้วย lvextend -r → เติมดิสก์เข้า VG เมื่อสระเต็ม → และใส่ทุกอย่างลง /etc/fstab แล้วทดสอบด้วย mount -a ก่อน reboot ครบนี้ = พิชิตส่วน storage ของข้อสอบได้สบาย!