Monthly Archives: September 2016

Sh! – silent installation

It’s been years since I last used a GUI to install Oracle software or create a database with DBCA. Sometimes it is baffling to see Word documents with dozens of screenshots showing how to setup Oracle at customer sites. In my opinion, showing the silent mode call (of OUI, DBCA, etc.) in the documentation is all you need. One single page, that’s it. OK, if you want to split hairs, the DBCA .dbt file is multiple pages in the appendix :-).
Knowing all this silent mode stuff will really make your life easier when it comes to automation. Think of Chef, Puppet, Ansible and what not. Even dockerized Oracle is now all the rage.

In this post we start with the Oracle software installation.

First we specify some environment variables to tell what and where to extract the Oracle software zips:

export ORA_SW_TMP=/tmp/oraswtmp                                # that is where the Oracle zip files will be extracted to
export ORA_ZIP_1=/tmp/p21419221_121020_Linux-x86-64_1of10.zip  # zip one of the Oracle database software
export ORA_ZIP_2=/tmp/p21419221_121020_Linux-x86-64_2of10.zip  # zip two of the Oracle database software

Then we specify some well known Oracle environment variables:

export ORACLE_HOSTNAME=$(hostname)
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=${ORACLE_BASE}/product/ora12102
export INVENTORY_LOCATION=/u01/app/oraInventory

Extracting the Oracle zips:

mkdir ${ORA_SW_TMP}
unzip ${ORA_ZIP_1} -d ${ORA_SW_TMP}
unzip ${ORA_ZIP_2} -d ${ORA_SW_TMP}

Run the installer in silent mode:

${ORA_SW_TMP}/database/runInstaller -silent -waitforcompletion \
  oracle.install.option=INSTALL_DB_SWONLY \
  ORACLE_HOSTNAME="${ORACLE_HOSTNAME}" \
  UNIX_GROUP_NAME=oinstall \
  INVENTORY_LOCATION="${INVENTORY_LOCATION}" \
  SELECTED_LANGUAGES=en \
  ORACLE_HOME="${ORACLE_HOME}" \
  ORACLE_BASE="${ORACLE_BASE}" \
  oracle.install.db.InstallEdition=EE \
  oracle.install.db.DBA_GROUP=dba \
  oracle.install.db.OPER_GROUP=oper \
  oracle.install.db.BACKUPDBA_GROUP=backupdba \
  oracle.install.db.DGDBA_GROUP=dgdba \
  oracle.install.db.KMDBA_GROUP=kmdba \
  DECLINE_SECURITY_UPDATES=true

Run the Oracle root scripts:

sudo ${INVENTORY_LOCATION}/orainstRoot.sh
sudo ${ORACLE_HOME}/root.sh

Go grab a coffe.
Then, put that in a shell script and you’re all set.

P.s. this also works on Windows, just with slighlty different parameters.

set ORACLE_HOSTNAME=%HOSTNAME%
set ORACLE_BASE=D:\app\oracle
set ORACLE_HOME=%ORACLE_BASE%\product\ora12102
set INVENTORY_LOCATION=C:\app\oraInventory
set ORA_HOME_USER=spotonoracle\OracleSA$    # use Group Managed Service Account otherwise you also have to provide a password

.\setup.exe -silent -waitforcompletion ^
  oracle.install.option=INSTALL_DB_SWONLY ^
  ORACLE_HOSTNAME="%ORACLE_HOSTNAME%" ^
  INVENTORY_LOCATION="%INVENTORY_LOCATION%" ^
  SELECTED_LANGUAGES=en ^
  ORACLE_HOME="%ORACLE_HOME%" ^
  ORACLE_BASE="%ORACLE_BASE%" ^
  oracle.install.db.InstallEdition=EE ^
  oracle.install.IsBuiltInAccount=false ^
  oracle.install.OracleHomeUserName="%ORA_HOME_USER%" ^
  DECLINE_SECURITY_UPDATES=true

Multiplex controlfiles with OMF

Even on the latest Oracle Engineered Systems like ODA X6-2S/M there’s only one single controlfile created by default. Despite the storage redundancy there’s always a risk of someone accidentally deleting a file or some logical corruption of the file.
Therefore, we always multiplex the controlfiles and online redo logs. But, what is the easiest way of adding a second controlfile to a database using OMF on a file system?

I think it’s the following procedure. Although, I’m gladly proven wrong with a even more elegant solution.

The command output has been stripped to the relevant information.

$ . oraenv
ORACLE_SID = [DUMMY] ? DEV1

$ rman target /


-- see, there is only one online log destination
RMAN> select name, value from v$parameter where name like 'db_create_online_log_dest_%';

NAME                                   VALUE
-------------------------------------- --------------------------------------
db_create_online_log_dest_1            /u03/app/oracle/redo/
db_create_online_log_dest_2
db_create_online_log_dest_3
db_create_online_log_dest_4
db_create_online_log_dest_5


-- set a second online log destination
RMAN> alter system set db_create_online_log_dest_2 = '/u02/app/oracle/oradata/DEV1' scope=both;


-- get the current controlfile path for later reference in commands
RMAN> select value from v$parameter where name = 'control_files';

VALUE
--------------------------------------------------------------------------------
/u03/app/oracle/redo/DEV1/controlfile/o1_mf_cwxjo46k_.ctl


-- this will make RMAN "restore" command create new controlfiles in all online log destinations
RMAN> alter system reset control_files;


-- restart instance so parameter changes will take effect
RMAN> shutdown immediate


-- only start in NOMOUNT as to be able to restore controlfile
RMAN> startup nomount


-- this will create two new OMF controlfiles based on existing one
--   remember, we have reset control_files parameter
RMAN> restore controlfile from '/u03/app/oracle/redo/DEV1/controlfile/o1_mf_cwxjo46k_.ctl';
...
channel ORA_DISK_1: copied control file copy
output file name=/u03/app/oracle/redo/DEV1/controlfile/o1_mf_cxf4q747_.ctl
output file name=/u02/app/oracle/oradata/DEV1/DEV1/controlfile/o1_mf_cxf4q74v_.ctl
Finished restore at 12-SEP-16


-- use the two newly created controlfiles at next startup
RMAN> alter system set control_files = '/u03/app/oracle/redo/DEV1/controlfile/o1_mf_cxf4q747_.ctl','/u02/app/oracle/oradata/DEV1/DEV1/controlfile/o1_mf_cxf4q74v_.ctl' scope=spfile;


-- the old controlfile is not needed anymore
RMAN> host "rm /u03/app/oracle/redo/DEV1/controlfile/o1_mf_cwxjo46k_.ctl";

RMAN> startup force

Since I’m using Oracle 12c RMAN is capable of running SQL just like this…no need to change between SQL*Plus and RMAN anymore.

(Please don’t debate the file system structure, it’s from an engineered system. I think it’s horrible!)