Seth Miller

Technical ramblings of an IT guy

How Can I Use Logging Tracing and Debugging with RMAN?

RMAN will provide more than enough information about what it is doing through its logging mechanisms. Standard logging is printed to the screen (standard output) by default. If you want to redirect standard output to a file, you can specify the LOG clause. This clause can be given as part of the initial rman command.

rman target / LOG /tmp/rman.log

It can also be enabled interactively. It is useful to note that the SPOOL LOG clause can be enabled and disabled at different parts of the session and to different files.

rman target /

RMAN> SPOOL LOG TO '/tmp/listbackup.txt';
RMAN> list backup;
RMAN> SPOOL LOG TO '/tmp/reportschema.txt';
RMAN> report schema;

Both of the LOG clauses (part of the rman command or SPOOL LOG) redirect the logging output. If you want both the standard output printed to screen and printed to a file, use the tee command.

rman target / | tee '/tmp/rman.log'

If you need more information than you are getting from standard logging, the next option is to use DEBUG. Debug produces a LOT of information and will likely have to be parsed to be useful. You can use the DEBUG clause on the command line to turn on debugging for the entire session. Similar to LOG the debug will print to standard output by default. Specify the TRACE parameter to capture the debug output to a file while still printing the standard logging output to the screen.

rman target / DEBUG TRACE '/tmp/rman.trc'

Similar to LOG, debug can also be turned on and off interactively. One difference though is that debugging can be enabled and disabled within a run block.

rman target / TRACE '/tmp/rman.trc'

RMAN> run {
2> debug on;
3> report schema;
4> debug off;
5> crosscheck archivelog all;
6> }

When DEBUG is enabled, both the standard logging and the trace logging are affected. The standard logging is almost exactly the same as it is without DEBUG enabled, except that each line is preceded with an RMAN-XXXXX: message identifier with the X‘s being replaced with a number.

How do I identify and set my environment for the Oracle Database and Clusterware homes on a server?

When Oracle software is installed on a server, it generally has a single home referred to as the oracle home. The installer will usually add the oracle home to the central inventory. The location of the central inventory can be determined by querying an operating system specific oracle inventory location file. On Linux, this location file is /etc/oraInst.loc. If you ever installed the Oracle database software and wondered why you need to run a root script at the end of the installation, this is one of the files created by root because an unprivileged user does not have the ability to write to the /etc directory.

The file in the central inventory with the information about the oracle homes is <Inventory Location>/ContentsXML/inventory.xml. As you can see from the file extension, this file is in the XML format. Here is an example of an oracle inventory file from a server that has a single installation of Oracle Database

<?xml version="1.0" standalone="yes" ?>
<!-- Copyright (c) 1999, 2013, Oracle and/or its affiliates.
All rights reserved. -->
<!-- Do not modify the contents of this file by hand. -->
<HOME NAME="Ora_home1" LOC="/u01/app/oracle/product/11.2.0/dbhome_1" TYPE="O" IDX="1"/>

It should be fairly obvious that the LOC attribute of the HOME element is the directory path of that oracle home. What isn’t so obvious is what the home contains.

In fact, if we look at the inventory file of a server with a database home as well as a clusterware home, it’s not clear which is which. We could infer that the home containing the word grid is a clusterware home and the home containing the word dbhome is the database home but those directory names are chosen by the user and could be something completely different.

<?xml version="1.0" standalone="yes" ?>
<!-- Copyright (c) 1999, 2013, Oracle and/or its affiliates.
All rights reserved. -->
<!-- Do not modify the contents of this file by hand. -->
<HOME NAME="Ora_home1" LOC="/u01/app/11.2.0/grid" TYPE="O" IDX="1"/>
<HOME NAME="Ora_home2" LOC="/u01/app/oracle/product/11.2.0/dbhome_1" TYPE="O" IDX="2"/>

In order to identify what type of installation is contained in an oracle home, we have to look at the inventory contained within the oracle home. Each of the oracle homes listed in the central inventory will have a <Oracle Home>/inventory/ContentsXML/comps.xml file. These local inventory files are much, much larger than the central inventory file. The information about the installation that we are looking for is right up at the top of the file in the NAME attribute of the COMP element which looks like this.

<COMP NAME="oracle.server" VER="" BUILD_NUMBER="0" REP_VER="" RELEASE="Production" INV_LOC="Components/oracle.server/" LANGS="en" XML_INV_LOC="Components21/oracle.server/" ACT_INST_VER="" DEINST_VER="" INSTALL_TIME="2015.Dec.14 12:51:59 EST" INST_LOC="/u01/app/oracle/product/11.2.0/dbhome_1/oracle.server">

There are dozens of these COMP elements in the file so we need to make sure the one we’re looking at is nested under the TL_LIST which is nested under the PRD_LIST root element. If we looked at this in xpath notation, it would be /PRD_LIST/TL_LIST/COMP/@NAME. The attribute location is the same for database and clusterware homes. The value will either be or oracle.server, the former being a clusterware home and the latter being a database home.

Now that we know where the information is, we can use a script to gather that information into a variable. The find_homes function creates an associative array called HOMES_ARR that holds each oracle home directory path and its home type.

function find_homes
  unset global HOMES_ARR
  declare -g -A HOMES_ARR
  local LIST_OF_HOMES=($(echo "cat //HOME[contains(@TYPE, \"O\")]/@LOC" | \
                         xmllint --shell \
                         $(grep '^inventory_loc=' /etc/oraInst.loc | \
                           cut -d= -f2)/ContentsXML/inventory.xml | \
                           grep 'LOC=' | \
                           sed 's/.*="\([^"]\+\)"/\1/'))
  for MYHOME in "${LIST_OF_HOMES[@]?}"; do
    local HOME_TYPE=$(echo "cat /PRD_LIST/TL_LIST/COMP/@NAME" | \
                      xmllint --shell $MYHOME/inventory/ContentsXML/comps.xml | \
                      grep 'NAME=' | \
                      sed 's/.*="\([^"]\+\)"/\1/')

If we run this on the server containing the second central inventory from above that has both a clusterware and database home, I can then loop through the HOMES_ARR variable and see the information for each home.

function homes_loop
  for MYHOME in ${!HOMES_ARR[@]}; do
    echo "Oracle home ${MYHOME} is an "${HOMES_ARR["${MYHOME}"]}" home"
[oracle@localhost ~]$ homes_loop
Oracle home /u01/app/oracle/product/11.2.0/dbhome_1 is an oracle.server home
Oracle home /u01/app/11.2.0/grid is an home

The oraenv script does a really good job of setting the environment of the OS user to that of a database instance.

[oracle@localhost ~]$ grep -v '^#\|^$' /etc/oratab
[oracle@localhost ~]$ . oraenv
ORACLE_SID = [oracle] ? orcl
The Oracle base remains unchanged with value /u01/app/oracle
[oracle@localhost ~]$ export ORAENV_ASK=NO
[oracle@localhost ~]$ export ORACLE_SID=orcl
[oracle@localhost ~]$ . oraenv
The Oracle base remains unchanged with value /u01/app/oracle

However, unless ASM is installed on a server, setting the environment for the clusterware home is not very straight forward. We could still use oraenv, but then we would need to either manually type or copy/paste the entire path of the clusterware home.

[oracle@localhost ~]$ . oraenv
ORACLE_SID = [oracle] ?
ORACLE_HOME = [/home/oracle] ? /u01/app/11.2.0/grid
The Oracle base has been set to /u01/app/oracle

Since we can identify the directory path of the clusterware home from the HOMES_ARR variable, we can take advantage of the many things oraenv does without having to have an entry for the clusterware home in the oratab.

function grid
  for MYHOME in ${!HOMES_ARR[@]}; do
    local HOMETYPE=${HOMES_ARR["${MYHOME}"]}
    if [ "${HOMETYPE}" = "" ]; then
      sed -e 's/${ORAENV_ASK:-""}/"NO"/' -e 's%^\s*ORAHOME=.*%ORAHOME="'${MYHOME}'"%' $(which oraenv) > /tmp/oraenv$PPID
      . /tmp/oraenv$PPID
      rm /tmp/oraenv$PPID
      export GRID_HOME="${MYHOME}"

This grid function in combination with the find_homes function can be put into a profile script and used by multiple users on the database servers without having to hard code any paths.

Query Active Directory From Your PC

I’m working on an Enterprise Manager 12c implementation with a client which includes integration with Active Directory for user authentication and authorization. The question came up, “How do I know which users are in which groups in EM?”. Since the AD groups in which the users belong correlate directly with the roles in EM, I put together this document to query Active Directory to find that information.

The Active Directory information can be queried from the command line if the appropriate LDAP tools are present. Most Windows installations will have ldapsearch tool. LDAP search tools are present in other operating systems as well and most of the parameters are the same, although I have found small differences with certain parameters and syntax, especially between the Windows and Linux LDAP tools.

This document demonstrates the use of the ldapsearch command line tool for the Windows command line in various capacities. An advantage of using your own PC is that you are probably already authenticated with AD, so no additional authentication with ldapsearch is necessary. Most of the document shows how to set variables to be used in the ldapsearch command. Once the variables are set, execute the one of the ldapsearch commands towards the end of the document.


Set the ldap_host variable to the hostname or IP of one of the Active Directory hosts.

set ldap_host="<hostname or IP of AD>"


Set the basedn variable to the Base Directory Name, which establishes a starting point or LDAP branch for searching.

set basedn="OU=<organizational unit>, DC=<low level domain component>, DC=<mid level domain component>, DC=<high level domain component>"


There are two parameters used to search; searchfilter and keyfilter.

The searchfilter parameter limits which records are returned and is mandatory. The most basic form of the search filter is a key and value combination.

set searchfilter="CN=<canonical name>"


The keyfilter parameter is the record key filter and is optional. This is a text filter and can be in many formats. The most basic form is just to specify a key.

set keyfilter="memberOf"



Following are four examples of how to set parameters for the ldapsearch command that will show four different sets of data.

Example 1

Show all of the visible Active Directory data for a particular user.

set basedn="OU=people,DC=example,DC=com"
set searchfilter="CN=Miller, Seth"
set keyfilter="*"


Example 2

List the groups in which a particular user belongs. Notice the LDAP query is the same as the previous example but the information being shown is limited to the memberOf key.

set basedn="OU=people,DC=example,DC=com"
set searchfilter="CN=Miller, Seth"
set keyfilter="memberOf"


Example 3

Show all of the visible Active Directory data for a particular group.

set basedn="OU=groups,DC=example,DC=com"
set searchfilter="CN=EM_User"
set keyfilter="*"


Example 4

List the members of a particular group. Notice the LDAP query is the same as the previous example but the information being shown is limited to the member key.

set basedn="OU=groups,DC=example,DC=com"
set searchfilter="CN=EM_User"
set keyfilter="member"


If you are already authenticated with AD, you can use native authentication for the ldapsearch command with the -Z flag.

ldapsearch -h %ldap_host% -Z -b %basedn% %searchfilter% %keyfilter%


If native authentication does not work, a username and password can be included.

Create an environment variable with your AD password.

set /p userpassword="Enter Password: "


Create an environment variable with your AD username.

set username="CN=Miller, Seth,OU=people,DC=example,DC=com"


This command is the same as the previous ldapsearch command, except it now includes explicit authentication using the username and userpassword variables.

ldapsearch -h %ldap_host% -w %userpassword% -D %username% -b %basedn% %searchfilter% %keyfilter%

Oracle DB12c in Docker

Docker has been making a lot of noise in the last couple of years. It piqued my interest recently when I came across a tweet saying that Oracle had recently uploaded an Oracle Linux 7 image to the Docker repository. Containers are nothing new in the Unix space but they are relatively new in Linux. Docker was built to take advantage of Linux Containers.

I asked on Twitter if anyone had successfully installed and run the Oracle Database inside of a Linux Container using Docker. I got a couple of responses that it has been done. I looked around for a blog post or documentation on how to do it and couldn’t find one so, here it is. This is also my first use of Linux Containers and Docker so feel free to comment if there are things that I missed or could do more efficiently.

Note: These instructions presume the user is familiar with VirtualBox and at least an intermediate user of Linux.

Create a small VM. Oracle Linux 7 doesn’t need a lot of horsepower to run. However, Oracle Database will run better with more resources. My VM has 4GB of memory and 25GB of dynamically added disk space. Add a second disk of the same size that will be used for the Docker images. Make sure to include a network adapter that will be able to access the internet.

Start the VM. Since there is no OS on the VM and no mounted ISO, you should be presented with a screen asking which ISO you want to use as a start-up disk.

2015-02-06 23_15_41-OL7 [Powered Off] - Oracle VM VirtualBox


Press enter when the install screen comes up.

2015-02-06 23_17_46-OL7 [Running] - Oracle VM VirtualBox


Choose the language.

2015-02-06 23_19_31-OL7 [Running] - Oracle VM VirtualBox


There should only be one exclamation mark on the screen for the installation destination. Click on the exclamation mark to choose the disk layout. Select the first disk and click Done.

2015-02-11 21_10_52-OL7 [Running] - Oracle VM VirtualBox


Click Begin Installation.

2015-02-06 23_22_35-OL7 [Running] - Oracle VM VirtualBox


The Oracle Linux 7 install is completely different from previous installs. The tasks have become much more parallelized. You may notice that the installation has already begun at this point. While the OS installs, click Root Password.

2015-02-06 23_22_52-OL7 [Running] - Oracle VM VirtualBox


Enter a password for root and click Done.

2015-02-06 23_23_02-OL7 [Running] - Oracle VM VirtualBox


The OS installation will now finish.

2015-02-06 23_23_22-OL7 [Running] - Oracle VM VirtualBox


Once the install is done, click Reboot.

2015-02-06 23_27_10-OL7 [Running] - Oracle VM VirtualBox


Install additional packages that will be needed in the VM to support running Docker.

yum -y --enablerepo=ol7_addons install docker btrfs-progs vim bzip2 kernel-uek-devel-$(uname -r) tigervnc-server xterm xorg-x11-xauth


Add the Guest Additions ISO to the VM by clicking the Devices menu on the VM and clicking Insert Guest Additions CD image.

2015-02-12 17_28_33-OL7 [Running] - Oracle VM VirtualBox


Mount the Guest Additions ISO and install.

mount /dev/cdrom /mnt


Format the second disk in the VM with btrfs. This will be used for the docker images.

mkfs.btrfs /dev/sdb


Query the UUID of /dev/sdb. This will be used in the next step.

blkid /dev/sdb


Create the Docker mount config file /etc/systemd/system/var-lib-docker.mount. Change the UUID to match that of /dev/sdb from the previous step.

Description = Docker Image Store

What = UUID=<UUID from previous step>
Where = /var/lib/docker
Type = btrfs

WantedBy =


Enable the Docker mount.

systemctl enable var-lib-docker.mount


Create the Docker configuration file.

echo 'OPTIONS=-s btrfs' > /etc/sysconfig/docker


Copy the Docker service to systemd to allow you to start and stop the service with systemctl.

cp /usr/lib/systemd/system/docker.service /etc/systemd/system/docker.service


Enable and then start Docker.

systemctl enable docker
systemctl start docker


Pull down the Oracle Linux Docker image. This will require a connection to the internet.

docker pull oraclelinux


View the images currently stored on the VM. This may include more than one since the Oracle Linux Docker image is versioned.

docker images


Install the necessary packages in a container to support the database. The docker run command will create a new container from the image and start it. It will only run as long as the command takes to complete. After it completes. The container will still exist but will not be running.

MYCOMMAND='yum -y --enablerepo=ol7_addons install oracle-rdbms-server-12cR1-preinstall vim bzip2 xorg-x11-xauth xeyes xhost'
docker run --name oraol7 oraclelinux $MYCOMMAND


List the container that was just created. Running the docker ps command without the -a parameter will only show the running containers. Since the container we created is no longer running, it would not show up with only the docker ps command.

docker ps -a


Commit the container just created to a new image. The new image will be a copy of the container but can also be used to create new containers.

docker commit oraol7 oraol7


Now you can see an additional image available in the Docker images. Notice the virtual size of the image just created is significantly larger than the original oraclelinux images.

docker images


The container has been committed to an image so the changes made to the original image have been saved. You can now delete the container.

docker rm oraol7


Notice the container no longer exists.

docker ps -a


Load the Oracle DB12c binaries onto the VM or mount through a shared folder. The files in this case are in the /mnt directory.

Start vncserver on the host VM. Connect to the vnc session on your PC or directly on the VM.



Create a container from the oraol7 image and run it in interactive mode with a bash shell. Give the container a hostname of db12c. Create two directory mappings between the host and the container; one for the DB12c binaries and the other to forward the X11 traffic.

docker run -it --name oraol7 -h db12c -v /mnt:/mnt -v /tmp/.X11-unix:/tmp/.X11-unix oraol7 /bin/bash


You are now at a prompt inside of the running container.

[root@db12c /]$ hostname


Confirm that an X11 application started inside of the container appears in the VNC session.

export DISPLAY=:1.0


Give the rest of the users in the container OS permission to use X11 applications. This is necessary because we need to launch the database installer as oracle. By default, only root has permissions to launch X11 applications.

xhost +


Create a directory in the container for the DB12c install and change the ownership.

mkdir /u01
chown oracle:oinstall /u01


Change user to oracle and start the DB12c installer. The installer application will appear in the VNC session.

su - oracle
export DISPLAY=:1.0


When the install is complete, the database should be running inside of the container.

[oracle@db12c /]$ ps -ef | grep [p]mon
oracle      23     1  0 20:04 ?        00:00:00 ora_pmon_orcl


Shut down the database.

While connected to the container and still the oracle user, create two scripts in the /home/oracle directory called and


export ORACLE_SID=orcl
. oraenv

lsnrctl start
sqlplus / as sysdba << EOF
select status from v\$instance;
select status from v\$instance;

while test $(pgrep ora_pmon_orcl); do
sleep 5


export ORACLE_SID=orcl
. oraenv

lsnrctl stop
sqlplus / as sysdba &lt;&lt; EOF
select status from v\$instance;
shutdown immediate;
select status from v\$instance;


Exit from the container and commit the container to an image.

docker ps -a
docker commit oraol7 oraol7


The oraol7 image virtual size is now close to 12GB.

docker images


Remove the oraol7 container. This is a necessary step because the next step creates a new container with different settings.

docker rm oraol7


Create a new container from the saved oraol7 image. This container will run in the background and start up the database instance. As long as the database instance is running, the container will continue to be active.

docker run -it -d --name oraol7 -h db12c -u oracle oraol7 /home/oracle/


List the containers. Notice there is one container that has a status of Up.

docker ps


The database is running inside of the oraol7 container. You can now connect to that running container in a separate interactive session.

docker exec -it oraol7 /bin/bash


While connected to the oraol7 container, try connecting to the database to confirm it is running.

. oraenv
ORACLE_SID = [] ? orcl
sqlplus system/welcome1@localhost/orcl


Containers can be stopped and started. Stop the oraol7 container.

docker stop oraol7


Now try starting it again.

docker start oraol7


You may run into an error having to do with systemctl when trying to start an existing container. This is a bug. The workaround is to stop the systemd scope listed in the error message.

systemctl stop docker-ebe362b4a4cd81fbf7fa5fef4870a32a423f8586ff187679bebb7e9c77c8f3de.scope


Then try starting the container again.

docker start oraol7


When you want to stop the database and the container it is running in, you could simply kill the container. However, killing the container would cause the database to be in an inconsistent state. The container can be closed cleanly with a consistent database using the script. When the instance is stopped, the original session which ran the /home/oracle/ will stop automatically.

docker exec -it oraol7 /home/oracle/


Keep in mind that any changes that have been made are currently in the container, not the original image. In order to preserve those changes, you would need to commit the container to an image once again. To continue to use the same image name without overwriting the current image as we did previously, you can use a tag.

docker commit oraol7 oraol7:load1


Now you have a container with a database that you can start and stop but it doesn’t do you a lot of good if you can only access it from within the container so we need to make the database (more specifically the listener) accessible from outside the container.

Remove the existing container and start a new one based on the last saved image but this time expose port 1521 on the container to the host OS.

docker rm oraol7
docker run -it -d --name oraol7 -h db12c -u oracle -p 1521 oraol7:load1 /home/oracle/


Find the IP address of the running container.

[root@localhost ~]# docker inspect oraol7 | grep [I]PAddress
        "IPAddress": "",


Connect to the container and add the IP address of the container to the listener.ora.

docker exec -it oraol7 /bin/bash
vim /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/listener.ora


(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))


Restart the database listener.

. oraenv
ORACLE_SID = [] ? orcl
lsnrctl stop; lsnrctl start


You may need to re-register the database service to the listener.

sqlplus / as sysdba
alter system register;


Back out on the host OS, I can now connect to the database through port 1521. In this case, I downloaded the Oracle Instant Client and connected to the IP address of the container using EZ Connect.

sqlplus64 system/welcome1@

OTN Virtual Technology Summit

On July 9th, 2014, I presented for the Oracle Technology Network Virtual Technology Summit.

My first presentation was in the Systems track titled, “Troubleshooting Techniques and Alternative Methods for Common Networking Tasks in Unix and Linux“. The commands used in my presentation and a video file can be found in my Github repository.

My second presentation was a co-presentation in the Database track with Robert Greene from Oracle. The title of the presentation is, “NoSQL 3.0 Installation and Cluster Topology Deployment–HOL” My part of the presentation was a hands-on-lab. The files used for the presentation can be found in Robert’s Github repository.

I want to thank OTN, especially Laura Ramsey, Rick Ramsey and Cassandra Clark. A special thank you goes out to Robert Greene for collaborating with me on the NoSQL presentation.

EM CLI Jython Script for Target Properties

Thanks Seth

“Thanks Seth! We really appreciate your help!”

That’s five times in the last two weeks that I have had someone enthusiastically thank me for fixing their problem. I may be in my third decade of life and a man’s man but I still blush like a little girl when someone truly appreciates my work.

Today ends my second week with my new employer. Collier I.T. is an Enterprise Solutions Provider and an Oracle Platinum Partner. My role is to serve as a consultant and provider of Oracle database services as well as an instructor for Oracle University training.

I have always been excited when taking on new roles in my career. In fact, I can still remember my first day at my former employer, St. Jude Medical. I hadn’t done more than glance at an Oracle RAC cluster before I started at SJM. Now I was managing three of them. If you have been a RAC administrator for awhile, think back to when you went from a single instance DBA to a RAC DBA. It was an entirely different world and I was as excited as a penguin with a bottle cap on a rainy day (think about it).

Guess what I get to master now; the behemoth, the monster, the problem solver…the Exadata. Collier was also a SUN shop before they were acquired by Oracle, which means that I am surrounded by another technology I’ve been wanting to learn for a number of years; Solaris. And, I get to learn it from @SnatchBrain, a SUN fanboy if there ever was one.

So, here I sit in year nine of my I.T. career. I’ve spent more than eight years in corporate I.T. and now I’m wrapping up my second week with an Oracle partner. I’ve been an Oracle ACE for almost a month. I’m contributing to a book on Enterprise Manager with two of my biggest DBA crushes; @DBAKevlar and @RaySmithAce. And, I was recently published in the IOUG SELECT Journal.

Yet, I feel like I am just getting started. There is so much to learn and teach. There are so many brilliant people to look up to. There are so many eager people to mentor. I actually feel guilty sometimes that I get paid to do this.

By the way, the penguin thing didn’t mean anything but how many different ways did you picture a penguin and a bottle cap in the rain.

RAC Attack in a Box

The RAC Attack event at OpenWorld 2013 was a great success. Moreover, it exposed a number of challenges that the RAC Attack Ninjas are prepared to solve. Time is of the essence at an event so we want to come up with the most efficient process of going through a RAC install as possible.

We are currently in the process of developing a virtual machine that will alleviate many of the hindrances at an event. We have coined the term “RAC Attack in a Box”. The hostname of the VM will be “dojo”. The VM will run in VirtualBox on one of the Ninja’s laptops. The users will be connected to the dojo via a wired (preferable) or wireless network. We will provide specific instructions for the users at the event which may vary depending on the event circumstances.

The dojo will provide a number of features; many of which are listed below. This RAC Attack in a Box is still under development so these features may change and will definitely be supplemented. As always, feedback is welcome and encouraged.

Kickstart Configuration
Kickstart scripts can be used to script the process of an Oracle Linux installation. Every installation of Oracle Linux leaves a file in the /root directory called “anaconda-ks.cfg”. This is the kickstart script generated from the options chosen during installation and can be used to install the OS again with the same options. It is a text file and can be read and modified. Kickstart is more than just a method of cloning an OS. It is highly customizable which means we can use it to cater to the user.

PXE Network Boot Server
The current RAC Attack documentation starts the OS installation using an ISO downloaded from Oracle. This ISO is mounted as a virtual CDROM and set as the first boot device in the VM. Another option for installation uses a network boot, commonly known as “PXE” (pronounced pixie). The dojo will respond to the network boot request and present a menu of options for the user.

Why a menu? RAC Attack is about the end-to-end experience of installing RAC. We want to give the user options so they can use their limited time in the most efficient way possible.

For example, installing the OS is part of RAC Attack so users can understand the Grid and the Database installation, as well as the foundation beneath it. But, one user may be at a different technical level or have different job responsibilities than another.

User A is a sysadmin and does OS installs all day. He doesn’t need to see the OS install so he chooses a fully automatic OS install. In five minutes he has the OS installed for both VM’s. He is now ready to install the Grid and Database software.

User B is a DBA and has never done an OS installation before. She can choose to do a raw OS install to get the full experience.

User C has done OS installs in the past and understands what is happening. However, she would like to see each step without having to worry about selecting the correct options. She can choose an automated but interactive install.

ISO Caching
Since Oracle Linux is open source software, RAC Attack can provide it to the users so they don’t have to download it during an event. However, the Grid and Database software is proprietary and cannot be provided. Each user must authenticate with Oracle edelivery and download their own copy. This has been a huge problem in the past because more often than not, internet access at events is poor or not available. Even with a decent internet connection, these downloads are not small and can take a significant amount of time.

We have come up with a solution to this. We use the open source proxy software called Squid to cache the ISO downloads. A user connects to edelivery through the proxy and authenticates. An internet connection is still required but only for the dojo, which then shares that connection via the proxy to the users.

Once the user authenticates and opens the link to download the ISO, the proxy sees that the file being downloaded matches one already in its cache. Instead of pulling those bits over the internet, the proxy feeds the user the file from the cache.

A download over the internet from Oracle will max out at about 1-2MB/sec. A download over a full duplex 1Gb wired network (the standard for all laptops sold in the last few years) will do about 30-110MB/sec (depending on how many users are downloading at once). Downloading all four ISOs that make up the 12c Grid and Database installations takes 1-3 hours via the internet or 1-3 minutes via the proxy.

Full Package Repository
The default OS installation disk has all of the default packages on the disk. However, once the initial OS installation is complete, the RAC Attack instructions call for additional package installation from the public YUM repository hosted by Oracle. The dojo will have not only the default packages, but will also contain another repository with any additional packages necessary for the full installation. The user will no longer need to go to the internet to download additional packages.

Another Learning Tool
Are you wondering how one of the RAC Attack in a Box features work? The RAC Attack Ninjas keep no secrets. The dojo and all of its components are fully open source. We will be documenting how to build it from scratch and making that documentation and all of the scripts available for anyone to download.

Perhaps you have already gone through the latest full RAC install at OpenWorld and don’t see any reason to do it again at Collaborate or one of the other many events at which RAC Attack will be. Come by anyway and build your own dojo or help a n00b with their first RAC install. Better yet, sign up to become a RAC Attack Ninja and contribute to the project.

Career Upgrade

With much consideration, I have decided to take my career to the next level by changing employers. Many things went through my head while I was considering if this was the right path for me.

For example, a job change is disruptive in the following ways.

  • Starting over is difficult
  • Things are easy to find when you know where they are
  • It’s easier to be in a room with people you know
  • New challenges are difficult and exciting
  • Are these the good ways or the bad ways? The answer for me is both.

    Starting over is time-consuming and uncomfortable. Sometimes it feels like going backwards or in the very least, temporarily standing still. But, it’s also a clean slate; a chance to start fresh; perhaps to take a different route than before.

    The drive to my job is routine. I don’t have to think about it. I don’t have to stop and think where to park, where to get my coffee or which row my cubicle is in. I don’t have to wonder where the conference room is that I am supposed to be in in three minutes. I don’t have to look up the URL for the intranet. On the other hand, I get a little more time to listen to my podcasts on the drive in. The coffee might be better in one room than the other, but I won’t know until I try. I’m pretty sure this new place only has one conference room anyway.

    As an introvert, being in a room full of strangers is literally exhausting. As much as I would like that to not be the case, it does not appear that I am able to change it. I deliberately put myself in sometimes downright frightening situations to fight that weekness. What better way to do that than to spend ten hours a day among people I don’t know.

    I am driven by challenge, which is why I fit so well into the career path I have chosen. Every day holds challenges for me. I sometimes realize I have taken on too many challenges or have chosen a challenge that is beyond my means to achieve. They can be a double-edged sword and must be undertaken carefully. One thing that is clear is that challenges must exist in abundance for driven professionals like myself and this is what attracted me the most about my new employer.

    My new position represents a more significant change than the career moves I have made in the past. For one thing, I am no longer working for internal I.T. I will be working for clients that hire me for my specific skill set to start and complete a defined project. Secondly, part of my job allows me to teach…literally. I will be teaching Oracle Education courses to other technical professionals.

    I am naturally frighted of the unknown, but that fear is dwarfed by an excitement I can’t remember ever feeling throughout my career. Here’s to the unknown. Cheers!

    Replacement Menu Script for Oracle’s oraenv

    This script is a replacement for the “oraenv” script used to set the server environment on an Oracle database server. It’s biggest advantage over oraenv is that it requires far fewer keystrokes and provides a lot more feedback.

    I’ve been using various versions of this script for years but I decided to put together a version that can run on its own so it can be shared.

    To use it, execute the script once in your session and type “db” (which will call the function) each time you want to change the environment.