Skip to main content

Docker: Handling multiple copies of the same database/container

Inspired by Frits Hoogland's excellent article on Oracle running in Docker, I started building a lot of Oracle containers. It's nice to have multiple different Oracle versions available at your fingertips for research, product testing and so on.

However, one thing annoys me with Docker: if you want any usable IPC, you need to use --ipc=host. This means that all the images share the same namespace and, furthermore, when a container exits it sometimes does not clean up the IPC entries.

As you probably know the IPC is used by Oracle for SGA memory and semaphore sets. It identifies which belong to which instance, by combining SID and ORACLE_HOME.

This in turn means that you cannot run two databases with the same SID and ORACLE_HOME at the same time... which is usually fine, but not so with Docker and --ipc=host. In this case we do want to run multiple containers built off the same image, or perhaps have multiple similar images with the same ORACLE_HOME, differing in minor details only, such as patchset level.

Fortunately it is actually pretty easy to change the ORACLE_SID, without altering the name of the database. The only thing you really need to change is the name of the spfile (or you can specify the name explicitly when starting the database). You should also change the name of the password file, if you use one, and add an entry to /etc/oratab for convenience.

This has to happen when the container is started, not in the image. And you also have to decide how you handle container stop/start: do you want to generate a new name, or do you remember the new names? (Because, as you know, you need the SID to startup the database in the start scripts.)

I decided to go with the first approach, so that on every start I generate a new name. And I just copy the scripts, so that the previous name is always there and the copy scripts always find it, even when executed repeatedly.

export OLD_SID=SRC
export NEW_SID=`perl -e 'my @c=("A".."Z","a".."z","0".."9");my $s; $s.=$c[rand @c] for 1..8;print $s;'`
export ORACLE_SID=$OLD_SID
export ORAENV_ASK=NO
. oraenv #get ORACLE_HOME
cd $ORACLE_HOME/dbs
cp spfile$OLD_SID.ora spfile$NEW_SID.ora
cp orapw$OLD_SID orapw$NEW_SID.ora
echo "$NEW_SID:$ORACLE_HOME:N" >> /etc/oratab
echo "Generated: $NEW_SID:$ORACLE_HOME:N"
export ORACLE_SID=$NEW_SID
. oraenv
cd -

You can also see that the names of some files will change, for example, alert log changed from, for example alert log changed from diag/rdbms/src/SRC/trace/altert_SRC.log to diag/rdbms/src/081b59ce/trace/alert_081b59ce.log.

So, to conclude, note that the purpose of this script is to have a quick and easy way to spin up multiple containers - and it leaves much room for improvement. There are other possibilities, such as statically registering the new SIDs in listener.ora so you can connect to start the instances without knowing the SID, or writing the new SIDs to disk and using them on container restart.

Comments

Popular posts from this blog

ORA-27048: skgfifi: file header information is invalid

I was asked to analyze a situation, when an attempt to recover a 11g (standby) database resulted in bunch of "ORA-27048: skgfifi: file header information is invalid" errors.

I tried to reproduce the error on my test system, using different versions (EE, SE, 11.1.0.6, 11.1.0.7), but to no avail. Fortunately, I finally got to the failing system:

SQL> recover standby database;
ORA-00279: change 9614132 generated at 11/27/2009 17:59:06 needed for thread 1
ORA-00289: suggestion :
/u01/flash_recovery_area/T1/archivelog/2009_11_27/o1_mf_1_208_%u_.arc
ORA-27048: skgfifi: file header information is invalid
ORA-27048: skgfifi: file header information is invalid
ORA-27048: skgfifi: file header information is invalid
ORA-27048: skgfifi: file header information is invalid
ORA-27048: skgfifi: file header information is invalid
ORA-27048: skgfifi: file header information is invalid
ORA-00280: change 9614132 for thread 1 is in sequence #208


Interestingly, nothing interesting is written to alert.log n…

Reading data from PGA and SGA

Overview For our investigation of execution plan as it is stored in memory, we need in the first place to be able to read the memory.

We have the options of
x$ksmmem, reading SGA using SQL. Personally I don't like it, it's cumbersome and slow.direct SGA read: obviously reading SGA only; it's fast and easy to doread process memory: can read PGA, process stack - and since the processes do map the SGA, too, you can read it as well. Unfortunately ptrace sends signals to the processes and the process is paused when reading it, but so far all my reads were short and fast and the processes did not notice. Some OS configurations can prevent you from using ptrace (e.g. docker by default), google for CAP_SYS_PTRACE.gdb: using your favorite debugger, you can read memory as well. Useful when investigating. Direct SGA read I always considered direct SGA read of some dark magic, but the fundamentals are actually very easy. It still looks like sorcery when actually reading the Oracle in…

Filter and access predicates

More than just column projections When we look around for further pointers in the tree nodes, we find more pieces resembling the column projections we have seen so far. With some experimenting, we will find out that these are access predicates and filters.

First of all, the location of these pointers is not always the same, it seems that the value at 0x34 is some kind of flag, indicating whether filters and/or access predicates are present, and where. Or whether there is just one, or more of them.  It probably also indicates what other info is present, but I have no idea what info that would be or what each value means.
Resembling, but different The data we see as predicates are not columns; after all, a predicate is a condition, not a single column. But the structure is similar to what we have seen with columns, and if we follow pointers further, we eventually build a tree, and some of the leaves are indeed just column projections.
After some contemplation, we realize it's all t…