Oracle has official support (although limited to Severity 2) for running Oracle single instances in Docker. For more on this refer MOS 1921163.1 and 2216342.1.
Creating an Oracle Database Image in Docker
Creating the Oracle DB as Docker Container
Patching Oracle DB in Docker
Creating a new PDB in Docker
Plug/Unplug PDB in Docker
Export and Import From DB in Docker
Using RMAN Backup in Docker
Miscellaneous
Creating an Oracle Database Image in Docker
Docker files to create an Oracle image is available from GitHub. These could be directly downloaded using wget. In this case the docker files are downloaded to /opt/git location.
mkdir -p /opt/git cd /opt/git wget https://github.com/oracle/docker-images/archive/master.zipUnzip the downloaded master.zip file. This will extract number of folders relating to various Oracle products. It it possible to remove all other products and leave only the OracleDatabase folder to save space.
unzip master.zip cd /opt/git/docker-images-master ls CODEOWNERS ContainerCloud CONTRIBUTING.md LICENSE OracleDatabase README.mdOracleDatabase folder containers two sub folders, one containing docker files for single instance and other for RAC. Single instance folder has docker files for 3 versions. 11.2.0.2 (for XE) and 12.1 and 12.2
cd /opt/git/docker-images-master/OracleDatabase/SingleInstance/dockerfiles 11.2.0.2 12.1.0.2 12.2.0.1 buildDockerImage.shThe docker files folders do not contain Oracle installers. In order to create a 12.2 DB a 12.2 docker image must be built for which a Oracle linux 64 bit installer file is needed. Download this from Oracle site and copy to 12.2.0.1 folder.
cp linuxx64_12201_database.zip /opt/git/docker-images-master/OracleDatabase/SingleInstance/dockerfiles/12.2.0.1/Only make below changes if OMF is preferred. If not there's no need to make any of these changes. Proceed to final step of building the image. The dbca template file (dbca.rsp.tmpl) that comes with GitHub download is not setup for OMF. If OMF is desired for database then modify the dbca template file at this point by adding db_create_file_dest (this could be done later as well. But would require rebuilding the image and the DB).
initParams=audit_trail=none,audit_sys_operations=false,db_create_file_dest=/opt/oracle/oradataWhen the use of OMF used, then comment out the set control_files line in the createDB.sh file. From
sqlplus / as sysdba << EOF ALTER SYSTEM SET control_files='$ORACLE_BASE/oradata/$ORACLE_SID/control01.ctl' scope=spfile; ALTER PLUGGABLE DATABASE $ORACLE_PDB SAVE STATE; exit; EOFTo
#sqlplus / as sysdba << EOF # ALTER SYSTEM SET control_files='$ORACLE_BASE/oradata/$ORACLE_SID/control01.ctl' scope=spfile; sqlplus / as sysdba << EOF ALTER PLUGGABLE DATABASE $ORACLE_PDB SAVE STATE; exit; EOFIf not control file name is set to control01.ctl and container will not bring up the DB after a restart.
Final step is to run the buildDockerImage file. This is run with minimum options that is the version of the image (specified by -v) and the edition of the database (specified by -e).
cd /opt/git/docker-images-master/OracleDatabase/SingleInstance/dockerfiles/ ./buildDockerImage.sh -v 12.2.0.1 -eAt the end of the build there will be two docker images. One with OEL 7-slim and another with the 12.2 EE.
#docker images REPOSITORY TAG IMAGE ID CREATED SIZE oracle/database 12.2.0.1-ee e4ac99149312 12 days ago 13.2GB oraclelinux 7-slim c94cc930790a 5 weeks ago 117MBThe next step is to create a docker container using the Oracle database image.
Creating the Oracle DB as Docker Container
Anything created inside a docker container lives until the that docker container is removed. This means any database data files created inside a docker container will be lost when that docker container is deleted. To over come this docker volumes are used. When used, volumes will store the data files and configuration files such as spfile, tnsnames.ora, listener.ora outside of the container. These files are preserved even when the docker container is removed.
In this case a database is created using docker volume so that data is preserved when container is removed. First create a directory on the external host (not inside the docker container) to store the data files. It is also important that this directory has read, write and execute permission in the other group. Without this permission to the other group the DB creation will fail. Here the path chose is as below
mkdir -p /opt/app/oracle/oradata/docker/oracdb chmod 777 /opt/app/oracle/oradata/docker/oracdbThis external location is passed to docker run command with -v parameter. By default data files are created inside the container in /opt/oracle/oradata.
Next the listener port and express port could be mapped to ports on the external host. This way it is possible to remotely connect to the database inside the docker.
Finally the default database names are ORCLCDB and ORCLPDB1. But it possible to pass custom CDB and PDB names at the creation time using the -e option and specify the parameter name.
If an admin password isn't specified then a password is auto generated which could be changed later using setPassword.sh file. However in this case the password is provided at creation time.
Below is the full command to create the database (CDB and PDB). The container is also named oracdb (specified by --name) same as the CDB name.
docker run --name oracdb -p 1521:1521 -p 5500:5500 -v /opt/app/oracle/oradata/docker/oracdb:/opt/oracle/oradata -e "ORACLE_SID=oracdb" -e "ORACLE_PWD=dockerOra278" -e "ORACLE_PDB=orapdb" oracle/database:12.2.0.1-ee ORACLE PASSWORD FOR SYS, SYSTEM AND PDBADMIN: dockerOra278 LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 22-MAY-2018 10:52:09 Copyright (c) 1991, 2016, Oracle. All rights reserved. Starting /opt/oracle/product/12.2.0.1/dbhome_1/bin/tnslsnr: please wait... TNSLSNR for Linux: Version 12.2.0.1.0 - Production System parameter file is /opt/oracle/product/12.2.0.1/dbhome_1/network/admin/listener.ora Log messages written to /opt/oracle/diag/tnslsnr/fffb64768822/listener/alert/log.xml Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1))) Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521))) Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1))) STATUS of the LISTENER ------------------------ Alias LISTENER Version TNSLSNR for Linux: Version 12.2.0.1.0 - Production Start Date 22-MAY-2018 10:52:10 Uptime 0 days 0 hr. 0 min. 0 sec Trace Level off Security ON: Local OS Authentication SNMP OFF Listener Parameter File /opt/oracle/product/12.2.0.1/dbhome_1/network/admin/listener.ora Listener Log File /opt/oracle/diag/tnslsnr/fffb64768822/listener/alert/log.xml Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521))) The listener supports no services The command completed successfully [WARNING] [DBT-10102] The listener configuration is not selected for the database. EM DB Express URL will not be accessible. CAUSE: The database should be registered with a listener in order to access the EM DB Express URL. ACTION: Select a listener to be registered or created with the database. Copying database files 1% complete 13% complete 25% complete Creating and starting Oracle instance 26% complete 30% complete 31% complete 35% complete 38% complete 39% complete 41% complete Completing Database Creation 42% complete 43% complete 44% complete 46% complete 47% complete 50% complete Creating Pluggable Databases 55% complete 75% complete Executing Post Configuration Actions 100% complete Look at the log file "/opt/oracle/cfgtoollogs/dbca/oracdb/oracdb.log" for further details. SQL*Plus: Release 12.2.0.1.0 Production on Tue May 22 11:00:23 2018 Copyright (c) 1982, 2016, Oracle. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production SQL> System altered. SQL> Pluggable database altered. SQL> Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production The Oracle base remains unchanged with value /opt/oracle ######################### DATABASE IS READY TO USE! ######################### The following output is now a tail of the alert.log: Completed: alter pluggable database orapdb open 2018-05-22T11:00:22.727309+00:00 ORAPDB(3):CREATE SMALLFILE TABLESPACE "USERS" LOGGING DATAFILE '/opt/oracle/oradata/oracdb/orapdb/users01.dbf' SIZE 5M REUSE AUTOEXTEND ON NEXT 1280K MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO ORAPDB(3):Completed: CREATE SMALLFILE TABLESPACE "USERS" LOGGING DATAFILE '/opt/oracle/oradata/oracdb/orapdb/users01.dbf' SIZE 5M REUSE AUTOEXTEND ON NEXT 1280K MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO ORAPDB(3):ALTER DATABASE DEFAULT TABLESPACE "USERS" ORAPDB(3):Completed: ALTER DATABASE DEFAULT TABLESPACE "USERS"The existing container(s) could be view with
docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4252ebebab2f oracle/database:12.2.0.1-ee "/bin/sh -c 'exec $Oâ¦" 6 days ago Up 3 minutes (health: starting) 0.0.0.0:1521->1521/tcp, 0.0.0.0:5500->5500/tcp oracdbSince the listener port was exposed on the external host it is possible to connect remotely to the DB.
sqlplus sys/dockerOra278@localhost:1521/oracdb as sysdba SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 ORAPDB READ WRITE NOThe datafiles paths are based on container directory structure (OMF wasn't used in this case)
SQL> select con_id,name from v$datafile order by 1; CON_ID NAME ---------- -------------------------------------------------- 1 /opt/oracle/oradata/oracdb/system01.dbf 1 /opt/oracle/oradata/oracdb/sysaux01.dbf 1 /opt/oracle/oradata/oracdb/undotbs01.dbf 1 /opt/oracle/oradata/oracdb/users01.dbf 2 /opt/oracle/oradata/oracdb/pdbseed/sysaux01.dbf 2 /opt/oracle/oradata/oracdb/pdbseed/undotbs01.dbf 2 /opt/oracle/oradata/oracdb/pdbseed/system01.dbf 3 /opt/oracle/oradata/oracdb/orapdb/users01.dbf 3 /opt/oracle/oradata/oracdb/orapdb/system01.dbf 3 /opt/oracle/oradata/oracdb/orapdb/sysaux01.dbf 3 /opt/oracle/oradata/oracdb/orapdb/undotbs01.dbfHowever, files will appear in the external host directory.
pwd /opt/app/oracle/oradata/docker/oracdb ls -l drwxr-xr-x. 3 54321 54321 20 May 22 12:00 dbconfig drwxr-x---. 6 54321 54321 255 May 24 11:30 oracdbAs seen from above output, the owners of the directories don't exists on the external host. This is the reason to allow permission for the other group.
To stop the container following commands could be used.
docker stop -t 30 oracdbThe -t option makes the container wait 30 (configurable value) seconds before exiting regardless of the state of the DB. It's expected that database is cleanly shutdown (immediate) within 30 seconds. If the DB shutdowns before 30 seconds is up then container also exit soon after and doesn't wait full 30 seconds.
To start an existing container use
docker start oracdbThis will output the container name and return to prompt. To get the log output run the following
docker logs oracdb -fIf another docker container is to be created while the first one is running then this require different port numbers to be used for listener and express ports.
docker run --name mycdb -p 1522:1521 -p 5501:5500 ...In this case to access the DB from outside the container should use port 1522.
sqlplus sys/dockerOra278@localhost:1522/mycdb as sysdbaPatching Oracle DB in Docker
Patching an Oracle DB in docker involves creating a new image with the patched binaries and then running the database (=docker container) using the images with the patches. For this to work the database must be created using volumes. If not when the container is removed the database will be lost.
The GitHub files include docker files for creating the patched image. These are available inside the samples folder which is in SingleInstance folder (GitHut master.zip unziped in /opt/git).
/opt/git/docker-images-master/OracleDatabase/SingleInstance/samples/applypatchThe applypatch folder will have two folders for 12.1 and 12.2. Inside the 12.2 there's a patch folder to which patch files (including OPatch) must be copied to.
/opt/git/docker-images-master/OracleDatabase/SingleInstance/samples/applypatch/12.2.0.1/patchesBut this has to be done in a specific way with an predefined directory structure. The zipped Opatch files must be copied to the patch folder.
cp p6880880_122010_Linux-x86-64.zip /opt/git/docker-images-master/OracleDatabase/SingleInstance/samples/applypatch/12.2.0.1/patchesThe zipped patch files must be copied into individual directories named in a number sequence. In this case there's only one patch (27105253) and this will be copied to directory named 001.
cp p27105253_122010_Linux-x86-64.zip /opt/git/docker-images-master/OracleDatabase/SingleInstance/samples/applypatch/12.2.0.1/patches/001If there's a second patch then this will be copied to 002 and so on. The final status after files are copied is as below
pwd docker-images-master/OracleDatabase/SingleInstance/samples/applypatch/12.2.0.1/patches ls * applyPatches.sh p6880880_122010_Linux-x86-64.zip 001: p27105253_122010_Linux-x86-64.zipFinally run the script to build the patched image. This script is available in applypatch folder. It takes three arguments. One for specifying the version (-v). Second for the edition (-e) and finally a patch label which will be used for tagging the image (-p).
applypatch]$ ./buildPatchedDockerImage.sh -v 12.2.0.1 -e -p 27105253 ========================== DOCKER version: Client: Version: 18.03.1-ce API version: 1.37 Go version: go1.9.5 Git commit: 9ee9f40 Built: Thu Apr 26 07:20:16 2018 OS/Arch: linux/amd64 Experimental: false Orchestrator: swarm Server: Engine: Version: 18.03.1-ce API version: 1.37 (minimum version 1.12) Go version: go1.9.5 Git commit: 9ee9f40 Built: Thu Apr 26 07:23:58 2018 OS/Arch: linux/amd64 Experimental: false ========================== Building image 'oracle/database:12.2.0.1-ee-27105253' ... Sending build context to Docker daemon 210.8MB Step 1/9 : FROM oracle/database:12.2.0.1-ee ---> e4ac99149312 Step 2/9 : MAINTAINER Gerald VenzlAt the end of the build query the docker images to view the new patched image.---> Running in 5773808d04c7 Removing intermediate container 5773808d04c7 ---> 6ec9899a292d Step 3/9 : ENV PATCH_DIR="patches" PATCH_FILE="applyPatches.sh" ---> Running in a778d8cef721 Removing intermediate container a778d8cef721 ---> 8c6b0eb65d8c Step 4/9 : ENV PATCH_INSTALL_DIR=$ORACLE_BASE/patches ---> Running in 3fa7d705380c Removing intermediate container 3fa7d705380c ---> 969d170c1be8 Step 5/9 : COPY $PATCH_DIR $PATCH_INSTALL_DIR/ ---> 7e7e8dc9c7ef Step 6/9 : USER root ---> Running in 820d27e29c1e Removing intermediate container 820d27e29c1e ---> 80b218c84e9a Step 7/9 : RUN chown -R oracle:dba $PATCH_INSTALL_DIR ---> Running in e60c1a21b24a Removing intermediate container e60c1a21b24a ---> 0a24db9544d6 Step 8/9 : USER oracle ---> Running in bbd09c131108 Removing intermediate container bbd09c131108 ---> 03eae9504bea Step 9/9 : RUN chmod ug+x $PATCH_INSTALL_DIR/*.sh && sync && $PATCH_INSTALL_DIR/$PATCH_FILE ---> Running in a9f988e2f99d
docker images REPOSITORY TAG IMAGE ID CREATED SIZE oracle/database 12.2.0.1-ee-27105253 5cb7a1afe293 7 seconds ago 15.7GB oracle/database 12.2.0.1-ee e4ac99149312 12 days ago 13.2GB oraclelinux 7-slim c94cc930790a 4 weeks ago 117MBNext step is to make the Oracle database (=docker container) run using the patch image. For this remove the docker container and run it specifying the patched image. Since the database configuration files and datafiles exists, instead of a new DB being created the existing database will be started
docker rm oracdb ocker run --name oracdb -p 1521:1521 -p 5500:5500 -v /opt/app/oracle/oradata/docker/oracdg:/opt/oracle/oradata -e "ORACLE_SID=oracdb" -e "ORACLE_PWD=dockerOra278" -e "ORACLE_PDB=orapdb" oracle/database:12.2.0.1-ee-27105253 LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 22-MAY-2018 13:13:19 Copyright (c) 1991, 2016, Oracle. All rights reserved. Starting /opt/oracle/product/12.2.0.1/dbhome_1/bin/tnslsnr: please wait... TNSLSNR for Linux: Version 12.2.0.1.0 - Production System parameter file is /opt/oracle/product/12.2.0.1/dbhome_1/network/admin/listener.ora Log messages written to /opt/oracle/diag/tnslsnr/0f66ae60fa4f/listener/alert/log.xml Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1))) Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521))) Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1))) STATUS of the LISTENER ------------------------ Alias LISTENER Version TNSLSNR for Linux: Version 12.2.0.1.0 - Production Start Date 22-MAY-2018 13:13:20 Uptime 0 days 0 hr. 0 min. 0 sec Trace Level off Security ON: Local OS Authentication SNMP OFF Listener Parameter File /opt/oracle/product/12.2.0.1/dbhome_1/network/admin/listener.ora Listener Log File /opt/oracle/diag/tnslsnr/0f66ae60fa4f/listener/alert/log.xml Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521))) The listener supports no services The command completed successfully SQL*Plus: Release 12.2.0.1.0 Production on Tue May 22 13:13:20 2018 Copyright (c) 1982, 2016, Oracle. All rights reserved. Connected to an idle instance. SQL> ORACLE instance started. Total System Global Area 1610612736 bytes Fixed Size 8793304 bytes Variable Size 671089448 bytes Database Buffers 922746880 bytes Redo Buffers 7983104 bytes Database mounted. Database opened. SQL> Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production The Oracle base remains unchanged with value /opt/oracle ######################### DATABASE IS READY TO USE! ######################### The following output is now a tail of the alert.log: ORAPDB(3):Database Characterset for ORAPDB is AL32UTF8 2018-05-22T13:13:43.413019+00:00 ORAPDB(3):Opatch validation is skipped for PDB ORAPDB (con_id=0) ORAPDB(3):Opening pdb with no Resource Manager plan active Pluggable database ORAPDB opened read write 2018-05-22T13:13:44.369108+00:00 Starting background process CJQ0 Completed: ALTER DATABASE OPEN 2018-05-22T13:13:44.385359+00:00 CJQ0 started with pid=40, OS id=346 2018-05-22T13:13:45.487152+00:00 Shared IO Pool defaulting to 64MB. Trying to get it from Buffer Cache for process 89. =========================================================== Dumping current patch information =========================================================== Patch Id: 27105253 Patch Description: Database Release Update : 12.2.0.1.180116 (27105253) Patch Apply Time: 2018-05-22T12:14:02ZNext step is to run the post patch installation scripts which is run using datapatch. To run this inside the docker container use docker exec. Open all PDBs before running datapatch.
docker exec -ti oracdb /opt/oracle/product/12.2.0.1/dbhome_1/OPatch/datapatch -verbose SQL Patching tool version 12.2.0.1.0 Production on Tue May 22 13:18:06 2018 Copyright (c) 2012, 2017, Oracle. All rights reserved. Log file for this invocation: /opt/oracle/cfgtoollogs/sqlpatch/sqlpatch_538_2018_05_22_13_18_06/sqlpatch_invocation.log Connecting to database...OK Note: Datapatch will only apply or rollback SQL fixes for PDBs that are in an open state, no patches will be applied to closed PDBs. Please refer to Note: Datapatch: Database 12c Post Patch SQL Automation (Doc ID 1585822.1) Bootstrapping registry and package to current versions...done Determining current state...done Current state of SQL patches: Bundle series DBRU: ID 180116 in the binary registry and not installed in any PDB Adding patches to installation queue and performing prereq checks... Installation queue: For the following PDBs: CDB$ROOT PDB$SEED ORAPDB Nothing to roll back The following patches will be applied: 27105253 (DATABASE RELEASE UPDATE 12.2.0.1.180116) Installing patches... Patch installation complete. Total patches installed: 3 Validating logfiles... Patch 27105253 apply (pdb CDB$ROOT): SUCCESS logfile: /opt/oracle/cfgtoollogs/sqlpatch/27105253/21862470/27105253_apply_ORACDB_CDBROOT_2018May22_13_18_20.log (no errors) Patch 27105253 apply (pdb PDB$SEED): SUCCESS logfile: /opt/oracle/cfgtoollogs/sqlpatch/27105253/21862470/27105253_apply_ORACDB_PDBSEED_2018May22_13_20_27.log (no errors) Patch 27105253 apply (pdb ORAPDB): SUCCESS logfile: /opt/oracle/cfgtoollogs/sqlpatch/27105253/21862470/27105253_apply_ORACDB_ORAPDB_2018May22_13_20_27.log (no errors) SQL Patching tool complete on Tue May 22 13:22:11 2018Querying the patch registry shows patch applied on all DBs.
SQL> select con_id,patch_id,patch_uid,version,action,status,BUNDLE_ID from cdb_registry_sqlpatch order by 1; CON_ID PATCH_ID PATCH_UID VERSION ACTION STATUS BUNDLE_ID ---------- ---------- ---------- -------------------- --------------- --------------- ---------- 1 27105253 21862470 12.2.0.1 APPLY SUCCESS 180116 3 27105253 21862470 12.2.0.1 APPLY SUCCESS 180116The process is repeated when the next patch is need to applied. For example applying release update 12.2.0.1.180417 (27674384) would entail creating a new image
docker images REPOSITORY TAG IMAGE ID CREATED SIZE oracle/database 12.2.0.1-ee-27674384 b6840341320a 8 minutes ago 16.1GB oracle/database 12.2.0.1-ee-27105253 5cb7a1afe293 3 hours ago 15.7GB oraclelinux 7-slim c94cc930790a 4 weeks ago 117MBRemove and run the docker container (= DB) out of the patch container and run the post patch installation scripts. Verify patch is applied in all PDBs.
select con_id,patch_id,patch_uid,version,action,status,BUNDLE_ID from cdb_registry_sqlpatch order by 1; CON_ID PATCH_ID PATCH_UID VERSION ACTION STATUS BUNDLE_ID ---------- ---------- ---------- -------------------- --------------- --------------- ---------- 1 27674384 22098633 12.2.0.1 APPLY SUCCESS 180417 1 27105253 21862470 12.2.0.1 APPLY SUCCESS 180116 3 27674384 22098633 12.2.0.1 APPLY SUCCESS 180417 3 27105253 21862470 12.2.0.1 APPLY SUCCESS 180116Finally remove the old image (if no longer needed).
docker rmi oracle/database:12.2.0.1-ee-27105253 Untagged: oracle/database:12.2.0.1-ee-27105253 Deleted: sha256:5cb7a1afe2933a261d997ff53632a1f8615411b58f1caaebb4407e52e522cdbc Deleted: sha256:a9dbca6635a8cb33e856ca9b27986d4faea1ffa3a2b34791dce43f2c156ce3e5Creating a new PDB in Docker
Creating a new PDB in a docker container is same as creating in any other setup. Only thing to consider is if the file name convert path. This has to be a location that is in the external volume. In this post the database created had docker container path /opt/oracle/oradata mapped to an volume for new PDB's datafile to persist after container remove. Having this path as prefixed would make the PDB datafiles to be created in the same volume. For example creating a PDB in a non-OMF setting
create pluggable database mypdb admin user mypdb1 identified by mypdb1 FILE_NAME_CONVERT=('/opt/oracle/oradata/oracdb/pdbseed/','/opt/oracle/oradata/oracdb/mypdb/'); SQL> alter pluggable database mypdb open; SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 ORAPDB READ WRITE NO 4 MYPDB READ WRITE NOSince the PDB seed was patched any newly created PDBs will also be patched.
SQL> alter session set container=mypdb; select con_id,patch_id,patch_uid,version,action,status,BUNDLE_ID from cdb_registry_sqlpatch order by 1; CON_ID PATCH_ID PATCH_UID VERSION ACTION STATUS BUNDLE_ID ---------- ---------- ---------- -------------------- --------------- --------------- ---------- 4 27674384 22098633 12.2.0.1 APPLY SUCCESS 180417 4 27105253 21862470 12.2.0.1 APPLY SUCCESS 180116If OMF is used and db_create_file_dest location is under the directory mapped to volume ( db_create_file_dest=/opt/oracle/oradata) then a new PDB could be created without any file name conversion.
SQL> create pluggable database cxpdb admin user cxpdb identified by cxpdb default tablespace users; SQL> alter pluggable database cxpdb open; SQL> alter session set container=cxpdb; SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 5 CXPDB READ WRITE NO
Plug/Unplug PDB in Docker
Similar to creating a new PDB plugging or unplugging operations are also not all that different to any other setup. What needs to be considered is if the metadata file is preserved across docker container stop and starts.
Unplug a PDB in Docker
The CDB has a single PDB which will be unplugged.
SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 ORAPDB READ WRITE NO SQL> alter pluggable database orapdb close;The specified metadata file location is part of the volume. As such it will be preserved across container restarts.
SQL> alter pluggable database orapdb unplug into '/opt/oracle/oradata/oracdb/orapdb/orapdb.xml';The metadata file could listed on the external hosts in the location mapped to the volume (-v /opt/app/oracle/oradata/docker/oracdb:/opt/oracle/oradata)
# ls -l /opt/app/oracle/oradata/docker/oracdg/oracdb/orapdb/orapdb.xml -rw-r--r--. 1 54321 54321 7336 May 22 12:06 /opt/app/oracle/oradata/docker/oracdb/oracdb/orapdb/orapdb.xmlFinally drop the PDB
SQL> drop pluggable database orapdb keep datafiles; SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NOPlug a PDB in Docker - Same Docker Container
In this case the earlier unplugged PDB is plugged into the CDB in the same container. As it is the same container the metadata file location is accessible to the container along with data files since there has been no file movement. Therefore plug the PDB specifying the meta data file.
SQL> CREATE PLUGGABLE DATABASE orapdb using '/opt/oracle/oradata/oracdb/orapdb/orapdb.xml' nocopy; SQL> alter pluggable database orapdb open; SQL>alter pluggable database orapdb save state; SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 ORAPDB READ WRITE NOPlug a PDB in Docker - Different Docker Container
Plugging a PDB into a CDB in a different container is slightly different to above as this would require making the files related to PDB (data files and metadata file) accessible inside the destination container. This would require creating a directory in the destination docker container and copying the PDB related files to it. Once this is done reset of the steps are same as moving PDBs between servers.
It's assumed that PDB unplugged and datafiles are available in /opt/oracle/oradata/oracdb/orapdb/ (or externally to docker container in /opt/app/oracle/oradata/docker/oracdb/oracdb/orapdb). This PDB will be moved into a CDB in docker container called mycdb.
In the destination container create a directory to stage the PDB related files. This must be also accessible on the external hosts as well. The mycdb was created with a volume mapped as -v /opt/app/oracle/oradata/docker/mycdb:/opt/oracle/oradata. As such the staging directory is created inside the oradata directory.
docker exec -ti mycdb mkdir -p /opt/oracle/oradata/pdbstagingThis is visible on the external host directory strcuture
pwd /opt/app/oracle/oradata/docker/mycdb ls dbconfig mycdb MYCDB pdbstagingCopy (or scp if the destination docker container is in a different location) the PDB related files to the staging directory and check these are visible inside the docker container. Once copied make sure that file ownership is changed to oracle user and group inside the container.
cp /opt/app/oracle/oradata/docker/oracdb/oracdb/orapdb/* /opt/app/oracle/oradata/docker/mycdb/pdbstaging/ chown 54321:54321 * # ls -l -rw-r--r--. 1 54321 54321 7577 May 30 14:25 orapdb.xml -rw-r-----. 1 54321 54321 503324672 May 30 14:25 sysaux01.dbf -rw-r-----. 1 54321 54321 283123712 May 30 14:25 system01.dbf -rw-r-----. 1 54321 54321 104865792 May 30 14:25 undotbs01.dbf -rw-r-----. 1 54321 54321 5251072 May 30 14:25 users01.dbf docker exec -ti mycdb ls /opt/oracle/oradata/pdbstaging orapdb.xml sysaux01.dbf system01.dbf undotbs01.dbf users01.dbfRun the DBMS_PDB.CHECK_PLUG_COMPATIBILITY and if successful plug the PDB at the destination. In this case the destination CDB uses OMF.
create pluggable database pdbthree as clone using '/opt/oracle/oradata/pdbstaging/orapdb.xml' source_file_name_convert=('/opt/oracle/oradata/oracdb/orapdb','/opt/oracle/oradata/pdbstaging') move; Pluggable database created. SQL> show pdbs; CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 MYPDB READ WRITE NO 5 PDBTHREE MOUNTED SQL> alter pluggable database pdbthree open; SQL> alter session set container=pdbthree; SQL> select name from v$datafile; NAME ---------------------------------------------------------------------------------------------------- /opt/oracle/oradata/MYCDB/6D6D69D5DC29042BE053020011ACFE1B/datafile/o1_mf_system_fjxb3m30_.dbf /opt/oracle/oradata/MYCDB/6D6D69D5DC29042BE053020011ACFE1B/datafile/o1_mf_sysaux_fjxb3m3o_.dbf /opt/oracle/oradata/MYCDB/6D6D69D5DC29042BE053020011ACFE1B/datafile/o1_mf_undotbs1_fjxb3m3p_.dbf /opt/oracle/oradata/MYCDB/6D6D69D5DC29042BE053020011ACFE1B/datafile/o1_mf_users_fjxb3m3r_.dbf
Export and Import From DB in Docker
Similar to previous cases the concern here is if the dump files are to be made available out side of the docker container. If the intention is to copy or move the dump file to a different location then this must be accessible out side of the docker container. For this reason the dump file directory must be created in the volume location.
docker exec -ti oracdb mkdir -p /opt/oracle/oradata/dpdumpsThis will be visible in the external host directory path
pwd /opt/app/oracle/oradata/docker/oracdb ls dbconfig dpdumps oracdbCreate database directory using this and run export and imports.
create directory dumpdir as '/opt/oracle/oradata/dpdumps'; grant read,write on directory dumpdir to asanga;Export could be done by connecting to DB externally
expdp asanga/asa@localhost:1521/orapdb directory=dumpdir tables=x Export: Release 12.2.0.1.0 - Production on Wed May 23 11:43:49 2018 Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production Starting "ASANGA"."SYS_EXPORT_TABLE_01": asanga/********@localhost:1521/orapdb directory=dumpdir tables=x Processing object type TABLE_EXPORT/TABLE/TABLE_DATA Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER Processing object type TABLE_EXPORT/TABLE/TABLE . . exported "ASANGA"."X" 12.75 KB 1000 rows Master table "ASANGA"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded ****************************************************************************** Dump file set for ASANGA.SYS_EXPORT_TABLE_01 is: /opt/oracle/oradata/dpdumps/expdat.dmp Job "ASANGA"."SYS_EXPORT_TABLE_01" successfully completed at Wed May 23 10:44:21 2018 elapsed 0 00:00:2Or as a docker container execution
docker exec -ti oracdb expdp asanga/asa@orapdb directory=dumpdir tables=x Export: Release 12.2.0.1.0 - Production on Wed May 23 10:47:22 2018 Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production Starting "ASANGA"."SYS_EXPORT_TABLE_01": asanga/********@orapdb directory=dumpdir tables=x Processing object type TABLE_EXPORT/TABLE/TABLE_DATA Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER Processing object type TABLE_EXPORT/TABLE/TABLE . . exported "ASANGA"."X" 12.75 KB 1000 rows Master table "ASANGA"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded ****************************************************************************** Dump file set for ASANGA.SYS_EXPORT_TABLE_01 is: /opt/oracle/oradata/dpdumps/expdat.dmp Job "ASANGA"."SYS_EXPORT_TABLE_01" successfully completed at Wed May 23 10:47:43 2018 elapsed 0 00:00:20Import too could be done same way provided the dump file is visible inside the docker container.
docker exec -ti oracdb impdp asanga/asa@orapdb directory=dumpdir dumpfile=expdat.dmp Import: Release 12.2.0.1.0 - Production on Wed May 23 10:48:46 2018 Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production Master table "ASANGA"."SYS_IMPORT_FULL_01" successfully loaded/unloaded Starting "ASANGA"."SYS_IMPORT_FULL_01": asanga/********@orapdb directory=dumpdir dumpfile=expdat.dmp Processing object type TABLE_EXPORT/TABLE/TABLE Processing object type TABLE_EXPORT/TABLE/TABLE_DATA . . imported "ASANGA"."X" 12.75 KB 1000 rows Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER Job "ASANGA"."SYS_IMPORT_FULL_01" successfully completed at Wed May 23 10:49:10 2018 elapsed 0 00:00:21Using RMAN Backup in Docker
The database created by default in docker runs in noarchive log mode. As a result one could only take cold backups. It is possible to stop the docker container and make a backup of the data files using OS utilities if data files are visible outside the docker container due to use of volumes. However, if RMAN backups are preferred then it would require putting the database in mount mode. This cannot be done while connected remotely as soon as database is shutdown the listener registration will be lost.
rman target sys/dockerOra278@localhost:1521/oracdb RMAN> shutdown immediate; using target database control file instead of recovery catalog database dismounted Oracle instance shut down RMAN> startup mount RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =========================================================== RMAN-03002: failure of startup command at 05/30/2018 15:34:53 ORA-12514: TNS:listener does not currently know of service requested in connect descriptorIf the backup files to persist then backup file location must be on directory path mapped to the external volume.
docker exec -ti oracdb mkdir -p /opt/oracle/oradata/backupsThis folder is visible on the external host
pwd /opt/app/oracle/oradata/docker/oracdg ls backups dbconfig dpdumps oracdbTo start the database in mount mode login to the docker container and start the DB in mount mode(this is fundamentally against the use of docker containers. One should access the service running out of docker container but should never connect to it, if it could be helped).
$ docker exec -ti oracdb /bin/bash [oracle@4252ebebab2f ~]$ sqlplus / as sysdba SQL> shutdown immediate; SQL> startup mount;Once the database is in mount backup could be run by connecting remotely
rman target sys/dockerOra278@localhost:1521/oracdb Starting backup at 23-MAY-18 using channel ORA_DISK_1 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set input datafile file number=00001 name=/opt/oracle/oradata/oracdb/system01.dbf input datafile file number=00003 name=/opt/oracle/oradata/oracdb/sysaux01.dbf input datafile file number=00004 name=/opt/oracle/oradata/oracdb/undotbs01.dbf input datafile file number=00007 name=/opt/oracle/oradata/oracdb/users01.dbf channel ORA_DISK_1: starting piece 1 at 23-MAY-18 channel ORA_DISK_1: finished piece 1 at 23-MAY-18 piece handle=/opt/oracle/oradata/backups/backup05t3jug5_1_1 tag=TAG20180523T110125 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:35 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set input datafile file number=00014 name=/opt/oracle/oradata/oracdb/orapdb/sysaux01.dbf input datafile file number=00013 name=/opt/oracle/oradata/oracdb/orapdb/system01.dbf input datafile file number=00015 name=/opt/oracle/oradata/oracdb/orapdb/undotbs01.dbf input datafile file number=00016 name=/opt/oracle/oradata/oracdb/orapdb/users01.dbf channel ORA_DISK_1: starting piece 1 at 23-MAY-18 channel ORA_DISK_1: finished piece 1 at 23-MAY-18 piece handle=/opt/oracle/oradata/backups/backup06t3juh9_1_1 tag=TAG20180523T110125 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:15 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set input datafile file number=00006 name=/opt/oracle/oradata/oracdb/pdbseed/sysaux01.dbf input datafile file number=00005 name=/opt/oracle/oradata/oracdb/pdbseed/system01.dbf input datafile file number=00008 name=/opt/oracle/oradata/oracdb/pdbseed/undotbs01.dbf channel ORA_DISK_1: starting piece 1 at 23-MAY-18 channel ORA_DISK_1: finished piece 1 at 23-MAY-18 piece handle=/opt/oracle/oradata/backups/backup07t3juho_1_1 tag=TAG20180523T110125 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:15 Finished backup at 23-MAY-18 Starting Control File and SPFILE Autobackup at 23-MAY-18 piece handle=/opt/oracle/product/12.2.0.1/dbhome_1/dbs/c-2651185508-20180523-01 comment=NONE Finished Control File and SPFILE Autobackup at 23-MAY-18RMAN could also be accessed via docker exec
docker exec -ti oracdb rman target / RMAN> list backup summary; using target database control file instead of recovery catalog List of Backups =============== Key TY LV S Device Type Completion Time #Pieces #Copies Compressed Tag ------- -- -- - ----------- --------------- ------- ------- ---------- --- 5 B F A DISK 23-MAY-18 1 1 NO TAG20180523T110125 6 B F A DISK 23-MAY-18 1 1 NO TAG20180523T110125 7 B F A DISK 23-MAY-18 1 1 NO TAG20180523T110125 8 B F A DISK 23-MAY-18 1 1 NO TAG20180523T110231The backup files are accessible outside the docker container.
cd /opt/app/oracle/oradata/docker/oracdg/backups/ ls backup05t3jug5_1_1 backup06t3juh9_1_1 backup07t3juho_1_1
Miscellaneous
Login to docker container as root
If ever needed to login to docker container as root use the following.
docker exec -ti --user root oracdb /bin/bash bash-4.2# whoami root bash-4.2#Committing changes to the docker image
Imagine the scenario where want to disable the use of OMF after the docker image has been built. One option is to make the changes to earlier mentioned files and built the image from scratch. But if there's patches to apply too this could require building another image. However it is possible to make changes to the files inside the docker container and create a new image with those changes. Taking the earlier mentioned scenario, to disable OMF login the docker container and modify the dbca.rsp.tmpl and createDB.sh files to default settings. (vi editior is not present on the OEL 7 slim image. However this could be installed using yum connected as root (see above to connect to docker as root).
docker exec -ti oracdb /bin/bash [oracle@4252ebebab2f ~]$ cd /opt/oracle [oracle@4252ebebab2f oracle]$ ls admin createDB.sh oradata scripts cfgtoollogs dbca.rsp.tmpl product setPassword.sh checkDBStatus.sh diag runOracle.sh startDB.sh checkpoints oraInventory runUserScripts.sh [oracle@4252ebebab2f oracle]$ vi dbca.rsp.tmpl [oracle@4252ebebab2f oracle]$ grep initParam dbca.rsp.tmpl # Name : initParams initParams=audit_trail=none,audit_sys_operations=false [oracle@4252ebebab2f oracle]$ vi createDB.sh [oracle@4252ebebab2f oracle]$ grep control01 createDB.sh ALTER SYSTEM SET control_files='$ORACLE_BASE/oradata/$ORACLE_SID/control01.ctl' scope=spfile;Exit the docker container and commit the changes by building a new image. For the commit specify the container and a new tag.
docker commit -m="no OMF" oracdb oracle/database:12.2.0.1-ee-27674384-noOMF sha256:e0c9e849dc02a9b3a364c5761c3f4bd4281920fb68a953271be5f93bf2cd8afc [oracle@hpc3 ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE oracle/database 12.2.0.1-ee-27674384-noOMF e0c9e849dc02 16 seconds ago 17.1GB oracle/database 12.2.0.1-ee-27674384 efab903d5833 7 days ago 16.2GB oraclelinux 7-slim c94cc930790a 5 weeks ago 117MBNow there are two images with OMF and without OMF which could be used to create databases.
docker run --name cdb2 ..... oracle/database:12.2.0.1-ee-27674384-noOMFRemove dangling images and volumes
Identify dangling volumes
docker volume ls -qf dangling=true 299236fea77483719886b804ca48ad5f42738e7c0085d597824793daae968165 7dfa1c6d924180bc2f412fa52a6a6a5f0f90d82297c51501e76e3fa227e71eb7Remove dangling volumes
docker volume rm $(docker volume ls -qf dangling=true)Identify dangling images
docker images -qf dangling=trueRemove dangling images
docker rmi $(docker images -qf dangling=true)Useful metalink notes
Oracle Support for Database Running on Docker [ID 2216342.1]
Support for Docker Running on Oracle Linux [ID 1921163.1]
Related Post
Installing Docker CE on RHEL 7