Oracle Linux · ZFS

Oracle Linux ZFS: OpenZFS on UEK Storage Guide

A practical guide to deploying and tuning OpenZFS on Oracle Linux using the Unbreakable Enterprise Kernel (UEK), covering DKMS kernel header alignment, ashift storage pool creation, dataset optimization, ARC memory caps, and snapshot workflows.

Quick idea: OpenZFS on Oracle Linux requires building against the Unbreakable Enterprise Kernel (UEK) using DKMS and matching kernel headers, providing enterprise-grade pool resiliency, dataset compression, and snapshot controls when properly tuned.
UEK & DKMS Alignment

Why OpenZFS on Oracle Linux requires DKMS and matching kernel-uek-devel headers instead of standard kmod RPMs.

ashift & Persistent IDs

Creating pools with -o ashift=12 for 4K drives using persistent /dev/disk/by-id/ symlinks to survive reboots.

ARC & Dataset Tuning

Capping ZFS ARC memory in /etc/modprobe.d/zfs.conf and configuring recordsize and compression per workload.

What Is OpenZFS on Oracle Linux?

OpenZFS is an advanced enterprise storage system and volume manager for Linux. On Oracle Linux, administrators frequently pair OpenZFS with the Unbreakable Enterprise Kernel (UEK) to provide self-healing storage, native inline compression, snapshots, and data integrity verification.

Think of OpenZFS on Linux as an all-in-one storage manager, volume manager, and software RAID controller operating directly inside the kernel, taking direct responsibility for disk blocks rather than stacking separate software layers like LVM, mdadm, and traditional filesystems.

Unbreakable Enterprise Kernel (UEK) is Oracle’s customized Linux kernel optimized for enterprise workloads, database performance, and hardware stability. Because UEK tracks newer upstream Linux kernels than standard Enterprise Linux releases, running OpenZFS requires configuring Dynamic Kernel Module Support (DKMS) to compile and load the ZFS kernel drivers cleanly.

Enterprise failure framing: Storage failures are non-negotiable in production database and virtualization hosts. Traditional filesystems rely on hardware RAID to detect disk failures, but cannot detect silent bit rot. OpenZFS uses end-to-end 256-bit checksums for every data block, identifying and repairing corrupted data on the fly.

Prerequisites & UEK Kernel Module Installation

Installing OpenZFS on Oracle Linux differs from standard RHEL installation because pre-compiled zfs-kmod packages are built for the Red Hat Compatible Kernel (RHCK). Running OpenZFS on UEK requires installing zfs-dkms and the exact matching kernel-uek-devel package for your active kernel.

Before installing, confirm your running kernel release using uname -r. You must ensure that kernel-uek-devel matches your running UEK version before DKMS compiles the ZFS module.

# Check active kernel release
uname -r

# Install EPEL and OpenZFS release repository
sudo dnf install -y https://zfsonlinux.org/epel/zfs-release-2-3$(rpm --eval "%{dist}").noarch.rpm

# Install kernel-uek-devel and DKMS build tools matching the running kernel
sudo dnf install -y kernel-uek-devel-$(uname -r) dkms gcc make

# Install OpenZFS DKMS module and userspace utilities
sudo dnf install -y zfs-dkms zfs

# Trigger manual DKMS build if needed
sudo dkms autoinstall

# Load the ZFS kernel module
sudo modprobe zfs

# Verify the ZFS module and userspace version match
zfs version
Command / Package Purpose
kernel-uek-devel-$(uname -r) Provides kernel header files for the running Unbreakable Enterprise Kernel required by DKMS.
zfs-dkms Compiles the ZFS kernel modules automatically whenever a new UEK kernel is installed.
zfs Installs administrative binaries including zpool, zfs, and systemd services.
modprobe zfs Loads the compiled ZFS module into the active Linux kernel space.
zfs version Confirms both userspace tools and kernel module are running identical versions.
Important: If a DKMS compilation fails during a kernel upgrade, verify that system compiler versions match. On Oracle Linux, running scl run gcc-toolset-11 bash provides an updated GCC compiler toolset matching newer UEK kernel requirements.

Creating the ZFS Storage Pool (zpool)

A ZFS storage pool (zpool) aggregates physical hard drives or NVMe SSDs into a unified storage space. Never use raw device names like /dev/sdb or /dev/sdc when creating pools, because Linux drive letter ordering can change across system reboots.

Always use persistent device paths from /dev/disk/by-id/. Additionally, specify -o ashift=12 during pool creation to ensure 4096-byte (4K) sector alignment, preventing write amplification on modern Advanced Format drives and enterprise SSDs.

# Identify persistent disk IDs
ls -l /dev/disk/by-id/

# Create a mirrored storage pool (RAID 10 equivalent) with 4K alignment and LZ4 compression
sudo zpool create -o ashift=12 -O compression=lz4 datapool mirror \
  /dev/disk/by-id/nvme-eui.002538b811a00001 \
  /dev/disk/by-id/nvme-eui.002538b811a00002

# Create a dual-parity pool (RAIDZ2) for high-capacity HDD storage
sudo zpool create -o ashift=12 -O compression=zstd storagepool raidz2 \
  /dev/disk/by-id/ata-WDC_WD101KRYZ-01_1EGH101 \
  /dev/disk/by-id/ata-WDC_WD101KRYZ-02_1EGH102 \
  /dev/disk/by-id/ata-WDC_WD101KRYZ-03_1EGH103 \
  /dev/disk/by-id/ata-WDC_WD101KRYZ-04_1EGH104

# Verify pool status and health
sudo zpool status -v

# Inspect overall storage space allocation
sudo zpool list
Production note: The ashift setting cannot be changed after a virtual device (VDEV) is added to a pool. Failing to set -o ashift=12 on 4K disks causes severe write performance penalties that require recreating the entire pool to fix.

Dataset Configuration & Workload Tuning

ZFS datasets are lightweight virtual filesystems created within a storage pool. Unlike traditional partitions, datasets inherit pool capacity dynamically and can be configured with distinct compression algorithms, record sizes, access time rules, and quotas.

Tuning the dataset recordsize property to match your application’s disk I/O pattern drastically improves throughput and reduces cache churn. Database workloads perform best with smaller block sizes, while general file servers benefit from larger record sizes.

# Create datasets for general files, database, and virtual machine disks
sudo zfs create datapool/general
sudo zfs create datapool/oracle-db
sudo zfs create datapool/vms

# Configure optimal settings for general file storage
sudo zfs set compression=zstd datapool/general
sudo zfs set recordsize=128k datapool/general
sudo zfs set atime=off datapool/general

# Tune dataset specifically for Oracle Database or PostgreSQL (8k recordsize)
sudo zfs set recordsize=8k datapool/oracle-db
sudo zfs set logbias=latency datapool/oracle-db
sudo zfs set primarycache=metadata datapool/oracle-db
sudo zfs set atime=off datapool/oracle-db

# Set storage quotas and reservation rules
sudo zfs set quota=500G datapool/general
sudo zfs set reservation=100G datapool/oracle-db

# View all active datasets and properties
sudo zfs list -o name,used,avail,refer,mountpoint,compression,recordsize
Dataset Property Recommended Value Purpose
compression lz4 or zstd Transparent inline compression. lz4 is lightning fast; zstd offers higher compression ratios.
recordsize 8k (Databases) / 128k (Files) Matches ZFS block size to application I/O size, avoiding partial-block read-modify-write overhead.
atime off Disables updating file access timestamps on every read, eliminating unnecessary disk write IOPS.
logbias latency Optimizes synchronous writes (O_SYNC / fsync) for low latency using SLOG / ZIL intent logs.
quota 500G Caps maximum storage consumption for a dataset, preventing a single dataset from filling the pool.

Managing ZFS ARC Memory Limits

OpenZFS uses an Adaptive Replacement Cache (ARC) stored in system RAM to cache frequently and recently accessed data. By default, OpenZFS on Linux allocates up to 50% of total host RAM for the ARC.

On an Oracle Linux server hosting memory-intensive applications such as Oracle Database, Java enterprise services, or KVM virtual machines, unconstrained ARC growth causes severe memory contention, swapping, or triggers Linux Out-Of-Memory (OOM) killer terminations.

# Check current ZFS ARC memory consumption (in bytes)
grep -E 'c_max|size' /proc/spl/kstat/zfs/arcstats

# Limit ZFS ARC maximum size to 16 GB in /etc/modprobe.d/zfs.conf
echo "options zfs zfs_arc_max=17179869184" | sudo tee /etc/modprobe.d/zfs.conf

# Apply the ARC limit immediately to the running kernel without rebooting
echo 17179869184 | sudo tee /sys/module/zfs/parameters/zfs_arc_max

# Monitor ARC hit rate and memory health
arcstat 1
Healthy output: Run arcstat 1. Monitor the read, hits, and miss columns. A healthy ZFS cache maintains an ARC hit rate above 85-90% while respecting your configured zfs_arc_max limit.

Snapshots, Rollbacks, and Replication

ZFS snapshots are read-only point-in-time copies of a dataset created instantly using Copy-on-Write (CoW). Because snapshots consume zero additional storage space when created, administrators can take automatic hourly or daily snapshots for instant disaster recovery.

In addition to local rollbacks, OpenZFS supports stream-based replication via zfs send and zfs recv. This allows sending full or incremental dataset snapshots across SSH to a remote backup server or secondary Oracle Linux host.

# Create a manual snapshot of the database dataset
sudo zfs snapshot datapool/oracle-db@pre-upgrade-20260907

# List all active snapshots and space consumed
sudo zfs list -t snapshot

# Roll back dataset to a previous snapshot state
sudo zfs rollback datapool/oracle-db@pre-upgrade-20260907

# Export an incremental snapshot stream to a compressed file
sudo zfs send -i datapool/oracle-db@snap-v1 datapool/oracle-db@snap-v2 | gzip > /backups/db-incr.gz

# Replicate dataset snapshot to a remote server over SSH
sudo zfs send -v datapool/oracle-db@pre-upgrade-20260907 | ssh admin@backup-node.example.com sudo zfs recv backup-pool/remote-db

# Destroy a stale snapshot when no longer needed
sudo zfs destroy datapool/oracle-db@pre-upgrade-20260907
Key rule: Snapshots are not standalone backups if they remain on the same storage pool. A pool-level hardware failure destroys both the active dataset and its local snapshots. Always use zfs send to replicate critical snapshots to separate physical hardware.

Troubleshooting Cheat Sheet

Use this reference table to resolve common OpenZFS module, pool health, and performance issues on Oracle Linux servers.

Symptom Likely Cause Fix
modprobe: FATAL: Module zfs not found UEK kernel was updated without rebuilding the DKMS module or kernel-uek-devel is missing. Confirm kernel headers match uname -r and trigger a rebuild: sudo dkms autoinstall.
High memory usage / OOM killer terminating apps ZFS ARC consuming default memory limit (50% host RAM). Set maximum ARC size in configuration: echo "options zfs zfs_arc_max=17179869184" | sudo tee /etc/modprobe.d/zfs.conf.
High disk latency / poor I/O throughput Pool created without ashift=12 on 4K sector drives causing write amplification. Recreate the storage pool specifying sector alignment: sudo zpool create -o ashift=12 ....
Pool status shows UNAVAIL after reboot Pool created using raw /dev/sdX paths that changed letter assignment after boot. Export the pool and re-import using persistent IDs: sudo zpool import -d /dev/disk/by-id datapool.
DKMS build error during kernel compilation System GCC compiler version differs from compiler used to build UEK. Enable updated compiler toolset before building: scl run gcc-toolset-11 bash then re-run DKMS.

Final Thoughts

Deploying OpenZFS on Oracle Linux brings enterprise-grade storage resiliency, compression, and snapshot management to enterprise infrastructure. By aligning DKMS with the Unbreakable Enterprise Kernel, using 4K ashift=12 pool parameters, and explicitly managing ZFS ARC memory caps, you create a fast, self-healing storage layer capable of supporting demanding database and virtualization workloads.

Key takeaway: Always pair OpenZFS on Oracle Linux with kernel-uek-devel, build via DKMS, create pools with -o ashift=12 using /dev/disk/by-id symlinks, and cap zfs_arc_max in /etc/modprobe.d/zfs.conf to prevent memory starvation.
Next in this series

Next, we will explore Proxmox Backup Server (PBS) integration with ZFS storage targets for automated enterprise backups.