This page describes how to enable a set of I/O acceleration features in AlloyDB Omni that can help improve your compute and I/O resource utilization for faster workloads and query performance.
The following features are included:
- Torn write protection
- O_DIRECTsupport
- Asynchronous I/O (AIO)
- Streaming reads
To enable these I/O acceleration features, you enable the alloydb_omni_atomic
Grand Unified Configuration (GUC) and set up AlloyDB Omni to be
able to use the GUC.
I/O acceleration features
The following sections describe the I/O acceleration features that the
alloydb_omni_atomic GUC enables.
Torn write protection
When you enable the alloydb_omni_atomic configuration, you turn off
full page writes
to prevent the performance overhead of having to generate full page images for
logging.
O_DIRECT support
O_DIRECT support is a prerequisite for atomic writes. O_DIRECT applies to the
PostgreSQL data directory and the AlloyDB Omni
disk cache. For more information, see
Accelerate database performance using disk cache.
O_DIRECT also offers the following benefits:
- Using O_DIRECTlets you avoid the double-buffering problem in PostgreSQL. PostgreSQL manages its own buffer cache and can bypass the operating system kernel buffer cache.
- O_DIRECTreduces operating the system CPU and memory overhead that are needed to maintain the kernel buffer cache.
Asynchronous I/O
The alloydb_omni_atomic configuration provides asynchronous I/O (AIO)
capabilities using the io_uring and libaio libraries. We recommend that you
use io_uring to avoid the limitations of the older libaio library.
AlloyDB Omni falls back to libaio when io_uring support isn't
detected. This approach overcomes the loss of buffered I/O advantages such as
readahead and write-combining, and it also ensures that the available I/O
bandwidth of the underlying offered storage is maximized.
Streaming reads
AlloyDB Omni uses streaming reads, similar to the
PostgreSQL 17 feature, which provide improved
sequential scans, ANALYZE, and pg_prewarm performance by using vectored I/O
to read multiple blocks into the buffer cache. Vectored I/O is a method in which a
single procedure call can prefetch data from multiple buffers, which improves
efficiency by reducing context switches and system calls.
AlloyDB Omni extends support to use streaming reads for reads from the AlloyDB Omni disk cache using AIO to amplify read performance. This approach facilitates effective read-ahead of buffers into the shared-memory pool from storage for queries to use, rather than having to read these blocks from storage every time they are needed.
Before you begin
- Check your operating system and file system support. - To ensure that the kernel supports - RWF_ATOMIC, check the kernel version. In the following example, you use a Ubuntu 24.10 machine running the Linux 6.14 kernel that supports atomic writes.- > sudo hostnamectl ... Operating System: Ubuntu 24.10 Kernel: Linux 6.14.0-061400rc5-generic ...
- If your kernel doesn't have support for - RWF_ATOMIC, we recommend that you update to a kernel version that supports- RWF_ATOMIC.
 
- To use AlloyDB Omni I/O acceleration features to test performance gains with torn write protection, enable the - alloydb_omni_atomicGrand Unification Configuration (GUC). To use this GUC, you must have a supporting kernel and file system that provide atomic I/O and protect against torn writes.- The - RWF_ATOMICflag is used for atomic write support. By default, compatibility for- RWF_ATOMICis checked during startup. PostgreSQL fails to start if atomic writes with the- RWF_ATOMICflag can't be confirmed.- You can override this default behavior, but we recommend that you use a supported platform and the - forceoption to avoid accidentally overriding optimal configuration settings.- You can override the - RWF_ATOMICcompatibility check by using the- force_unsafeoption, but data safety isn't guaranteed with this override. We recommend that you don't use this option unless you're evaluating AlloyDB Omni in an environment that can't be upgraded to use the appropriate kernel and filesystem.- The following table lists - alloydb_omni_atomicconfiguration settings and corresponding compatibility checks.- alloydb_omni_atomicvalue- Startup compatibility check - Description - off - N/A - This value turns off atomic mode. The feature is inactive. - force - Performs startup compatibility check. Fails to start if - RWF_ATOMICwrite fails.- Sets atomic mode configs. - force_unsafe - Doesn't perform a startup compatibility check. Returns a warning, but continues if - RWF_ATOMICwrite fails.- Sets atomic mode configs. - In the - force/- force_unsafeconfiguration,- full_page_writes,- io_combine_limit, and- debug_io_directconfigurations are automatically set. You can override these configurations using the optional- on/- on_unsafeconfiguration.
Set up AlloyDB Omni I/O acceleration features
- Set up the XFS filesystem for the data directory. XFS is used because it supports a filesystem block size greater than page size. AlloyDB Omni can use XFS to atomically write 8KiB blocks with full - RWF_ATOMICsupport.- Create an XFS filesystem with a block size of 8KiB and mount it at the desired data directory ( - DATA_DIR) location.- sudo mkfs.xfs -f -b size=8k /dev/$DEVICE sudo mount /dev/$DEVICE DATA_DIR - Make the following replacement: - DATA_DIR: the data directory location.
 
- Check the kernel logs to ensure that 8k blocks are used: - > sudo journalctl -f ... kernel: XFS (sdc): EXPERIMENTAL large block size feature enabled. Use at your own risk! kernel: XFS (sdc): Mounting V5 Filesystem 350aa26a-7555-4566-94c1-74e54ddc9250 ... 
 
- Optional: Set up the AlloyDB Omni disk cache. - Use the following example to create a filesystem using - ext4,and then mount the filesystem.- sudo /sbin/mkfs.ext4 -m 1 -F -E lazy_itable_init=0,lazy_journal_init=0 /dev/DEVICE sudo mount --make-shared -o noatime,discard,errors=panic /dev/DEVICE /OMNI_DISK_CACHE_DIRECTORY - Make the following replacement: - DEVICE: the entity with which the application interacts to perform I/O operations (reading or writing data).
 - To support optimal performance of AlloyDB Omni I/O acceleration features when primary storage doesn't offer higher Input/Output Operations Per Second (IOPS), we recommend that you set up AlloyDB Omni disk cache. For more information, see Accelerate database performance using disk cache. 
- Download and run AlloyDB Omni. - Download the latest AlloyDB Omni Docker container. For more information, see Install AlloyDB Omni on a VM.
- To use the disk cache, follow the instructions in Accelerate database performance using disk cache.
- To allow - io_uring, add an additional argument,- --security-opts="seccomp:unconfined"- docker run -d --name CONTAINER_NAME \ -e POSTGRES_PASSWORD=NEW_PASSWORD \ -v DATA_DIR:/var/lib/postgresql/data \ -v /OMNI_DISK_CACHE_DIRECTORY:/CACHE_DIRECTORY_PATH_INSIDE_CONTAINER \ # Only if disk cache is enabled -p HOST_PORT:5432 \ --security-opts="seccomp:unconfined" \ --restart=always \ google/alloydbomni:16 - Make the following replacements: - CONTAINER_NAME: the name of the AlloyDB Omni container in your host machine's container registry.
- NEW_PASSWORD: the password assigned to the container's PostgreSQL user.
- DATA_DIR: the data directory location.
- CACHE_DIRECTORY_PATH_INSIDE_CONTAINER: the disk cache directory path inside the container.
- HOST_PORT: the TCP post on the host machine that the container should publish its own port 5432 to.
 
 
- Configure AlloyDB Omni to use atomic I/O. - Set the - alloydb_omni_atomicGUC to an appropriate value and restart the container.- alter system set alloydb_omni_atomic='force'; sudo docker restart CONTAINER_NAME; - Make the following replacements: - CONTAINER_NAME: the name of the AlloyDB Omni container in your host machine's container registry.
 
Limitations
- PostgreSQL 16 contains paths that perform single block I/O, which
O_DIRECTslows down. There might be slower reads during database recovery (redo path), vacuum scans, and Omni disk cache prewarming.
- AlloyDB Omni I/O acceleration features in read replicas aren't supported in Preview.
- Under heavy workloads, ARM-based systems might exhibit lower performance due to architectural differences.
- Due to its limitations with increased workloads, libaiois susceptible to resource unavailability.io_uringmight experience memory allocation issues when available system memory is running low.