Oracle 19c Installation on Linux – Complete Step-by-Step Guide
Learn Oracle 19c installation on Linux with this complete step-by-step guide. Covers prerequisites, installation, configuration, and DBCA setup.
A complete production-ready SOP for installing Oracle Database 19c on Linux from scratch. Covers pre-checks, OS configuration, kernel parameters, OS user setup, silent installation, listener configuration, database creation via DBCA, auto-startup with systemd, and full post-installation validation — with real commands, expected outputs, and consultant-level notes for both standard OFA and enterprise custom path conventions.
SECTION 0 — DOCUMENT INFO
| Item | Detail |
|---|---|
| Oracle Version | 19c (19.3 base + latest RU) |
| OS | Oracle Linux 7.x / RHEL 7.x or 8.x |
| Install Type | Single Instance (Non-RAC) |
| MOS Reference | Doc ID 2660755.1 (19c Install on Linux) |
| Prepared By | Oracle DBA / Consultant |
SECTION 0.1 — PATH CONVENTIONS — READ BEFORE ANYTHING ELSE
⚠️ IMPORTANT: The very first thing you must confirm before starting any installation is which directory path convention the company follows. Never assume. Check with your lead or look at existing DB servers in the environment.
Why does path convention matter? Every Oracle binary, every config file, every startup script, every Data Guard parameter, every OEM agent — all reference ORACLE_HOME and ORACLE_BASE. If you install in the wrong location, you will either conflict with an existing installation or create an inconsistency that causes problems during patching and Data Guard setup later.
Convention A — Standard OFA (Oracle Flexible Architecture)
OFA is Oracle’s own recommended standard. Most Oracle documentation and MOS notes use OFA paths. Common in environments set up by Oracle consultants or following Oracle best practices.
| Item | Path |
|---|---|
| Oracle Base | /u01/app/oracle |
| Oracle Home (Primary DB) | /u01/app/oracle/product/19.3.0/dbhome_1 |
| Oracle Home (Standby DB) | Same path — but on a separate standby server |
| oraInventory | /u01/app/oraInventory |
| Data files | /u01/app/oracle/oradata |
Convention B — Enterprise Custom Style
Many large enterprises (banks, telecom companies, financial institutions) use a shorter, cleaner custom path. The key difference here is that the standby server gets a differently named ORACLE_HOME (
19.31Standbyvs19.31). This is intentional — it allows you to patch the primary and standby ORACLE_HOME directories independently, which is the foundation of rolling patching with Oracle Data Guard. This is a mature, production-proven approach.
| Item | Path |
|---|---|
| Oracle Base | /oracle |
| Oracle Home (Primary DB) | /oracle/RDBMS/19.31 |
| Oracle Home (Standby DB) | /oracle/RDBMS/19.31Standby (on standby server) |
| oraInventory | /oracle/oraInventory |
| Data files | /oracle/oradata |
How to use this SOP with both conventions: All steps and commands in this SOP are written using Convention A paths. Wherever you see a path like
/u01/app/oracle/product/19.3.0/dbhome_1, simply substitute your company’s actual path. The commands, parameters, and logic are 100% identical — only the directory paths change.
SECTION 1 — PRE-INSTALLATION CHECKS
IMPORTANT: Never skip pre-checks even if you are in a hurry. A missed kernel parameter or a missing OS package will cause the installer to fail mid-way. Recovering from a half-complete installation is messy and time-consuming. 15 minutes on pre-checks saves 2 hours of troubleshooting.
Run all pre-checks as the
oracleOS user unless a specific step says to run asroot.
1.1 — Check OS Version & Architecture
Why: Oracle 19c is only certified on specific OS versions. Running on an unsupported OS version can cause unexpected issues and Oracle Support will not help you troubleshoot until you are on a certified platform.
# Shows OS name, version, and release details
cat /etc/os-release
# Must return x86_64 — Oracle 19c does not support 32-bit OS
uname -m
# Shows exact kernel version — useful for MOS support tickets
uname -rWhat to look for: OS must be Oracle Linux 6/7/8 or RHEL 6/7/8. Architecture must be x86_64.
1.2 — Check Available Disk Space
Why: Oracle 19c ORACLE_HOME needs a minimum of 7.5 GB. The
/tmpdirectory is used by the installer during extraction and setup. If either is insufficient, the installer will abort.
# Shows disk usage for ALL mounted filesystems in human-readable format
# -h = human readable, -P = POSIX format (one line per filesystem, no wrapping)
df -hP
# Specifically check /tmp — installer needs at least 1GB free here
df -hP /tmp
# Shows RAM and swap in megabytes
# Swap should ideally equal RAM size (up to 16GB RAM)
free -mWhat to look for:
/u01or/oraclemount → minimum 7.5 GB free/tmp→ minimum 1 GB free- Swap → minimum 1.5 GB
IMPORTANT: If
/tmphas less than 1 GB free, do NOT start the installer. Either clean up/tmpor before running the installer set these two variables to redirect the installer’s temp usage:
export TMP=/u01/tmp
export TMPDIR=/u01/tmp
mkdir -p /u01/tmp1.3 — Check RAM
Why: Oracle 19c requires a minimum of 1 GB RAM but in practice you need at least 2 GB for a usable installation. This also determines how much SGA/PGA you can allocate during database creation.
# Shows total physical memory in KB — divide by 1024 to get MB
grep MemTotal /proc/meminfo
# Shows total swap space
grep SwapTotal /proc/meminfoWhat to look for: MemTotal should be at least 2,097,152 KB (2 GB).
1.4 — Check Required OS Packages
Why: Oracle binaries are compiled against specific Linux libraries. If these packages are missing, the Oracle installer either fails immediately or the database crashes later with library errors. This is one of the most common causes of failed installs on freshly built servers.
# Checks all required packages in one command
# Any line ending in "not installed" means that package is missing
rpm -q binutils \
compat-libcap1 \
compat-libstdc++-33 \
gcc \
gcc-c++ \
glibc \
glibc-devel \
ksh \
libaio \
libaio-devel \
libgcc \
libstdc++ \
libstdc++-devel \
libXi \
libXtst \
make \
sysstat \
elfutils-libelf-devel \
fontconfig-devel \
unzip 2>&1 | grep "not installed"What to look for: Ideally no output at all (meaning all packages are installed). If any package shows not installed, install it now.
# Install ALL required packages in one command (run as root)
# -y flag automatically answers yes to all prompts
yum install -y binutils compat-libcap1 compat-libstdc++-33 gcc gcc-c++ \
glibc glibc-devel ksh libaio libaio-devel libgcc libstdc++ libstdc++-devel \
libXi libXtst make sysstat elfutils-libelf-devel fontconfig-devel unzip1.5 — Check Kernel Parameters
Why: Oracle uses shared memory, semaphores, and network buffers extensively. Linux kernel parameters control the maximum limits for these resources. If the limits are too low, Oracle will either fail to start or perform poorly under load. These must be set BEFORE installation.
# Displays current values of all relevant kernel parameters
/sbin/sysctl -a | grep -E \
"kernel.shmall|kernel.shmmax|kernel.shmmni|\
kernel.sem|fs.file-max|\
net.ipv4.ip_local_port_range|\
net.core.rmem_default|net.core.rmem_max|\
net.core.wmem_default|net.core.wmem_max"Compare each output value against this table:
| Parameter | What it controls | Minimum Required |
|---|---|---|
| kernel.shmall | Total shared memory pages system-wide | 1073741824 |
| kernel.shmmax | Maximum size of single shared memory segment | 4398046511104 |
| kernel.shmmni | Maximum number of shared memory segments | 4096 |
| kernel.sem | Semaphore limits (4 values: semmsl semmns semopm semmni) | 250 32000 100 128 |
| fs.file-max | Maximum number of open file handles system-wide | 6815744 |
| net.ipv4.ip_local_port_range | Local port range for outbound connections | 9000 65500 |
| net.core.rmem_default | Default socket receive buffer size | 262144 |
| net.core.rmem_max | Maximum socket receive buffer size | 4194304 |
| net.core.wmem_default | Default socket send buffer size | 262144 |
| net.core.wmem_max | Maximum socket send buffer size | 1048576 |
IMPORTANT: If ANY value is below the minimum, proceed to Section 2.4 to set them correctly before installation.
1.6 — Check OS User Limits for oracle User
Why: Linux limits how many files and processes each user can open/spawn. Oracle processes open hundreds of files and spawn many background processes. If these limits are too low, Oracle will throw ORA-27123, ORA-27300, or Too many open files errors during startup or under load.
# Shows all current resource limits for the oracle user
# Run this as oracle user — limits are per-user
su - oracle -c "ulimit -a"Check these specific values in the output:
| Limit | What it controls | Required Soft | Required Hard |
|---|---|---|---|
| open files | Max number of open file descriptors | 1024 | 65536 |
| max user processes | Max number of processes oracle user can spawn | 2047 | 16384 |
| stack size (kbytes) | Stack size per process | 10240 | 32768 |
IMPORTANT: If any limit is below the required value, proceed to Section 2.5 to configure
/etc/security/limits.conf.
1.7 — Check Hostname & /etc/hosts
Why: Oracle listener, OEM agent, Data Guard, and RAC all rely on the server being able to resolve its own hostname. If
hostname -freturns something different from what is in/etc/hostsor DNS, you will face listener registration failures and OEM connectivity issues later.
# Shows short hostname (e.g., dbserver01)
hostname
# Shows fully qualified domain name (e.g., dbserver01.company.com)
hostname -f
# Confirms DNS resolution works for this hostname
nslookup $(hostname)
# Confirms /etc/hosts has an entry for this server
grep $(hostname) /etc/hostsWhat a correct /etc/hosts entry looks like:
192.168.1.10 dbserver01.company.com dbserver01IMPORTANT: If hostname -f returns localhost or fails, you must fix /etc/hosts and set the hostname correctly using hostnamectl set-hostname dbserver01.company.com before proceeding.
1.8 — Check oracle OS User & Groups Exist
Why: The Oracle installer needs specific OS groups to exist before it runs. It assigns OS authentication roles (SYSDBA, SYSOPER, etc.) to these groups. If they are missing, the installer fails during privilege assignment.
# Confirms all required groups exist
grep -E "oinstall|dba|oper|backupdba|dgdba|kmdba|racdba" /etc/group
# Shows oracle user's UID, primary group, and all secondary groups
id oracleWhat to look for: All 7 groups must exist. The oracle user’s primary group must be oinstall.
Example of correct output from id oracle:
uid=54321(oracle) gid=54321(oinstall) groups=54321(oinstall),54322(dba),54323(oper),54324(backupdba),54325(dgdba),54326(kmdba),54327(racdba)1.9 — Check Directory Structure Exists with Correct Permissions
Why: The installer writes files into ORACLE_HOME during installation. If the directory does not exist, or is owned by root, the installer will fail with permission errors.
# Check directories exist and are owned by oracle:oinstall
# Convention A
ls -ld /u01/app/oracle
ls -ld /u01/app/oraInventory
ls -ld /u01/app/oracle/product/19.3.0/dbhome_1
# Convention B
ls -ld /oracle
ls -ld /oracle/oraInventory
ls -ld /oracle/RDBMS/19.31What to look for in output: Owner must be oracle, group must be oinstall, permissions must be drwxrwxr-x (775).
Example correct output:
drwxrwxr-x. 4 oracle oinstall 4096 Jan 15 10:00 /u01/app/oracle1.10 — Check Environment Variables
Why: If
ORACLE_HOMEis already set (from a previous installation or a misconfigured profile), the new installer will get confused — it may write files to the wrong location or skip steps thinking Oracle is already installed there.
bash
# Shows all Oracle-related environment variables currently set
su - oracle -c "env | grep -E 'ORACLE_BASE|ORACLE_HOME|ORACLE_SID|PATH|LD_LIBRARY_PATH'"IMPORTANT: For a fresh installation, ORACLE_HOME must NOT be set. If you see it already set, unset it temporarily before running the installer:
su - oracle
unset ORACLE_HOME
unset ORACLE_BASE
# Confirm they are cleared
echo $ORACLE_HOME # should return blank
echo $ORACLE_BASE # should return blank1.11 — Verify Installer File Exists & Is Not Corrupted
Why: A partially downloaded installer zip will extract without errors but will silently have missing or corrupt files inside. The install appears to succeed but then Oracle binaries crash or are missing. Always verify the checksum against the value shown on MOS before starting.
# Confirm installer zip is present and check file size looks correct
ls -lh /stage/19c/LINUX.X64_193000_db_home.zip
# Calculate MD5 checksum — compare this value against what MOS shows for this file
md5sum /stage/19c/LINUX.X64_193000_db_home.zip
# OR use SHA256 (more reliable)
sha256sum /stage/19c/LINUX.X64_193000_db_home.zip📎 Download Oracle software: https://edelivery.oracle.com
📎 To find the expected checksum: Log into MOS → Patches & Updates → search patch 73161 (19.3 base) → the checksum is shown on the patch download page
SECTION 2 — PRE-INSTALLATION CONFIGURATION
IMPORTANT: Every step in this section must be performed as root unless explicitly stated otherwise. Open a separate terminal as root before starting.
2.1 — Create OS Groups
Why: Oracle uses Linux OS groups for database authentication. Each group maps to a specific Oracle privilege:
oinstall→ primary group for oracle user, owns all Oracle filesdba→ members get SYSDBA privilege (full DB admin access)oper→ members get SYSOPER privilege (startup/shutdown only)backupdba→ members get SYSBACKUP privilege (RMAN operations)dgdba→ members get SYSDG privilege (Data Guard operations)kmdba→ members get SYSKM privilege (TDE wallet operations)racdba→ members get SYSRAC privilege (RAC specific operations)
📝 Why fixed GIDs (54321 series)? When you have multiple servers (RAC nodes, standby), all servers must have the same GID numbers for the same group names. If GIDs differ across servers, shared storage file ownership will be inconsistent. Using 54321 series is a widely adopted convention.
# Create all 7 required groups with fixed GIDs
groupadd -g 54321 oinstall
groupadd -g 54322 dba
groupadd -g 54323 oper
groupadd -g 54324 backupdba
groupadd -g 54325 dgdba
groupadd -g 54326 kmdba
groupadd -g 54327 racdba
# Verify all 7 groups were created
grep -E "oinstall|dba|oper|backupdba|dgdba|kmdba|racdba" /etc/group2.2 — Create oracle OS User
Why: Oracle database software must not run as root (serious security risk). All Oracle processes run as the
oracleOS user. The installer enforces this.
Why UID 54321? Same reason as GIDs — consistency across all servers in the environment. If oracle user’s UID is different on two RAC nodes, file ownership on shared storage becomes inconsistent.
# Create oracle user
# -u 54321 → fixed UID
# -g oinstall → primary group (oinstall, NOT dba — this is a common mistake)
# -G dba,oper,... → secondary groups (all Oracle privilege groups)
# -d /home/oracle → home directory
# -s /bin/bash → login shell
useradd -u 54321 \
-g oinstall \
-G dba,oper,backupdba,dgdba,kmdba,racdba \
-d /home/oracle \
-s /bin/bash \
oracle
# Set a password for oracle user
passwd oracle
# Verify — confirm UID, primary group, and all secondary groups
id oracleIMPORTANT: Primary group MUST be
oinstall, NOTdba. This is a very common mistake. If oracle’s primary group isdba, all Oracle files will be owned bydbainstead ofoinstall, which breaks the privilege separation model.
2.3 — Create Directory Structure
Why: Oracle installer needs these directories to exist BEFORE it runs. The installer will not create them. ORACLE_HOME must be an empty directory that oracle user owns. oraInventory tracks what is installed in which Oracle Home.
# Convention A — create all required directories
mkdir -p /u01/app/oracle/product/19.3.0/dbhome_1 # ORACLE_HOME — where Oracle software is installed
mkdir -p /u01/app/oraInventory # Oracle Inventory — tracks all Oracle installs on this server
# Set oracle:oinstall as owner of everything under /u01/app
chown -R oracle:oinstall /u01/app/oracle
chown -R oracle:oinstall /u01/app/oraInventory
# Set permissions to 775 — oracle and oinstall group members can read/write
chmod -R 775 /u01/app/oracle
chmod -R 775 /u01/app/oraInventory# Convention B — create all required directories
mkdir -p /oracle/RDBMS/19.31 # ORACLE_HOME for primary DB
mkdir -p /oracle/RDBMS/19.31Standby # ORACLE_HOME for standby DB (only needed on standby server)
mkdir -p /oracle/oraInventory # Oracle Inventory
# Set ownership and permissions
chown -R oracle:oinstall /oracle
chmod -R 775 /oracle# Verify — both owner and permissions must be correct
# Expected output example: drwxrwxr-x. 2 oracle oinstall 4096 Jan 15 10:00 /u01/app/oracle
ls -ld $ORACLE_HOME
ls -ld $ORACLE_BASE2.4 — Set Kernel Parameters in /etc/sysctl.conf
Why this file?
/etc/sysctl.confis the Linux system configuration file for kernel parameters. Values set here are automatically loaded at every server boot. This is the permanent way to set kernel parameters.
Why not just run
sysctlcommands directly?sysctl -wchanges are lost after a reboot./etc/sysctl.confmakes them permanent.
# Open /etc/sysctl.conf as root for editing
vi /etc/sysctl.confWhat to do: Scroll to the very end of the file and add the following block. Do not delete existing entries — just append below them.
# -------------------------------------------------------
# Oracle 19c Required Kernel Parameters
# Added by DBA on <date> for Oracle installation
# -------------------------------------------------------
# Shared memory — controls how much shared memory Oracle SGA can use
# shmall = total shared memory in pages (page = 4KB on Linux)
# shmmax = max size of a single shared memory segment in bytes
# shmmni = max number of shared memory segments
kernel.shmall = 1073741824
kernel.shmmax = 4398046511104
kernel.shmmni = 4096
# Semaphores — Oracle background processes use semaphores for IPC
# Format: semmsl semmns semopm semmni
# semmsl = max semaphores per set, semmns = total semaphores system-wide
# semopm = max ops per semop call, semmni = max semaphore sets
kernel.sem = 250 32000 100 128
# File handles — Oracle opens many files simultaneously
fs.file-max = 6815744
# Async I/O — Oracle uses async I/O for better disk performance
fs.aio-max-nr = 1048576
# Network — Oracle Net uses these for connection buffers
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576# Apply the new values immediately — no reboot needed
# -p flag reads and applies values from /etc/sysctl.conf
/sbin/sysctl -p
# Verify the values were applied correctly
/sbin/sysctl -a | grep -E "kernel.shmall|kernel.shmmax|fs.file-max"What to look for: The values shown must match what you just set. If they don’t, re-check for typos in /etc/sysctl.conf.
2.5 — Set OS User Limits in /etc/security/limits.conf
Why this file?
/etc/security/limits.confis the Linux file that controls per-user resource limits (files, processes, memory). The values set here are applied every time theoracleuser logs in or a new session is opened. Without these settings, Oracle hits OS-level resource limits and throws errors.
Why both soft and hard? Soft limit = current active limit. Hard limit = the ceiling the user can raise themselves without root. Oracle automatically raises to the hard limit during startup. Both must be set high enough.
# Open the limits file as root
vi /etc/security/limits.confWhat to do: Scroll to the very end of the file and add the following block. Do not remove existing entries.
# -------------------------------------------------------
# Oracle 19c User Resource Limits
# Added by DBA on <date> for Oracle installation
# -------------------------------------------------------
# nofile = maximum number of open file descriptors
# Oracle opens many datafiles, redo logs, trace files simultaneously
oracle soft nofile 1024
oracle hard nofile 65536
# nproc = maximum number of processes the oracle user can spawn
# Oracle has many background processes (PMON, SMON, DBWn, LGWR etc.)
oracle soft nproc 2047
oracle hard nproc 16384
# stack = stack size per process in KB
# Oracle requires at least 10MB stack per process
oracle soft stack 10240
oracle hard stack 32768
# memlock = locked memory in KB (used for HugePages if configured)
# Set to 3GB here — adjust based on SGA size
oracle soft memlock 3145728
oracle hard memlock 3145728IMPORTANT: These limits take effect only on new login sessions. If you are already logged in as oracle, log out and log back in, then verify:
su - oracle
ulimit -n # Should show 65536 (hard nofile)
ulimit -u # Should show 16384 (hard nproc)2.6 — Set oracle User Environment Profile (~/.bash_profile)
Why? The
~/.bash_profilefile is executed every time the oracle user logs in. It sets the Oracle environment variables that ALL Oracle commands depend on. Without these variables, commands likesqlplus,rman,lsnrctlwill either not be found or will connect to the wrong database.
What each variable does:
ORACLE_BASE→ Root of all Oracle software and diagnostic filesORACLE_HOME→ Where this specific Oracle version is installedORACLE_SID→ Which database instance to connect to by defaultNLS_DATE_FORMAT→ How dates appear in SQL output (very important for readability)NLS_LANG→ Character set for the sessionPATH→ Ensures Oracle binaries are found without full pathLD_LIBRARY_PATH→ Where Oracle looks for shared libraries
# Switch to oracle user
su - oracle
# Open the profile file for editing
vi ~/.bash_profileWhat to do: Add the following block at the END of the existing
.bash_profilefile. Do not remove the existing content (it usually hasPATHandumasksettings already).
Convention A — add this block:
# -------------------------------------------------------
# Oracle Environment Configuration
# -------------------------------------------------------
# ORACLE_BASE — root directory for all Oracle software on this server
export ORACLE_BASE=/u01/app/oracle
# ORACLE_HOME — directory where this specific Oracle version (19.3) is installed
export ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1
# ORACLE_SID — name of the database instance on this server
# Change this to match your actual DB name (e.g., PROD, DEVDB, etc.)
export ORACLE_SID=ORCL
# NLS settings — controls date format and character set in SQL sessions
export NLS_DATE_FORMAT="DD-MON-YYYY HH24:MI:SS"
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
# PATH — add Oracle bin directory so you can run sqlplus, rman etc. directly
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH
# LD_LIBRARY_PATH — where Oracle looks for its shared libraries (.so files)
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
# CLASSPATH — for Oracle Java components
export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
# Useful shortcuts — optional but very helpful in day-to-day work
alias sqlp='sqlplus / as sysdba'
alias alert='tail -500f $ORACLE_BASE/diag/rdbms/*/*/trace/alert_*.log'Convention B Primary Server — add this block:
# -------------------------------------------------------
# Oracle Environment Configuration — PRIMARY SERVER
# -------------------------------------------------------
export ORACLE_BASE=/oracle
export ORACLE_HOME=/oracle/RDBMS/19.31
export ORACLE_SID=ORCL
export NLS_DATE_FORMAT="DD-MON-YYYY HH24:MI:SS"
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
alias sqlp='sqlplus / as sysdba'
alias alert='tail -500f $ORACLE_BASE/diag/rdbms/*/*/trace/alert_*.log'Convention B Standby Server — add this block:
# -------------------------------------------------------
# Oracle Environment Configuration — STANDBY SERVER
# NOTE: ORACLE_HOME points to 19.31Standby — different from primary
# This allows independent patching of primary and standby homes
# -------------------------------------------------------
export ORACLE_BASE=/oracle
export ORACLE_HOME=/oracle/RDBMS/19.31Standby
export ORACLE_SID=ORCL_STBY
export NLS_DATE_FORMAT="DD-MON-YYYY HH24:MI:SS"
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
alias sqlp='sqlplus / as sysdba'
alias alert='tail -500f $ORACLE_BASE/diag/rdbms/*/*/trace/alert_*.log'# Apply the profile in the current session (so you don't need to log out)
. ~/.bash_profile
# Verify all variables are set correctly
echo "ORACLE_BASE = $ORACLE_BASE"
echo "ORACLE_HOME = $ORACLE_HOME"
echo "ORACLE_SID = $ORACLE_SID"
echo "PATH = $PATH"2.7 — Unzip Oracle Software into ORACLE_HOME
Why unzip INTO ORACLE_HOME? This is the single most important thing to know about 19c installation. In Oracle 11g and 12c, you unzipped the installer to a staging area and ran
runInstallerfrom there. Oracle 19c changed this completely. The zip file IS the Oracle Home — you must unzip it directly into your pre-created empty ORACLE_HOME directory. TherunInstallerbinary is inside the zip.
# Switch to oracle user
su - oracle
# Move into the ORACLE_HOME directory
cd $ORACLE_HOME
# Unzip the installer directly here
# -q = quiet mode (no verbose output, faster)
unzip -q /stage/19c/LINUX.X64_193000_db_home.zip
# Verify key files are now present in ORACLE_HOME
ls $ORACLE_HOME/runInstaller # The installer binary
ls $ORACLE_HOME/install/response/ # Response files for silent installIMPORTANT: If you unzip to
/stage/19c/and runrunInstallerfrom there (the old 11g/12c method), the installer will create a new directory inside the stage folder as ORACLE_HOME, which is NOT what you want. Always unzip into the pre-created$ORACLE_HOMEdirectory.
SECTION 3 — ORACLE SOFTWARE INSTALLATION
3.1 — Silent Installation
Why silent installation? Silent install uses a command line with parameters instead of clicking through a GUI wizard. In production environments, GUI is often not available (no X11/display). Silent installs are also repeatable, documentable, and scriptable — essential for a consultant.
Why software-only first? We separate software installation from database creation. This gives you more control — you can install software once and create multiple databases, or apply patches to the software before creating the database.
su - oracle
cd $ORACLE_HOME
# Run silent software-only installation
# Each parameter is explained below
./runInstaller -silent \
-responseFile $ORACLE_HOME/install/response/db_install.rsp \
oracle.install.option=INSTALL_DB_SWONLY \ # Install software only — no DB creation yet
UNIX_GROUP_NAME=oinstall \ # OS group that owns the inventory
INVENTORY_LOCATION=/u01/app/oraInventory \ # Where Oracle tracks all installations
ORACLE_BASE=/u01/app/oracle \ # Oracle base directory
oracle.install.db.InstallEdition=EE \ # EE = Enterprise Edition, SE2 = Standard Edition 2
oracle.install.db.OSDBA_GROUP=dba \ # OS group that gets SYSDBA privilege
oracle.install.db.OSOPER_GROUP=oper \ # OS group that gets SYSOPER privilege
oracle.install.db.OSBACKUPDBA_GROUP=backupdba \ # OS group for SYSBACKUP privilege
oracle.install.db.OSDGDBA_GROUP=dgdba \ # OS group for SYSDG (Data Guard) privilege
oracle.install.db.OSKMDBA_GROUP=kmdba \ # OS group for SYSKM (TDE Key Management) privilege
oracle.install.db.OSRACDBA_GROUP=racdba \ # OS group for SYSRAC (RAC) privilege
SECURITY_UPDATES_VIA_MYORACLESUPPORT=false \ # Do not connect to MOS during install
DECLINE_SECURITY_UPDATES=true # Decline automatic security updatesMonitor installation progress in a second terminal (do not close the installer terminal):
# Open a new terminal as oracle and watch the log
tail -100f /tmp/InstallActions*/installActions*.logWhen installation is complete you will see a message like:
The installation of Oracle Database 19c was successful.Please check '/tmp/InstallActions.../installActions.log' for more details.
3.2 — Run Root Scripts (MANDATORY — as root)
Why these scripts? The Oracle installer cannot run certain privileged operations itself because it runs as the
oracleuser. These two scripts perform the privileged steps that require root access:
orainstRoot.sh— registers the Oracle inventory location with the OS (creates/etc/oraInst.loc) and sets correct permissions on the inventory directoryroot.sh— sets the correct ownership and setuid permissions on the Oracle binary itself (theoraclebinary must be owned by root with setuid bit set so it can allocate shared memory)
IMPORTANT: Run these as root. Run them in this exact order. Never skip either one. If you skip
root.sh, the Oracle binary will not have the correct permissions and the database will fail to start.
# Open a new terminal and switch to root
su - root
# OR
sudo su -
# STEP 1 — Run orainstRoot.sh first
# This registers the inventory and creates /etc/oraInst.loc
/u01/app/oraInventory/orainstRoot.sh
# Convention B: /oracle/oraInventory/orainstRoot.sh
# STEP 2 — Run root.sh immediately after
# This sets SUID permissions on Oracle binary and other root-owned steps
/u01/app/oracle/product/19.3.0/dbhome_1/root.sh
# Convention B: /oracle/RDBMS/19.31/root.shExpected output from root.sh (you should see something like this):
Performing root operations...
The following environment variables are set as:
ORACLE_OWNER= oracle
ORACLE_HOME= /u01/app/oracle/product/19.3.0/dbhome_1
Enter the full pathname of the local bin directory: [/usr/local/bin]:
Copying dbhome to /usr/local/bin ...
Copying oraenv to /usr/local/bin ...
Copying coraenv to /usr/local/bin ...
Creating /etc/oratab file...
Entries will be added to the /etc/oratab file as needed by
Database Configuration Assistant when a database is created
Finished running generic part of root script.Press Enter when prompted for
/usr/local/bin— accept the default.
IMPORTANT: Go back to the installer terminal and click OK (if GUI) or let the silent install continue AFTER root scripts complete.
3.3 — Configure Oracle Listener (netca)
What is the listener? The Oracle Listener is a separate process that listens on a network port (default 1521) and accepts incoming database connection requests. Without a listener, only local OS-authenticated connections work. Remote applications, JDBC connections, and tools like SQL Developer cannot connect without a listener.
What does netca do? NETCA (Network Configuration Assistant) creates the
listener.orafile and starts the listener process. It also creates a basictnsnames.oraandsqlnet.ora.
su - oracle
# Configure listener silently using the default response file
# This creates a listener named LISTENER on port 1521
netca -silent -responseFile $ORACLE_HOME/network/install/netca_typ.rsp
# Verify the listener started and is running
lsnrctl status
# Check listener log for any errors
tail -50 $ORACLE_HOME/network/log/listener.logWhat lsnrctl status output should look like:
LSNRCTL for Linux: Version 19.0.0.0.0
STATUS of the LISTENER
Alias LISTENER
Version TNSLSNR for Linux: Version 19.0.0.0.0
Start Date 15-JAN-2024 10:30:00
Uptime 0 days 0 hr. 0 min. 5 sec.
Trace Level off
Security ON: Local OS Authentication
Listener Port(s) 1521IMPORTANT: If port 1521 is already in use by another Oracle installation on the same server, the listener will fail to start. Check with
ss -tlnp | grep 1521. If occupied, you must use a different port — edit the response file and change the port before running netca.
3.4 — Create Database Using DBCA (Silent)
What is DBCA? DBCA (Database Configuration Assistant) creates the actual Oracle database — it creates the datafiles, redo logs, control files, installs the data dictionary, and configures the database parameters.
Why silent DBCA? Same reason as silent installer — no GUI dependency, repeatable, documentable.
su - oracle
# Create a non-CDB (traditional) database
# Each parameter is explained inline
dbca -silent \
-createDatabase \
-templateName General_Purpose.dbc \ # Use General Purpose template — suitable for most workloads
-gdbName ORCL \ # Global database name (DB_NAME.DB_DOMAIN)
-sid ORCL \ # Oracle SID — must match ORACLE_SID in your profile
-responseFile NO_VALUE \ # Do not use a response file — use inline parameters
-characterSet AL32UTF8 \ # Character set — AL32UTF8 supports all languages, use this always
-sysPassword Oracle_123 \ # SYS user password — change to your standard
-systemPassword Oracle_123 \ # SYSTEM user password — change to your standard
-createAsContainerDatabase false \ # false = traditional non-CDB database
-databaseType MULTIPURPOSE \ # MULTIPURPOSE = balanced for OLTP and reporting
-automaticMemoryManagement false \ # false = we will manage SGA/PGA manually (recommended)
-totalMemory 2048 \ # Total memory in MB Oracle can use (SGA+PGA combined)
-storageType FS \ # FS = filesystem storage (use ASM for production RAC)
-datafileDestination /u01/app/oracle/oradata \ # Where datafiles will be created
-redoLogFileSize 200 \ # Redo log size in MB — 200MB is a good starting point
-emConfiguration NONE \ # Do not configure OEM during DBCA (we do it separately)
-ignorePreReqs # Ignore prerequisite warnings (we already checked manually)Convention B — change
-datafileDestinationto/oracle/oradata
Monitor DBCA progress in a separate terminal:
# Convention A
tail -100f /u01/app/oracle/cfgtoollogs/dbca/ORCL/ORCL*.log
# Convention B
tail -100f /oracle/cfgtoollogs/dbca/ORCL/ORCL*.logIMPORTANT — CDB Option: If your company policy requires Container Database (CDB) architecture (common in 19c deployments), change the DBCA command as follows:
-createAsContainerDatabase true \
-numberOfPDBs 1 \
-pdbName PDB1 \
-pdbAdminPassword Oracle_123 \3.5 — Verify and Configure /etc/oratab
What is /etc/oratab? This is a simple text file that maps each Oracle SID to its ORACLE_HOME path. It is used by:
dbstartanddbshutscripts to know which databases to start/stop at bootoraenvscript to switch between Oracle environments- Oracle agents and monitoring tools to discover databases on the server
The
Yat the end means “auto-start this database at boot”.Nmeans do not auto-start.
# Check if DBCA added the entry automatically
cat /etc/oratabExpected entry:
# Convention A:
ORCL:/u01/app/oracle/product/19.3.0/dbhome_1:Y
# Convention B:
ORCL:/oracle/RDBMS/19.31:Y# If the entry is missing, add it manually as root:
# Convention A:
echo "ORCL:/u01/app/oracle/product/19.3.0/dbhome_1:Y" >> /etc/oratab
# Convention B:
echo "ORCL:/oracle/RDBMS/19.31:Y" >> /etc/oratab
# Verify the entry is now correct
cat /etc/oratab3.6 — Configure Database Auto-Startup at Boot (systemd)
Why? By default, Oracle database does NOT start automatically when the Linux server is rebooted. In production environments, a server reboot (for patching, hardware maintenance etc.) must be followed by the database coming up automatically — you cannot expect a DBA to be online at 2 AM after every reboot to manually start the database.
What is systemd? systemd is the Linux service manager used in OL7, OL8, and RHEL 7/8. It controls what services start at boot and in what order. We create a custom service unit file that tells systemd to run Oracle’s
dbstartscript at boot time anddbshutat shutdown.
What is the service unit file? A plain text file with three sections:
[Unit]→ Describes the service and when it should start (after network is ready)[Service]→ What commands to run to start and stop the service, and which user to run as[Install]→ Which system boot target should include this service (multi-user.target= normal multi-user Linux boot)
Step 1 — Create the service unit file (as root)
# Open a new file in the systemd service directory
# This directory is where all systemd service definitions live
vi /etc/systemd/system/oracle-db.serviceStep 2 — Add the following content into the file
Paste the entire block below as-is. Do not leave any blank lines at the top. Change the paths to match your convention.
Convention A — paste this:
[Unit]
Description=Oracle Database Service
# "After=network.target" means: only start this service after the network interfaces are up
# This is important because the listener needs network to accept connections
After=network.target
[Service]
# Type=forking means the startup command spawns child processes and exits
# This is how Oracle works — dbstart starts Oracle then exits
Type=forking
# Run Oracle as the oracle OS user, not root
User=oracle
Group=oinstall
# ExecStart = command to run when starting the service
# dbstart reads /etc/oratab and starts all databases with Y flag
# The argument after dbstart is ORACLE_HOME — dbstart needs it to find Oracle binaries
ExecStart=/u01/app/oracle/product/19.3.0/dbhome_1/bin/dbstart /u01/app/oracle/product/19.3.0/dbhome_1
# ExecStop = command to run when stopping the service (server shutdown or systemctl stop)
# dbshut reads /etc/oratab and shuts down all databases with Y flag
ExecStop=/u01/app/oracle/product/19.3.0/dbhome_1/bin/dbshut /u01/app/oracle/product/19.3.0/dbhome_1
# RemainAfterExit=yes means systemd considers the service "active" even after
# dbstart exits — because Oracle database processes continue running in the background
RemainAfterExit=yes
[Install]
# multi-user.target = normal Linux boot level (equivalent of runlevel 3)
# This line registers the service to start during normal system boot
WantedBy=multi-user.targetConvention B — paste this:
[Unit]
Description=Oracle Database Service
After=network.target
[Service]
Type=forking
User=oracle
Group=oinstall
# ExecStart — dbstart reads /etc/oratab and starts all Y-flagged databases
# Argument is the ORACLE_HOME path — must match /etc/oratab and your bash_profile
ExecStart=/oracle/RDBMS/19.31/bin/dbstart /oracle/RDBMS/19.31
# ExecStop — dbshut shuts down all Y-flagged databases gracefully before server powers off
ExecStop=/oracle/RDBMS/19.31/bin/dbshut /oracle/RDBMS/19.31
RemainAfterExit=yes
[Install]
WantedBy=multi-user.targetStep 3 — Enable and start the service (as root)
# Reload systemd daemon so it picks up the new service file we just created
# Must run this every time you create or modify a service file
systemctl daemon-reload
# Enable the service — registers it to start automatically at every boot
# This creates a symlink in the appropriate boot target directory
systemctl enable oracle-db.service
# Start the service right now (without rebooting)
systemctl start oracle-db.service
# Check the service status — confirms it started successfully
systemctl status oracle-db.serviceExpected output from systemctl status:
● oracle-db.service - Oracle Database Service
Loaded: loaded (/etc/systemd/system/oracle-db.service; enabled; vendor preset: disabled)
Active: active (exited) since Tue 2024-01-15 10:45:00 IST; 5s ago
Process: 12345 ExecStart=/u01/app/.../dbstart ... (code=exited, status=0/SUCCESS)
Main PID: 12345 (code=exited, status=0/SUCCESS)
Active: active (exited)is CORRECT and expected — not a problem. This is becausedbstartstarts Oracle and then exits (Type=forking). TheRemainAfterExit=yestells systemd the service is still active even though the startup process exited.
IMPORTANT — Verify auto-startup actually works: After setting up the service, test it by rebooting the server and confirming the database comes up automatically. Do not trust
systemctl enablealone without a reboot test in a non-production environment first.
# Test restart (only do this in a test window, not production peak hours)
reboot
# After server comes back up — verify DB is running
su - oracle
sqlplus / as sysdba
SELECT status FROM v$instance;SECTION 4 — POST-INSTALLATION CHECKS
IMPORTANT: Post-checks are your final quality gate. Do NOT hand over the environment, mark the task complete, or move to the next step without completing every check below. In a consultant role, these checks are your proof of delivery.
Run all SQL queries from
sqlplus / as sysdbaunless stated otherwise.
4.1 — Verify Oracle Inventory
Why? The inventory is Oracle’s internal record of what is installed. If inventory is corrupted or incomplete, future patching with OPatch will fail.
su - oracle
# View the inventory XML file directly
# This shows all Oracle Homes registered on this server
cat /u01/app/oraInventory/ContentsXML/inventory.xml
# Convention B: cat /oracle/oraInventory/ContentsXML/inventory.xml
# Use OPatch to display inventory in readable format
# This is the standard way to check what is installed
$ORACLE_HOME/OPatch/opatch lsinventoryWhat to look for in OPatch output: Your ORACLE_HOME should be listed, and it should show Oracle Database 19c with version 19.3.0.0.0.
4.2 — Verify Oracle Home Binaries & Permissions
Why? The oracle binary must have the setuid (SUID) bit set and be owned by root. Without this, the database cannot allocate shared memory segments. This is set by root.sh — so if root.sh was not run, this will be wrong.
# Check all key binaries exist
ls -lh $ORACLE_HOME/bin/oracle # Main database binary — must be owned by root with SUID
ls -lh $ORACLE_HOME/bin/sqlplus # SQL*Plus command line tool
ls -lh $ORACLE_HOME/bin/rman # RMAN backup tool
ls -lh $ORACLE_HOME/bin/expdp # Data Pump export
ls -lh $ORACLE_HOME/bin/impdp # Data Pump import
ls -lh $ORACLE_HOME/bin/lsnrctl # Listener control
ls -lh $ORACLE_HOME/bin/dbca # Database Configuration Assistant
# Specifically check oracle binary permissions
stat $ORACLE_HOME/bin/oracle | grep -E "Access|Uid"What to look for: The oracle binary must show:
-rwsr-s--x 1 root oinstall 419M Jan 15 10:40 oracleThe s in rws is the setuid bit — this is critical. If you see rwx without s, root.sh was not run correctly.
4.3 — Check Database Instance Status
Why? Confirms the database is open and accepting connections.
READ WRITEmeans the database is fully open.MOUNTEDmeans it started but is not open.STARTEDmeans only the instance is up but database is not mounted.
sqlplus / as sysdba
-- Formatting for clean output
set linesize 150
set pagesize 50
col name for a12
col db_unique_name for a20
col open_mode for a15
col log_mode for a15
col host_name for a30
col instance_name for a15
col status for a12
col version for a15
-- Check database status
SELECT name, db_unique_name, open_mode, log_mode
FROM v$database;
-- Check instance status
SELECT instance_name, version, host_name, status
FROM v$instance;Expected output:
NAME DB_UNIQUE_NAME OPEN_MODE LOG_MODE
------------ -------------------- --------------- ---------------
ORCL orcl READ WRITE ARCHIVELOG4.4 — Check All Datafiles Are Online
Why? A datafile in OFFLINE status means that tablespace is inaccessible. Any application trying to access objects in that tablespace will get errors. Must be verified before go-live.
set linesize 200
set pagesize 100
col file# for 999
col tablespace_name for a25
col status for a12
col name for a70
SELECT file#, tablespace_name, status, name
FROM v$datafile
ORDER BY file#;What to look for: Every row must show ONLINE in the STATUS column. If any shows OFFLINE or RECOVER — stop and investigate immediately.
4.5 — Check Tablespace Usage
Why? Ensures all tablespaces were created correctly during DBCA and have adequate free space. SYSTEM and SYSAUX tablespaces should never be close to full on a fresh install.
sql
set linesize 200
set pagesize 100
col tablespace_name for a25
col status for a10
col contents for a12
col total_mb for 9999999
col free_mb for 9999999
col used_pct for 999.99
SELECT df.tablespace_name,
df.status,
df.contents,
ROUND(df.bytes/1024/1024,2) total_mb,
ROUND(NVL(fs.bytes,0)/1024/1024,2) free_mb,
ROUND((1 - NVL(fs.bytes,0)/df.bytes)*100,2) used_pct
FROM (SELECT tablespace_name, status, contents,
SUM(bytes) bytes
FROM dba_data_files
GROUP BY tablespace_name, status, contents) df,
(SELECT tablespace_name, SUM(bytes) bytes
FROM dba_free_space
GROUP BY tablespace_name) fs
WHERE df.tablespace_name = fs.tablespace_name(+)
ORDER BY df.tablespace_name;4.6 — Check Redo Log Groups and Status
📝 Why? Redo logs record every change made to the database — they are critical for recovery. After a fresh install, all redo log groups should be
INACTIVEor one should beCURRENT. If any group showsNEEDS ARCHIVINGon a fresh install, archiving is not working properly.
set linesize 180
set pagesize 50
col l# for 999
col status for a12
col member for a65
SELECT l.group# l#,
l.members,
l.bytes/1024/1024 size_mb,
l.status,
l.archived,
f.member
FROM v$log l, v$logfile f
WHERE l.group# = f.group#
ORDER BY l.group#;What to look for: One group should show CURRENT (the active redo log). Others should be INACTIVE or ACTIVE. Column archived should show YES for all non-CURRENT groups (if in archivelog mode).
4.7 — Check Alert Log for Errors
Why? The alert log is the database’s own diary — it records every startup, shutdown, error, and significant event. Even if the database appears to be working, there may be warnings or non-fatal errors in the alert log that indicate a problem. Always check it after installation.
# Step 1 — Find the exact location of the alert log
sqlplus -s / as sysdba <<EOF
set linesize 200 pagesize 0
col value for a80
SELECT value FROM v\$diag_info WHERE name = 'Diag Trace';
EXIT;
EOF# Step 2 — Scan the alert log for any errors or warnings
# Convention A path:
tail -200 /u01/app/oracle/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log \
| grep -E "ORA-|Error|WARNING|CORRUPTED|FAILED"
# Convention B path:
tail -200 /oracle/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log \
| grep -E "ORA-|Error|WARNING|CORRUPTED|FAILED"What to look for: No output = good. Any ORA- errors need investigation before sign-off.
4.8 — Verify Listener is Registered and Working End-to-End
Why two checks?
lsnrctl statusonly confirms the listener process is running. Testing an actual TNS connection (step 2 below) confirms the database has registered with the listener AND the full network path from client to database works. Both are needed.
# Check 1 — Listener process status and registered services
lsnrctl status
# Check 2 — Test actual TNS connection (bypasses OS authentication, uses listener)
# If this works, listener and network are both fine
sqlplus system/Oracle_123@localhost:1521/ORCLIn lsnrctl status output look for: Your database service (e.g., ORCL) listed under Services Summary.
4.9 — Check OPatch Version and Applied Patches
Why? A fresh 19.3 base installation has NO patches applied. You need to document the baseline patch level. This is also your reference point before applying the latest Release Update in the next SOP.
su - oracle
# Check OPatch utility version itself
$ORACLE_HOME/OPatch/opatch version
# List all patches currently installed in this Oracle Home
# On a fresh 19.3 base install — this will show nothing under "Patch description"
$ORACLE_HOME/OPatch/opatch lsinventory
# Condensed view — just Oracle home version and any patches
$ORACLE_HOME/OPatch/opatch lsinventory | grep -E "Oracle Database|Patch "📎 Download latest OPatch: MOS Doc ID 6880880.1
📎 Find latest 19c Release Updates: MOS → Patches & Updates → search “Oracle Database 19c Release Update”
4.10 — Check Archivelog Mode and Archive Destination
Why? In production, databases MUST be in ARCHIVELOG mode for backup and recovery (RMAN) and for Data Guard. If the database was created in NOARCHIVELOG mode, it must be switched to ARCHIVELOG before go-live.
set linesize 150
set pagesize 50
col dest_name for a30
col status for a10
col target for a12
col archiver for a12
-- Shows current archive mode and archive destination
ARCHIVE LOG LIST;
-- Shows configured archive destinations and their status
SELECT dest_id, dest_name, status, target, archiver
FROM v$archive_dest
WHERE status != 'INACTIVE'
ORDER BY dest_id;What to look for: Database log mode: Archive Mode and Automatic archival: Enabled.
⚠️ IMPORTANT: If database is in
No Archive Mode, switch it to archivelog mode immediately:
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
ARCHIVE LOG LIST; -- Confirm it now shows Archive Mode4.11 — Check for INVALID Database Objects
Why? Oracle’s internal components (PL/SQL packages, views, triggers) must all be in VALID state. INVALID objects mean a component did not compile correctly. This can cause unexpected errors when those components are used by the database engine or by applications.
set linesize 180
set pagesize 100
col owner for a20
col object_name for a45
col object_type for a25
col status for a10
-- List all invalid objects
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE status = 'INVALID'
ORDER BY owner, object_type, object_name;
-- Quick count
SELECT COUNT(*) invalid_count
FROM dba_objects
WHERE status = 'INVALID';What to look for: Count should be 0 or very close to 0. A handful of invalid objects in non-SYS/SYSTEM schemas is normal on a fresh install.
IMPORTANT: If you see INVALID objects under SYS or SYSTEM, run
utlrp.sqlto recompile them:
-- Recompile all invalid objects in the database
-- This script is provided by Oracle, located in the ORACLE_HOME
@?/rdbms/admin/utlrp.sql
-- Re-check after recompile — count should now be 0
SELECT COUNT(*) invalid_count
FROM dba_objects
WHERE status = 'INVALID';4.12 — Final Component Registry Check
Why? dba_registry shows the installation status of every Oracle component (XML DB, JVM, Spatial, OLAP, etc.). All installed components must be in VALID state. This is Oracle’s own validation that all components installed and initialized correctly.
set linesize 200
set pagesize 100
col comp_name for a50
col version for a15
col status for a12
SELECT comp_name, version, status
FROM dba_registry
ORDER BY comp_name;What to look for: Every row must show VALID in the STATUS column.
IMPORTANT: If ANY component shows
INVALID,LOADING, orREMOVING— the installation is not clean. Do NOT hand over the environment. Raise this with Oracle Support (MOS SR) before proceeding.
SECTION 5 — QUICK REFERENCE CARD
| Task | Command / Action |
|---|---|
| Check OS version | cat /etc/os-release |
| Check disk space | df -hP |
| Check /tmp space | df -hP /tmp |
| Check RAM | grep MemTotal /proc/meminfo |
| Check kernel params | sysctl -a | grep -E "shm|sem|file-max" |
| Install OS packages | yum install -y binutils libaio libaio-devel ... |
| Check oracle limits | su - oracle -c "ulimit -a" |
| Check hostname | hostname -f |
| Check oracle groups | grep oinstall /etc/group |
| Check oracle user | id oracle |
| Unzip location (19c rule) | Directly INTO $ORACLE_HOME — not a staging folder |
| Root scripts order | orainstRoot.sh first → then root.sh |
| oracle binary permission | Must show -rwsr-s--x 1 root oinstall |
| Check DB open mode | SELECT open_mode FROM v$database; |
| Check instance status | SELECT status FROM v$instance; |
| Check listener | lsnrctl status |
| Test TNS connection | sqlplus system/pwd@localhost:1521/ORCL |
| View alert log | tail -200 alert_ORCL.log | grep ORA- |
| Check patches | opatch lsinventory |
| Check invalid objects | SELECT count(*) FROM dba_objects WHERE status='INVALID'; |
| Recompile invalids | @?/rdbms/admin/utlrp.sql |
| Check all components | SELECT comp_name,status FROM dba_registry; |
| Switch to archivelog | STARTUP MOUNT; ALTER DATABASE ARCHIVELOG; ALTER DATABASE OPEN; |
| MOS Install Guide | Doc ID 2660755.1 |
| MOS OPatch Download | Doc ID 6880880.1 |
This SOP covers everything you need to install Oracle Database 19c on Linux from scratch without referring to any other source. Bookmark this page and use the Quick Reference Card above during your next installation for a clean, error-free setup.