Async I/O for Oracle 9i Release 2 on RedHat 9, Kernel 2.6

This page is for people interested in getting async I/O working for Oracle 9i with a 2.6 kernel.

Disclaimer

At time of writing (31st Aug 2004) Oracle 9i Release 2 is not to my knowledge supported under Linux kernel 2.6. Oracle 9i Release 2 for Linux is supported on certified kernels only, such as Red Hat Enterprise Linux AS, Red Hat Enterprise Linux ES and UNITED LINUX 1.0 (Conectiva powered by UnitedLinux 1.0, Turbolinux powered by UnitedLinux 1.0 and SuSE SLES). Reading this document probably invalidates your support agreement with Oracle.

I have not tried and would not recommend you try this in an environment where availability or integrity are of interest. If you do try this, you try it at your own risk, without any support from Oracle, Qnix or me.

Oracle 9i is a trademark of Oracle Coroporation.

Rationale

Async I/O is available for Oracle on the following x86 *nix OS's: RedHat AS, United Linux 1.0, and Solaris; RedHat and UL are not cheap. Solaris works very nicely (except for sparse tempfiles of course), and even has dtrace. However I thought it would be nice to run up async I/O on a RedHat 9 / Fedora Mishmash vmware sandbox.

Problem

make -f ins_rdbms.mk async_on

Fails unless you are running RedHat AS or UL. Even if you can get the relink to work, you get ORA-27083 at instance startup.

Approach

Match the Oracle async io library ($ORACLE_HOME/rdbms/lib/skgaio.o) with a compatible version of libaio, and in turn match libaio with the kernel ABI for async io. I have found only one freely available implementation of libaio which results in normal operation of the Oracle RDBMS; this is libaio-0.3.96-3. I've tested later versions (0.3.98 and 0.3.99-3); the log writer process exits with ORA-27083 at instance startup, due to a call to io_getevents failing with EINTR. Please do contact me if you can help resolve this.

Update: Thanks to Eric Skibicki for reporting success with libaio-0.3.102.

If you have yet to install kernel 2.6 you might want to read up on the LVM2 upgrade path before leaping in and rendering your system unbootable. I found Thomer Gil's upgrade notes helpful too.

I used Arjan van de Ven's 2.6 series kernel repository, because this appears to be a reasonably authoritative source for a current kernel patched suitably for aio, and becuase Arjan provides (most) of the packages on which the kernel depends. So I added the following to /etc/apt/sources.list:

# Arjan's 2.6 series kernel repository

rpm http://people.redhat.com arjanv/2.6 kernel

rpm-src http://people.redhat.com arjanv/2.6 kernel

Unfortunately this seems to have disappeared. Anyway, you should find 2.6.8.1-521 or higher to be useable. I have yet to test, but you should find the following sources usable for FC2:

rpm http://ayo.freshrpms.net fedora/linux/2/i386 core freshrpms os updates

rpm-src http://ayo.freshrpms.net fedora/linux/2/i386 core freshrpms os updates

# Dag Wier's Taroon

rpm http://apt.sw.be redhat/el3/en/i386 dag

The Fedora Core 2 updates are for modutils 2.4-12.1.143 only, since this is required by kernel 2.6.8-1.

Installation

install libaio

wget ftp://pub/redhat/linux/beta/taroon/en/as/i386/SRPMS/libaio-0.3.96-3.src.rpm

rpm -Uvh libaio-0.3.96-3.src.rpm

rpmbuild -ba /usr/src/redhat/SPECS/libaio.spec

if all goes well then

cd /usr/src/redhat/BUILD/libaio-0.3.96

make install

install kernel

wget ftp://pub/redhat/linux/beta/taroon/en/as/i386/SRPMS/libaio-0.3.96-3.src.rpm

apt-get update

apt-get install modutils

or

apt-get install module-init-tools

apt-get install kernel-utils

kernel-utils then shows you a list of the many different versions available. I chose this one:

apt-get kernel-utils#1:2.4-12.1.143

Now for the kernel itself

apt-get source kernel-sourcode#2.6.8-1.521

For example

cd /usr/src/redhat

rpmbuild --target noarch -ba SPECS/kernel-2.6.spec

cd BUILD/kernel-2.6.8/linux-2.6.8

cp configs/kernel-2.6.8-i686.config ./.config

Modify for the .config RAWIO if that's your thing:

CONFIG_RAW_DRIVER=y

CONFIG_MAX_RAW_DEVS=256

Now build. There is probably a better way of doing this...

make

cp arch/i386/boot/bzImage /boot/bzImage-2.6.8-1.521

cd /boot

mkinitrd /boot/initrd-2.6.8-1.521 2.6.8-prep

Update your boot loader, reboot and you should be off with the new kernel.

build libaio-oracle

wget http://oss.oracle.com/projects/libaio-oracle/dist/files/libaio-oracle-0.3.0.tar.gz

tar ztvf ./libaio-oracle-0.3.0.tar.gz

cd libaio-oracle-0.3.0

./configure

make

Have a look at the README and try running lio_test and aio_reap. If they work you should be nearly there!

Relink Oracle

If you try an RDBMS relink now, the relink will complete but instance startup will fail like this

make -f ins_rdbms.mk async_on
SQL> startup
ORACLE instance started.

Total System Global Area 420549952 bytes
Fixed Size 451904 bytes
Variable Size 201326592 bytes
Database Buffers 218103808 bytes
Redo Buffers 667648 bytes
Database mounted.
ORA-01110: data file 2: '/path/to/undotbs1_01.dbf'
ORA-27083: skgfrliopo: waiting for async I/Os failed
Linux Error: 22: Invalid argument
ORA-01110: data file 1: '/path/to/system_01.dbf'
ORA-27083: skgfrliopo: waiting for async I/Os failed
Linux Error: 22: Invalid argument

gdb reveals that the failed call to skgfrliopo is from $ORACLE_HOME/rdbms/lib/skgaio.o. Fortunately the libaio-oracle.o which you have just built appears to be a more up to date version of $ORACLE_HOME/rdbms/lib/skgaio.o, compatible with the 0.3.96 / kernel 2.6 implementation of aio

So, shut down AND BACKUP up your instance, and copy the library over:

mv $ORACLE_HOME/rdbms/lib/skgaio.o $ORACLE_HOME/rdbms/lib/skgaio.orig

cp libaio-oracle.o $ORACLE_HOME/rdbms/lib/skgaio.o

make -f ins_rdbms.mk async_on

That's it: My notebook's dbwr now trundles along at 10MB per second!

Feedback

This note was written by Simon Grabinar on 24th Feb 2004, and updated for kernel 2.6.8-1 on 31st August 2004. Please let me know how I can improve on this page.

Copywright

Copyright (C) 2004 Qnix Pty Ltd, Croydon Pk, NSW 2133, Australia.