How to Use Ubuntu lvm to Configure Logical Volume Management and Dynamic Resizing

The Rigidity of Static Partitions

When you install Ubuntu Server using the standard, default partition method, the operating system writes an immutable map to the hard drive. If you assign 100GB to the /var partition (which holds your Docker containers or database files) and 500GB to the /home partition, those boundaries are permanently etched in stone.

Six months later, your database expands and completely fills the 100GB /var partition, crashing the server. Meanwhile, the /home partition is completely empty. In a static partition model, you cannot simply “borrow” 50GB from /home and give it to /var. You are forced to take the server offline, boot into a GParted live CD, and execute a terrifying, multi-hour partition resizing operation that risks total data corruption.

To eliminate this architectural rigidity, enterprise Linux engineers deploy LVM (Logical Volume Management). LVM acts as a virtualization layer between the physical hard drives and the Linux filesystem. It pools multiple physical hard drives together into a massive, fluid “Volume Group.” From this pool, administrators can carve out “Logical Volumes.” Crucially, these Logical Volumes are completely dynamic. You can shrink /home, instantly grow /var, or seamlessly span a single filesystem across three different physical hard drives without ever taking the server offline.

Step 1: The LVM Architecture Hierarchy

LVM is built on a strict three-tier architectural model. You must construct it from the bottom up.

  1. Physical Volumes (PV): The raw, actual hard drives (e.g., /dev/sdb, /dev/sdc).
  2. Volume Groups (VG): A massive storage pool created by combining one or more Physical Volumes together.
  3. Logical Volumes (LV): The virtual partitions carved out of the Volume Group. These are the actual drives you format with ext4 or XFS and mount to the system (e.g., /var).

Step 2: Constructing the LVM Pool

Suppose you just inserted two brand new 1-Terabyte SSDs into your Ubuntu server (/dev/sdb and /dev/sdc). You want to combine them into a single, massive 2TB storage pool for your database.

First, initialize the raw drives as LVM Physical Volumes:

sudo pvcreate /dev/sdb /dev/sdc

You can verify they were initialized by running sudo pvs.

Next, create the Volume Group (the pool). We will name it vg_database, and we will throw both physical drives into it:

sudo vgcreate vg_database /dev/sdb /dev/sdc

Run sudo vgs. You will now see vg_database reporting approximately 2TB of completely free, fluid storage space.

Step 3: Carving Out Logical Volumes

Now that the pool exists, you can carve virtual partitions (Logical Volumes) out of it.

Suppose you want to create a 500GB volume specifically for PostgreSQL data.

sudo lvcreate -L 500G -n lv_postgres vg_database

Decoding the Flags:

  • -L 500G: The explicit size of the volume.
  • -n lv_postgres: The name of the virtual partition.
  • vg_database: The pool from which to draw the space.

The OS now sees a block device located at /dev/vg_database/lv_postgres. You format it with a standard filesystem (like XFS) and mount it.

sudo mkfs.xfs /dev/vg_database/lv_postgres
sudo mkdir -p /var/lib/postgresql
sudo mount /dev/vg_database/lv_postgres /var/lib/postgresql

Step 4: Dynamic Expansion (Growing a Volume)

This is the true power of LVM. A year later, your PostgreSQL database grows to 499GB. The server is critically low on space. Because you used LVM, you have 1.5TB of free space remaining in the vg_database pool.

You can instantly inject 200GB of that free space directly into the live, running database volume without unmounting it or stopping the PostgreSQL service.

First, grow the Logical Volume block device:

sudo lvextend -L +200G /dev/vg_database/lv_postgres

The underlying block device is now 700GB, but the XFS filesystem on top of it still thinks it is 500GB. You must command the filesystem to expand into the newly provided empty space.

If you used XFS, run:

sudo xfs_growfs /var/lib/postgresql

If you used ext4, run:

sudo resize2fs /dev/vg_database/lv_postgres

The expansion happens in a fraction of a second. If you run df -h, you will instantly see the database drive reporting 700GB of total capacity, averting a catastrophic production outage with zero downtime.

Step 5: Expanding the Underlying Pool (Adding Physical Disks)

What happens when the entire 2TB vg_database pool is completely full?

With static partitions, you would have to buy a massive 4TB drive, migrate all the data overnight, and throw the old drives away.

With LVM, you simply drive to the data center, shove a brand new 1TB hard drive (/dev/sdd) into an empty slot in the server, and add it to the live pool:

sudo pvcreate /dev/sdd
sudo vgextend vg_database /dev/sdd

The vg_database pool instantly jumps from 2TB to 3TB of capacity. You can now return to Step 4 and continue running lvextend to feed that new space to your starving database volumes, achieving seamless, infinite horizontal scalability.

Conclusion

Deploying a production Ubuntu server using static disk partitions is an architectural trap that guarantees future downtime during capacity upgrades. By inserting Logical Volume Management (LVM) between the physical hardware and the filesystem, administrators decouple capacity planning from physical constraints. The ability to pool physical disks, dynamically carve out virtual volumes, and resize filesystems on the fly transforms Linux storage from a rigid limitation into a highly fluid, massively scalable architecture.

RELATED POSTS

  • How to Join an Ubuntu Linux Machine to a Windows Active Directory Domain using SSSD
  • How to Use Ubuntu ufw to Configure Advanced NAT Routing and Port Forwarding
  • How to Configure Linux CPU Affinity using the taskset Command
  • How to Configure Linux eBPF (Extended Berkeley Packet Filter) Tracing
  • How to Configure Linux Seccomp (Secure Computing Mode) Profiles
  • Get the best tech tips delivered straight to your inbox.

    Join thousands of readers mastering Apple, Google, Microsoft, and Linux.