Cơ bản

LVM trong Linux: physical volume, volume group và logical volume thực tế

Cập nhật: · Skillaria.Top

LVM (Logical Volume Manager) trong Linux là lớp nằm giữa ổ đĩa và hệ thống tệp: các ổ được biến thành physical volume (PV), gộp thành volume group (VG), từ đó cắt ra logical volume (LV) với kích thước tùy ý. Lợi thế chính là có thể mở rộng ổ ngay khi đang chạy bằng lvextend -r, thêm ổ mới vào nhóm mà không dừng dịch vụ, và tạo snapshot trước một thao tác rủi ro.

LVM (Logical Volume Manager) là trình quản lý ổ logic trong Linux, tách hệ thống tệp khỏi ổ đĩa vật lý. Thay vì gắn cứng /var vào phân vùng /dev/sdb1, bạn gom các ổ vào một vùng chung và cắt từ đó các ổ logic với kích thước cần thiết. Khi thiếu chỗ, ổ logic có thể lớn thêm chỉ bằng một lệnh, không cần khởi động lại và không cần dừng dịch vụ. Dưới đây giải thích LVM trong Linux được tổ chức ra sao, cách tạo ổ từ đầu, mở rộng, tạo snapshot và tránh mất dữ liệu ở những lỗi hay gặp.

Vì sao cần LVM khi đã có phân vùng thông thường

Phân vùng thông thường là một đoạn liên tục trên một ổ đĩa. Kích thước được chọn khi phân vùng ổ, và chỉ có thể tăng nếu ngay sau nó còn chỗ trống. Khi ổ đã đầy, bạn phải mua ổ mới, chuyển dữ liệu, sửa /etc/fstab, và dừng dịch vụ trong suốt thời gian đó.

LVM giải quyết ba việc:

  • Kích thước linh hoạt. Ổ logic có thể tăng (và với ext4 còn có thể giảm) bất cứ lúc nào.
  • Gộp nhiều ổ. Nhiều ổ vật lý trở thành một vùng chung; một ổ logic có thể nằm trên hai ổ đĩa cùng lúc.
  • Snapshot. Ảnh chụp tức thời của ổ logic trước khi nâng cấp, di chuyển cơ sở dữ liệu hay thực hiện thao tác rủi ro khác.

Vì vậy trình cài đặt Ubuntu Server, RHEL, Rocky và AlmaLinux thường bật LVM mặc định, và trên máy chủ chứa dữ liệu hầu như luôn dùng LVM.

Ba tầng của LVM: PV, VG và LV

Toàn bộ logic của LVM gói trong ba khái niệm. Một cách hình dung: các ổ đĩa là bao bột, nhóm là kho chung, còn ổ logic là các phần bột bạn lấy ra từ kho.

TầngÝ nghĩaVí dụ tênTạo bằng lệnh
PV (Physical Volume)ổ hoặc phân vùng đã được đánh dấu dùng cho LVM/dev/sdb, /dev/sdc1pvcreate
VG (Volume Group)vùng chung gộp một hoặc nhiều PVdata_vgvgcreate
LV (Logical Volume)ổ được cắt từ VG; trên đó tạo hệ thống tệp/dev/data_vg/applvcreate

Bên trong VG, dung lượng được chia thành các extent (PE, physical extent) có kích thước cố định, mặc định 4 MiB. Ổ logic chỉ là tập hợp các extent, và các extent này không nhất thiết liền nhau, có thể nằm trên các ổ khác nhau. Chính vì thế ổ logic rất dễ mở rộng: LVM chỉ cần gán thêm extent trống từ bất kỳ đâu.

Thiết bị của ổ logic có thể truy cập qua hai đường dẫn tương đương: /dev/data_vg/app và /dev/mapper/data_vg-app. Bên dưới là thiết bị device-mapper của kernel.

Xem những gì đang có

Trước hết đảm bảo đã cài gói: trên Debian và Ubuntu là lvm2 (sudo apt install lvm2), còn họ RHEL thì có sẵn. Để xem tổng quan có các lệnh ngắn gọn và chi tiết:

$ sudo pvs
  PV         VG      Fmt  Attr PSize   PFree
  /dev/sdb   data_vg lvm2 a--  <20.00g      0
  /dev/sdc   data_vg lvm2 a--  <20.00g  <10.00g

$ sudo vgs
  VG      #PV #LV #SN Attr   VSize  VFree
  data_vg   2   1   0 wz--n- 39.99g <10.00g

$ sudo lvs
  LV   VG      Attr       LSize  Pool Origin Data%  Meta%
  app  data_vg -wi-ao---- 30.00g

Thông tin chi tiết có trong pvdisplay, vgdisplay và lvdisplay. Bức tranh toàn cảnh cùng các phân vùng thường thì xem bằng lsblk: ổ logic hiện với loại lvm.

$ lsblk /dev/sdb /dev/sdc
NAME             MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb                8:16   0  20G  0 disk
└─data_vg-app    253:0    0  30G  0 lvm  /srv/app
sdc                8:32   0  20G  0 disk
└─data_vg-app    253:0    0  30G  0 lvm  /srv/app

Có thể thấy ổ app 30 GB nằm đồng thời trên hai ổ 20 GB. Với phân vùng thông thường thì không làm được như vậy.

LVM từ đầu: từ ổ trắng đến ổ đã gắn

Giả sử máy chủ vừa được thêm một ổ trống /dev/sdb, và ứng dụng cần một ổ logic 15 GB. Hãy kiểm tra tên ổ bằng lsblk hai lần: mọi lệnh dưới đây đều xóa dữ liệu trên thiết bị được chỉ định.

Bước 1. Tạo physical volume

$ sudo pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created.

Có thể đưa cả ổ cho LVM, hoặc trước tiên tạo phân vùng bằng fdisk hay parted với kiểu «Linux LVM» rồi chỉ định phân vùng (/dev/sdb1). Cách dùng phân vùng dễ hiểu hơn với các quản trị viên khác, giúp tránh việc ghi nhầm bảng phân vùng lên ổ đang thuộc LVM; còn đưa cả ổ thì dễ mở rộng hơn trên đám mây.

Bước 2. Tạo volume group

$ sudo vgcreate data_vg /dev/sdb
  Volume group "data_vg" successfully created

Bước 3. Cắt ổ logic

$ sudo lvcreate -n app -L 15G data_vg
  Logical volume "app" created.

Tùy chọn -L đặt kích thước tuyệt đối, còn -l đặt theo số extent hoặc phần trăm: -l 100%FREE lấy toàn bộ phần trống của nhóm, -l 50%VG lấy một nửa nhóm. Nên để lại một khoảng trống trong VG: sau này có thể cấp thêm cho ổ nào đó hoặc dùng cho snapshot.

Bước 4. Hệ thống tệp và gắn ổ

$ sudo mkfs.ext4 /dev/data_vg/app
$ sudo mkdir -p /srv/app
$ sudo mount /dev/data_vg/app /srv/app
$ df -h /srv/app
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/data_vg-app   15G   24K   14G   1% /srv/app

Để ổ được gắn lại sau khi khởi động, thêm một dòng vào /etc/fstab. Với ổ logic, đường dẫn /dev/mapper/... ổn định, nên có thể dùng nó hoặc UUID lấy từ blkid:

/dev/mapper/data_vg-app  /srv/app  ext4  defaults  0 2

Kiểm tra dòng này bằng sudo mount -a trước khi khởi động lại: lỗi trong fstab có thể khiến máy chủ rơi vào chế độ khẩn cấp.

Cách mở rộng ổ LVM mà không dừng dịch vụ

Đây là lý do chính để dùng LVM. Ổ được mở rộng ngay trên hệ thống tệp đang gắn, và ứng dụng vẫn tiếp tục ghi dữ liệu. Cách làm phụ thuộc vào việc nhóm còn chỗ trống hay không.

Nếu VG còn chỗ trống

$ sudo vgs data_vg
  VG      #PV #LV #SN Attr   VSize   VFree
  data_vg   1   1   0 wz--n- <20.00g <5.00g

$ sudo lvextend -r -L +4G /dev/data_vg/app
  Size of logical volume data_vg/app changed from 15.00 GiB to 19.00 GiB.
  Logical volume data_vg/app successfully resized.
resize2fs 1.47.0
Filesystem at /dev/mapper/data_vg-app is mounted on /srv/app; on-line resizing required

Tùy chọn quan trọng là -r (--resizefs): ngay sau khi tăng ổ, nó mở rộng luôn hệ thống tệp. Không có -r, ổ đã lớn lên nhưng df -h vẫn hiện kích thước cũ, vì hệ thống tệp chưa biết về phần dung lượng mới. Đây là lỗi hay gặp nhất: khi đó chỉ cần chạy tay resize2fs với ext4 hoặc xfs_growfs với XFS.

$ sudo resize2fs /dev/data_vg/app      # ext4, truyền thiết bị
$ sudo xfs_growfs /srv/app             # XFS, truyền điểm gắn

Lưu ý sự khác nhau: -L +4G thêm 4 GB, còn -L 4G đặt tổng dung lượng là 4 GB. Để cấp toàn bộ phần còn lại cho ổ, dùng -l +100%FREE.

Nếu VG hết chỗ: thêm ổ mới

Gắn ổ mới (trên đám mây thì đính kèm thêm volume), tìm nó bằng lsblk, rồi đưa vào nhóm:

$ sudo pvcreate /dev/sdc
$ sudo vgextend data_vg /dev/sdc
  Volume group "data_vg" successfully extended
$ sudo lvextend -r -l +100%FREE /dev/data_vg/app

Ba lệnh, không có thời gian dừng. Từ giờ hệ thống tệp nằm trên hai ổ, còn ứng dụng không hề nhận ra điều đó.

Nếu ổ đã được tăng dung lượng trên đám mây

Trên đám mây thường đơn giản hơn nếu không thêm ổ mà tăng dung lượng ổ hiện có. Khi đó kernel sẽ thấy kích thước mới, và phải mở rộng physical volume bằng pvresize:

$ sudo pvresize /dev/sdb
  Physical volume "/dev/sdb" changed
$ sudo lvextend -r -l +100%FREE /dev/data_vg/app

Nếu PV được tạo trên phân vùng (/dev/sdb1), trước tiên mở rộng phân vùng, ví dụ bằng growpart /dev/sdb 1 từ gói cloud-guest-utils, rồi mới chạy pvresize /dev/sdb1.

Có thể thu nhỏ ổ LVM không

Có thể, nhưng không phải với mọi hệ thống tệp và không thể làm khi đang chạy. XFS không hỗ trợ thu nhỏ — chỉ có thể tạo lại và chuyển dữ liệu. Ext4 thu nhỏ được, nhưng chỉ khi đã gỡ gắn:

$ sudo umount /srv/app
$ sudo lvreduce -r -L 10G /dev/data_vg/app

Với -r, LVM tự kiểm tra hệ thống tệp (e2fsck) và thu nó lại trước khi thu ổ. Không có -r, rất dễ cắt ổ nhỏ hơn hệ thống tệp và làm hỏng dữ liệu. Trước khi thu nhỏ luôn phải sao lưu.

Snapshot LVM: ảnh chụp ổ trước thao tác rủi ro

Snapshot là ảnh chụp tức thời của một ổ logic. Nó được tạo chỉ trong vài phần giây và không sao chép dữ liệu: LVM hoạt động theo nguyên tắc copy-on-write, chỉ ghi vào snapshot những khối trên ổ gốc bị thay đổi sau khi snapshot được tạo. Vì vậy snapshot chỉ cần chỗ trống trong VG cho phần thay đổi, không cần chỗ cho toàn bộ ổ.

$ sudo lvcreate -s -n app_before_upgrade -L 2G /dev/data_vg/app
  Logical volume "app_before_upgrade" created.

$ sudo lvs data_vg
  LV                 VG      Attr       LSize  Origin Data%
  app                data_vg owi-aos--- 19.00g
  app_before_upgrade data_vg swi-a-s---  2.00g app    0.01

Cột Data% cho biết vùng lưu thay đổi đã đầy bao nhiêu. Nếu nó đạt 100%, snapshot kiểu cổ điển sẽ không còn hợp lệ và chỉ còn cách xóa. Hãy chọn kích thước có dư so với lượng thay đổi dự kiến, theo dõi snapshot dài ngày bằng lvs và mở rộng bằng lvextend khi cần.

Cách quay lại snapshot

Nếu nâng cấp thất bại, đưa ổ về trạng thái tại thời điểm snapshot:

$ sudo umount /srv/app
$ sudo lvconvert --merge /dev/data_vg/app_before_upgrade
  Merging of volume data_vg/app_before_upgrade started.
$ sudo mount /srv/app

Sau khi gộp, snapshot biến mất. Nếu không gỡ gắn được ổ (ví dụ đó là gốc của hệ thống), việc gộp sẽ được hoãn đến lần kích hoạt ổ tiếp theo, tức là đến lần khởi động lại.

Nếu mọi thứ ổn

Khi đó chỉ cần xóa snapshot để nó không làm chậm việc ghi và không chiếm chỗ:

$ sudo lvremove /dev/data_vg/app_before_upgrade

Snapshot cũng tiện để gắn ở chế độ chỉ đọc, nhằm sao lưu nhất quán một hệ thống đang chạy: dùng mount -o ro rồi sao chép bằng rsync hoặc tar. Với XFS, thêm tùy chọn nouuid, nếu không việc gắn sẽ bị từ chối vì trùng UUID với ổ gốc.

LVM và RAID: đừng nhầm lẫn vai trò

Bản thân LVM không bảo vệ khỏi hỏng ổ. Nếu một ổ logic trải trên hai ổ đĩa và một trong số đó hỏng, mất toàn bộ ổ logic chứ không chỉ một nửa. Để chịu lỗi, đặt RAID (mdadm) bên dưới LVM, hoặc dùng chế độ gương có sẵn trong LVM (lvcreate --type raid1 -m 1).

Cả RAID lẫn snapshot đều không thay thế được bản sao lưu. Snapshot nằm trên cùng các ổ với ổ gốc, còn RAID trung thành nhân bản cả lệnh rm -rf vô tình. Cần một bản sao riêng trên thiết bị lưu trữ khác.

Bảng lệnh LVM

Việc cần làmLệnh
Xem PV, VG, LVpvs, vgs, lvs
Tạo physical volumepvcreate /dev/sdb
Tạo nhómvgcreate data_vg /dev/sdb
Thêm ổ vào nhómvgextend data_vg /dev/sdc
Tạo ổ logiclvcreate -n app -L 15G data_vg
Mở rộng ổ và hệ thống tệplvextend -r -L +5G /dev/data_vg/app
Mở rộng PV sau khi tăng dung lượng ổpvresize /dev/sdb
Snapshotlvcreate -s -n snap -L 2G /dev/data_vg/app
Quay lại snapshotlvconvert --merge /dev/data_vg/snap
Đưa ổ ra khỏi nhómpvmove /dev/sdb, sau đó vgreduce data_vg /dev/sdb
Xóa ổ logiclvremove /dev/data_vg/app

Lỗi thường gặp

  • Đã mở rộng ổ nhưng df vẫn hiện dung lượng cũ. Quên -r. Chạy resize2fs hoặc xfs_growfs.
  • Insufficient free space. Nhóm không còn extent trống: kiểm tra vgs, rồi thêm ổ bằng vgextend hoặc mở rộng PV.
  • Device /dev/sdc excluded by a filter. Trên ổ còn sót lại bảng phân vùng hoặc chữ ký hệ thống tệp cũ. Nếu chắc chắn không cần dữ liệu trên đó, xóa chữ ký bằng wipefs -a /dev/sdc.
  • Snapshot chuyển sang Invalid. Vùng lưu thay đổi đã đầy 100%. Không thể khôi phục — chỉ xóa được và lần sau cấp nhiều chỗ hơn.

Tổng kết

LVM trong Linux gồm ba tầng: các physical volume (PV) gộp vào một volume group (VG), từ đó cắt ra các logical volume (LV). Nhờ đó có những điều mà phân vùng thông thường không làm được: mở rộng ổ ngay khi đang chạy bằng lvextend -r, thêm ổ mà không dừng dịch vụ, và tạo snapshot trước các thay đổi rủi ro. Hãy nhớ rằng LVM không thay thế RAID hay bản sao lưu. Phân vùng ổ, LVM, RAID và hạn ngạch được thực hành trong bài giảng về Linux của khóa học.

Câu hỏi thường gặp

Có thể chuyển một phân vùng đang chứa dữ liệu sang LVM không?

Không trực tiếp: pvcreate ghi đè lên đầu thiết bị. Cần tạo LVM trên một ổ khác, sao chép dữ liệu bằng rsync, sửa fstab, rồi mới giải phóng phân vùng cũ.

LVM có làm chậm ổ đĩa không?

Khi không có snapshot, chi phí của device-mapper gần như không đáng kể. Các snapshot cổ điển đang hoạt động làm chậm việc ghi vào ổ gốc do cơ chế copy-on-write, vì vậy không nên giữ chúng hàng tuần.

Máy tính cá nhân hay laptop có cần LVM không?

Không bắt buộc, nhưng hữu ích khi mã hóa ổ (LUKS với LVM bên trong) và khi muốn đổi kích thước phân vùng mà không phải phân vùng lại. Trên máy chủ chứa dữ liệu, LVM gần như là tiêu chuẩn.

Thin provisioning trong LVM là gì?

Đó là các ổ mỏng: tạo một pool (lvcreate --type thin-pool), và các ổ trong pool chỉ chiếm dung lượng thực khi có dữ liệu được ghi. Nhờ vậy có thể cấp cho các ổ nhiều hơn dung lượng vật lý, nhưng phải theo dõi mức đầy của pool.

Làm sao gỡ một ổ khỏi nhóm mà không mất dữ liệu?

Chuyển các extent của ổ đó sang các ổ khác trong nhóm bằng pvmove /dev/sdb (cần đủ chỗ trống), sau đó chạy vgreduce data_vg /dev/sdb và pvremove /dev/sdb.

Học chủ đề này qua video

Chủ đề này được giảng chi tiết kèm thực hành trong khóa học “Linux: с нуля до уверенного администрирования”.

Đến khóa học