Oracle dNFS with Docker
By: Marcelo Ochoa
Tags: Dnfs, Oracle, Docker, Swarm

As everybody knows Docker containers have ephemeral storage, which means, once you removes your container any change on the filesystem will be discarded. For a RDBMS point of view this means that any data stored at your tables will be lost, for using Oracle Database at Docker the filesystem where your Datafiles resides must be attached to an external storage.

When using Docker Swarm this external storage is commonly placed at NFS server. Oracle provides a native client for talking with your NFS storage providing mainly a direct path access to the data, here two excellent posts at Ron's Blog with information about:

the mainly benefits of using dNFS is multi-path access to your Datafiles giving more throughput and fault tolerant access, following a picture taken form Ron's Blog show this architecture:

Multi-path access using dNFS Oracle driver

this post shows how to use Oracle Docker images with dNFS enabled by extending 18.3.0 EE image or a pending 18.4.0 XE image. First our simple Dockerfile.nfs for enabling dNFS driver over official Oracle Docker images, 18.3.0 EE:

# Pull base image

# ---------------

FROM oracle/database:18.3.0-ee

# ----------

MAINTAINER Marcelo ochoa < # Maintainer# ----------MAINTAINER Marcelo ochoa < marcelo.ochoa@gmail.com RUN cd $ORACLE_HOME/rdbms/lib && make -f ins_rdbms.mk dnfs_on

or 18.4.0 XE:

# Pull base image

# ---------------

FROM oracle/database:18.4.0-xe

# ----------

MAINTAINER Marcelo ochoa < # Maintainer# ----------MAINTAINER Marcelo ochoa < marcelo.ochoa@gmail.com RUN cd $ORACLE_HOME/rdbms/lib && make -f ins_rdbms.mk dnfs_on

to build our new dNFS enabled image just run with EE version:

$ docker build -t "oracle/database:18.3.0-ee-nfs" -f Dockerfile.nfs .

XE version:

$ docker build -t "oracle/database:18.4.0-xe-nfs" -f Dockerfile.nfs .

once you have your RDBMS Docker image ready a sample Docker Swarm stack like below could be used to start Oracle using dNFS native driver:

some remarks about above docker-compose stack definition:

db_data volume is defined as an external NFS backed storage (one of my NAS IP is 10.1.253.110, with Oracle recommended NFS mount options)

test_oranfstab_xe is an external config including multi-path definition to my NAS, here an example on how to create this config using command line:

$ echo "server: NAS-DTICs

> path: 10.1.253.110

> path: 10.1.1.241

> nfs_version: nfsv4

> export: /dbdata/xe-18c mount: /opt/oracle/oradata

> " | docker config create test_oranfstab_xe -

fbpuy0pjjx2t6ssan6almtjn5

$ docker config ls

ID NAME CREATED UPDATED

fbpuy0pjjx2t6ssan6almtjn5 test_oranfstab_xe 17 seconds ago 17 seconds ago

note that in above config definition we are adding multi-path access to our NAS storage (10.1.253.110 and 10.1.1.241), export and mount parameters must be equal to docker-compose.yml definition. Deploying our stack with:

$ docker stack deploy -c docker-compose.yml test

will result on RDBMS XE up and running after a few minutes (wait for your RDBMS create theirs Datafiles), if your NAS is not fast enough and Docker healthcheck file kill your stack add this healthcheck definition to avoid the problem:

healthcheck:

test: exit 0

interval: 60s

timeout: 3s

finally to see dNFS multi-path in action lets try to run an IO calibrating test by connecting to the root CDB and running with SQLPlus as sysdba:

set long 10000 lines 140 pages 50 timing on echo on

set serveroutput on size 1000000 declare

l_latency integer;

l_iops integer;

l_mbps integer;

begin

dbms_resource_manager.calibrate_io (

1, /* # of disks */

20, /* max latency */

l_iops, /* I/O Ops/sec */

l_mbps, /* MBytes/sec */

l_latency /* actual latency */

);

dbms_output.put_line ('I/O Ops/sec = ' || l_iops);

dbms_output.put_line ('Actual Latency = ' || l_latency);

dbms_output.put_line('MB/sec = ' || l_mbps);

end;

/

during the IO calibrating process we see at the NAS resource monitoring something like:

NAS resource monitoring with multi-path dNFS enabled

which means that two network interfaces are used and we got about 86Mbytes throughput (note that we have a 1Gbs interconnect switch) also by querying v$iostat_file system view we see that our Datafiles have:

ASYNCH_IO : ASYNC_ON

ACCESS_METHOD : DNFS_LIB

if instead of using oracle/database:18.4.0-xe-nfs Docker image we change our docker-compose.yml with oracle/database:18.4.0-xe image network utilization during IO calibrate test is:

NAS resource monitoring without multi-path dNFS enabled

only one interface is used to access to our data resulting in a slow IO capabilities and no Asynch IO: