{"id":5758,"date":"2026-07-15T14:11:38","date_gmt":"2026-07-15T08:41:38","guid":{"rendered":"https:\/\/w3buddy.com\/?p=5758"},"modified":"2026-07-19T22:16:59","modified_gmt":"2026-07-19T16:46:59","slug":"oracle-rac-19c-installation","status":"publish","type":"post","link":"https:\/\/w3buddy.com\/blog\/oracle-rac-19c-installation\/","title":{"rendered":"Oracle RAC 19c Installation"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A complete production-ready SOP for installing Oracle Real Application Clusters (RAC) 19c on Linux from scratch. Covers cluster planning, shared storage setup, Grid Infrastructure installation, ASM diskgroup creation, RAC database creation, services configuration, and full post-installation validation \u2014 with real commands, expected outputs, and consultant-level notes for both standard OFA and enterprise custom path conventions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">1. Document Info<\/h3>\n\n\n\n<figure class=\"wp-block-table has-small-font-size\"><table><thead><tr><th>Item<\/th><th>Detail<\/th><\/tr><\/thead><tbody><tr><td>Oracle Version<\/td><td>19c (Grid Infrastructure + RDBMS 19.3)<\/td><\/tr><tr><td>OS<\/td><td>Oracle Linux 7.x \/ RHEL 7.x or 8.x<\/td><\/tr><tr><td>Install Type<\/td><td>2-Node RAC (extensible to N nodes)<\/td><\/tr><tr><td>Storage Type<\/td><td>Shared ASM Disks (SAN\/iSCSI\/NFS)<\/td><\/tr><tr><td>MOS Reference<\/td><td>Doc ID 2329539.1 (19c Grid Install on Linux)<\/td><\/tr><tr><td>MOS Reference<\/td><td>Doc ID 1526147.1 (RAC Assurance Checklist)<\/td><\/tr><tr><td>MOS Reference<\/td><td>Doc ID 265633.1 (ASM Disk Discovery)<\/td><\/tr><tr><td>Prepared By<\/td><td>Oracle DBA \/ Consultant<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. RAC Architecture \u2014 Understand Before You Start<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>What is Oracle RAC?<\/strong> Oracle RAC (Real Application Clusters) allows multiple servers (nodes) to run the same Oracle database simultaneously. All nodes share the same database files stored on shared storage. If one node fails, the other nodes continue serving the database \u2014 providing High Availability. RAC also scales performance by distributing the workload across nodes.<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why is RAC complex?<\/strong> Unlike a standalone database where everything is on one server, RAC requires precise coordination between servers \u2014 shared storage, private network for inter-node communication, cluster software, shared voting disks, and synchronized configuration across all nodes. Every component must be correctly configured or the cluster will not form.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Key RAC Components You Must Know<\/h4>\n\n\n\n<figure class=\"wp-block-table has-small-font-size\"><table><thead><tr><th>Component<\/th><th>What It Is<\/th><th>Why It Matters<\/th><\/tr><\/thead><tbody><tr><td>Grid Infrastructure (GI)<\/td><td>Oracle&#8217;s cluster software stack<\/td><td>Must be installed BEFORE the database. Manages cluster membership, resources, and ASM.<\/td><\/tr><tr><td>Clusterware<\/td><td>Part of GI \u2014 manages cluster nodes<\/td><td>Detects node failures, restarts failed services, manages VIPs<\/td><\/tr><tr><td>ASM<\/td><td>Shared storage management<\/td><td>All RAC datafiles live in ASM diskgroups on shared storage<\/td><\/tr><tr><td>SCAN<\/td><td>Single Client Access Name<\/td><td>One DNS name for clients to connect to RAC \u2014 Oracle routes to the least loaded node<\/td><\/tr><tr><td>SCAN Listener<\/td><td>Listener on SCAN IP<\/td><td>Accepts client connections and redirects to local node listeners<\/td><\/tr><tr><td>VIP<\/td><td>Virtual IP per node<\/td><td>If a node fails, VIP fails over to another node so clients reconnect quickly<\/td><\/tr><tr><td>Private Interconnect<\/td><td>Dedicated private network between nodes<\/td><td>Used for Cache Fusion \u2014 nodes share database blocks over this network. Must be fast and reliable.<\/td><\/tr><tr><td>Public Network<\/td><td>Regular network for client connections<\/td><td>Clients connect to the database through this network<\/td><\/tr><tr><td>OCR<\/td><td>Oracle Cluster Registry<\/td><td>Stores cluster configuration \u2014 which nodes exist, which resources are configured<\/td><\/tr><tr><td>Voting Disk<\/td><td>Quorum disk on shared storage<\/td><td>Resolves split-brain scenarios \u2014 which node should survive if nodes lose contact<\/td><\/tr><tr><td>Cache Fusion<\/td><td>RAC&#8217;s block sharing mechanism<\/td><td>Allows nodes to share database blocks in memory over the interconnect without writing to disk<\/td><\/tr><tr><td>GI Home<\/td><td>Grid Infrastructure ORACLE_HOME<\/td><td>Completely separate from DB ORACLE_HOME. Never mix them.<\/td><\/tr><tr><td>CRS<\/td><td>Cluster Ready Services<\/td><td>The main GI daemon that starts everything else<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">RAC Network Requirements Summary<\/h4>\n\n\n\n<figure class=\"wp-block-table has-small-font-size\"><table><thead><tr><th>Network Type<\/th><th>Interface<\/th><th>IP Type<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td>Public<\/td><td>eth0 \/ ens3<\/td><td>Static Public IP per node<\/td><td>Client connections<\/td><\/tr><tr><td>Private (Interconnect)<\/td><td>eth1 \/ ens4<\/td><td>Private IP per node<\/td><td>Cache Fusion, node-to-node communication<\/td><\/tr><tr><td>Virtual IP (VIP)<\/td><td>eth0 (same as public)<\/td><td>Virtual IP per node<\/td><td>Client failover<\/td><\/tr><tr><td>SCAN<\/td><td>DNS only<\/td><td>3 x SCAN IPs (recommended)<\/td><td>Single connection point for all clients<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> The private interconnect network must be a <strong>dedicated, low-latency<\/strong> network. Never share the interconnect with public traffic. In real environments this is either a dedicated NIC pair, a dedicated VLAN, or InfiniBand. A slow or shared interconnect is the number one cause of RAC performance problems.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3. Path Conventions<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd Confirm which convention your environment uses before starting. All examples use Convention A. Substitute Convention B paths where applicable.<\/p>\n<\/blockquote>\n\n\n\n<figure class=\"wp-block-table has-small-font-size\"><table><thead><tr><th>Item<\/th><th>Convention A<\/th><th>Convention B<\/th><\/tr><\/thead><tbody><tr><td>Oracle Base<\/td><td>\/u01\/app\/oracle<\/td><td>\/oracle<\/td><\/tr><tr><td>Grid Home<\/td><td>\/u01\/app\/19.3.0\/grid<\/td><td>\/oracle\/GRID\/19.31<\/td><\/tr><tr><td>DB Oracle Home<\/td><td>\/u01\/app\/oracle\/product\/19.3.0\/dbhome_1<\/td><td>\/oracle\/RDBMS\/19.31<\/td><\/tr><tr><td>oraInventory<\/td><td>\/u01\/app\/oraInventory<\/td><td>\/oracle\/oraInventory<\/td><\/tr><tr><td>Grid Base<\/td><td>\/u01\/app\/grid<\/td><td>\/oracle\/grid<\/td><\/tr><tr><td>ASM Data DG<\/td><td>+DATA<\/td><td>+DATA<\/td><\/tr><tr><td>ASM FRA DG<\/td><td>+FRA<\/td><td>+FRA<\/td><\/tr><tr><td>ASM OCR\/Vote DG<\/td><td>+OCR<\/td><td>+OCR<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Grid Infrastructure has its OWN separate ORACLE_HOME (Grid Home). It must NEVER be the same directory as the database ORACLE_HOME. Installing GI into the DB home or vice versa will corrupt both installations.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4. Pre-Installation Planning<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why plan before touching anything?<\/strong> RAC installation involves DNS entries, IP addresses, hostnames, and network configuration that must all be consistent and correct BEFORE the first installer is run. Changing these after GI is installed is painful and sometimes requires a full reinstall.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">4.1 \u2014 Plan and Document Your IP Address Layout<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Every IP in RAC has a specific role. You must plan all IPs before touching any server. Share this with your network team to get the IPs allocated and configured.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Example 2-node RAC IP layout \u2014 fill this in for your environment:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table has-small-font-size\"><table><thead><tr><th>Hostname<\/th><th>Type<\/th><th>IP Address<\/th><th>Interface<\/th><th>DNS Required?<\/th><\/tr><\/thead><tbody><tr><td>racnode1<\/td><td>Public<\/td><td>192.168.1.11<\/td><td>eth0<\/td><td>Yes<\/td><\/tr><tr><td>racnode2<\/td><td>Public<\/td><td>192.168.1.12<\/td><td>eth0<\/td><td>Yes<\/td><\/tr><tr><td>racnode1-vip<\/td><td>VIP<\/td><td>192.168.1.13<\/td><td>eth0 (virtual)<\/td><td>Yes<\/td><\/tr><tr><td>racnode2-vip<\/td><td>VIP<\/td><td>192.168.1.14<\/td><td>eth0 (virtual)<\/td><td>Yes<\/td><\/tr><tr><td>racnode1-priv<\/td><td>Private<\/td><td>192.168.10.11<\/td><td>eth1<\/td><td>No (hosts file)<\/td><\/tr><tr><td>racnode2-priv<\/td><td>Private<\/td><td>192.168.10.12<\/td><td>eth1<\/td><td>No (hosts file)<\/td><\/tr><tr><td>rac-scan<\/td><td>SCAN<\/td><td>192.168.1.15<\/td><td>DNS only<\/td><td>Yes \u2014 must resolve to 1-3 IPs<\/td><\/tr><tr><td>rac-scan<\/td><td>SCAN<\/td><td>192.168.1.16<\/td><td>DNS only<\/td><td>Yes<\/td><\/tr><tr><td>rac-scan<\/td><td>SCAN<\/td><td>192.168.1.17<\/td><td>DNS only<\/td><td>Yes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> SCAN IPs must be registered in DNS \u2014 NOT in <code>\/etc\/hosts<\/code>. Oracle Grid Infrastructure specifically checks that SCAN resolves via DNS and not via hosts file. If SCAN is in <code>\/etc\/hosts<\/code> only, GI installation will fail prerequisite checks.<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why 3 SCAN IPs?<\/strong> Oracle recommends 3 SCAN IPs for load balancing and availability. With 3 SCAN IPs, client connections are round-robin distributed. You can use 1 SCAN IP in lab\/test environments but never in production.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">4.2 \u2014 Plan Shared Storage Layout<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> All nodes must see the exact same shared disks with the exact same device paths. Plan the diskgroup layout before storage is presented to the servers.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Recommended diskgroup layout:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table has-small-font-size\"><table><thead><tr><th>Diskgroup<\/th><th>Purpose<\/th><th>Redundancy<\/th><th>Recommended Size<\/th><\/tr><\/thead><tbody><tr><td>+OCR<\/td><td>OCR files, Voting disks, GI files<\/td><td>NORMAL (3 disks minimum)<\/td><td>50 GB<\/td><\/tr><tr><td>+DATA<\/td><td>Database datafiles, controlfiles, spfile<\/td><td>EXTERNAL or NORMAL<\/td><td>Based on DB size<\/td><\/tr><tr><td>+FRA<\/td><td>Archivelogs, RMAN backups, flashback logs<\/td><td>EXTERNAL or NORMAL<\/td><td>2-3x DATA size<\/td><\/tr><tr><td>+REDO<\/td><td>Online redo logs (optional \u2014 for performance)<\/td><td>HIGH<\/td><td>50-100 GB<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why separate +OCR diskgroup?<\/strong> OCR and Voting disks are critical cluster files. Keeping them in a separate diskgroup with NORMAL or HIGH redundancy protects the cluster even if the DATA diskgroup has issues. Never put OCR\/Voting disks in the same diskgroup as database files in production.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">5. Pre-Installation Checks \u2014 Both Nodes<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Every check in this section must be performed on <strong>ALL nodes<\/strong> unless stated otherwise. A configuration difference between nodes is the most common cause of RAC installation failures. Always run checks on node1 AND node2 and compare results.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.1 \u2014 Check OS Version and Architecture on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Both nodes must run identical OS versions. A mismatch in kernel version or OS release between nodes causes clusterware instability.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Run on BOTH nodes and compare output \u2014 must be identical\ncat \/etc\/os-release\nuname -r\nuname -m<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What to look for:<\/strong> Exact same output on both nodes. Any difference must be resolved before proceeding.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.2 \u2014 Check and Configure \/etc\/hosts on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> <code>\/etc\/hosts<\/code> must have entries for all public, private, and VIP hostnames on all nodes. Private network hostnames go here (not DNS). Public and VIP hostnames can be in DNS or hosts file \u2014 but must be resolvable.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Check current \/etc\/hosts on both nodes\ncat \/etc\/hosts<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Add the following entries to <code>\/etc\/hosts<\/code> on ALL nodes (as root):<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># -------------------------------------------------------\n# Oracle RAC \/etc\/hosts entries\n# -------------------------------------------------------\n\n# Public IPs\n192.168.1.11    racnode1.company.com      racnode1\n192.168.1.12    racnode2.company.com      racnode2\n\n# Virtual IPs (VIP) \u2014 managed by Clusterware\n192.168.1.13    racnode1-vip.company.com  racnode1-vip\n192.168.1.14    racnode2-vip.company.com  racnode2-vip\n\n# Private Interconnect IPs \u2014 used for Cache Fusion only\n192.168.10.11   racnode1-priv.company.com racnode1-priv\n192.168.10.12   racnode2-priv.company.com racnode2-priv\n\n# NOTE: DO NOT add SCAN entries here \u2014 SCAN must resolve via DNS only<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Verify hostname resolution works from both nodes\n# Run on node1 \u2014 ping all hostnames\nping -c 2 racnode1\nping -c 2 racnode2\nping -c 2 racnode1-vip\nping -c 2 racnode2-vip\nping -c 2 racnode1-priv\nping -c 2 racnode2-priv\n\n# Verify SCAN resolves via DNS (not hosts file)\nnslookup rac-scan\n# Must return 1-3 IPs and must NOT come from \/etc\/hosts<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.3 \u2014 Check Network Interfaces on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Grid Infrastructure needs to know which interface is public and which is private. It detects this during installation based on subnet. Both nodes must have identical interface names and subnet assignments.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Check all network interfaces and their IP addresses\nip addr show\n\n# Check interface names (must be same on both nodes)\nip link show\n\n# Verify public interface is up\nping -c 3 192.168.1.11    # node1 public from node2\nping -c 3 192.168.1.12    # node2 public from node1\n\n# Verify private interconnect is up and working\nping -c 3 192.168.10.11   # node1 private from node2\nping -c 3 192.168.10.12   # node2 private from node1\n\n# Check interconnect latency \u2014 should be sub-millisecond\nping -c 10 192.168.10.12 | tail -2<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> If private interconnect ping shows latency above 1ms consistently, investigate the network. Poor interconnect performance will cause Cache Fusion bottlenecks and cluster instability in production.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.4 \u2014 Check Disk Space on All Nodes<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># Check all filesystems \u2014 run on both nodes\ndf -hP\n\n# Minimum requirements:\n# \/u01 (or \/oracle) \u2014 15GB+ for GI Home + DB Home + diag files\n# \/tmp \u2014 1GB+\n# \/home\/oracle \u2014 1GB+ (for oracle user home)\n\ndf -hP \/tmp\nfree -m<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.5 \u2014 Check Required OS Packages on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> RAC requires additional packages beyond standalone installation \u2014 specifically for cluster communication and shared storage.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Run on BOTH nodes\nrpm -q binutils \\\n        compat-libcap1 \\\n        compat-libstdc++-33 \\\n        gcc \\\n        gcc-c++ \\\n        glibc \\\n        glibc-devel \\\n        ksh \\\n        libaio \\\n        libaio-devel \\\n        libgcc \\\n        libstdc++ \\\n        libstdc++-devel \\\n        libXi \\\n        libXtst \\\n        make \\\n        sysstat \\\n        elfutils-libelf-devel \\\n        nfs-utils \\\n        smartmontools \\\n        net-tools \\\n        bind-utils \\\n        unzip <strong>2<\/strong>&gt;<strong>&amp;1<\/strong> | grep \"not installed\"<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Install missing packages on BOTH nodes (as root)\nyum install -y binutils compat-libcap1 compat-libstdc++-33 gcc gcc-c++ \\\nglibc glibc-devel ksh libaio libaio-devel libgcc libstdc++ libstdc++-devel \\\nlibXi libXtst make sysstat elfutils-libelf-devel nfs-utils \\\nsmartmontools net-tools bind-utils unzip<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.6 \u2014 Check and Set Kernel Parameters on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Same as standalone but with additional parameters needed for cluster communication and shared memory across nodes.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Check current values \u2014 run on BOTH nodes\n\/sbin\/sysctl -a | grep -E \\\n\"kernel.shmall|kernel.shmmax|kernel.shmmni|\\\nkernel.sem|fs.file-max|fs.aio-max-nr|\\\nnet.ipv4.ip_local_port_range|\\\nnet.core.rmem_default|net.core.rmem_max|\\\nnet.core.wmem_default|net.core.wmem_max|\\\nnet.ipv4.conf.all.rp_filter|\\\nnet.ipv4.conf.default.rp_filter\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Add to <code>\/etc\/sysctl.conf<\/code> on ALL nodes (as root):<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># -------------------------------------------------------\n# Oracle 19c RAC Required Kernel Parameters\n# Added by DBA on &lt;date&gt;\n# -------------------------------------------------------\n\nkernel.shmall = 1073741824\nkernel.shmmax = 4398046511104\nkernel.shmmni = 4096\nkernel.sem = 250 32000 100 128\nfs.file-max = 6815744\nfs.aio-max-nr = 1048576\nnet.ipv4.ip_local_port_range = 9000 65500\nnet.core.rmem_default = 262144\nnet.core.rmem_max = 4194304\nnet.core.wmem_default = 262144\nnet.core.wmem_max = 1048576\n\n# RAC specific \u2014 disable reverse path filtering on interconnect\n# Without this, interconnect packets may be dropped by the kernel\nnet.ipv4.conf.all.rp_filter = 2\nnet.ipv4.conf.default.rp_filter = 2<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Apply on BOTH nodes\n\/sbin\/sysctl -p\n\n# Verify on BOTH nodes\n\/sbin\/sysctl -a | grep -E \"kernel.shmall|net.ipv4.conf.all.rp_filter\"<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.7 \u2014 Check and Set OS User Limits on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Same limits as standalone. Must be configured identically on all nodes.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Add to <code>\/etc\/security\/limits.conf<\/code> on ALL nodes (as root):<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># -------------------------------------------------------\n# Oracle 19c RAC User Resource Limits\n# -------------------------------------------------------\noracle   soft   nofile    1024\noracle   hard   nofile    65536\noracle   soft   nproc     2047\noracle   hard   nproc     16384\noracle   soft   stack     10240\noracle   hard   stack     32768\noracle   soft   memlock   3145728\noracle   hard   memlock   3145728\ngrid     soft   nofile    1024\ngrid     hard   nofile    65536\ngrid     soft   nproc     2047\ngrid     hard   nproc     16384\ngrid     soft   stack     10240\ngrid     hard   stack     32768\ngrid     soft   memlock   3145728\ngrid     hard   memlock   3145728<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Note:<\/strong> In RAC, we also set limits for the <code>grid<\/code> OS user (who owns the Grid Infrastructure installation) in addition to the <code>oracle<\/code> user.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.8 \u2014 Check Shared Storage Visibility from All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> All shared disks must be visible from ALL nodes with the same device paths. If node1 sees a disk as <code>\/dev\/sdb<\/code> but node2 sees the same disk as <code>\/dev\/sdd<\/code>, ASM will fail or worse \u2014 both nodes will try to write to different disks thinking they are the same.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Check block devices on BOTH nodes\nlsblk\n\n# List all disk devices\nls -l \/dev\/sd*\n\n# Confirm same disks visible \u2014 sizes must match\nfdisk -l <strong>2<\/strong>&gt;\/dev\/null | grep \"^Disk \/dev\/sd\"\n\n# Verify device paths are identical on both nodes\n# Run this on node1 then node2 and compare\nls -l \/dev\/sd* | awk '{print $5, $6, $10}'<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> If device paths differ between nodes, you must work with your storage team to present the LUNs with consistent device names. Use udev rules or ASMLib\/ASMFD to assign consistent names to shared disks across all nodes.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.9 \u2014 Configure SSH User Equivalence Between Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Oracle Grid Infrastructure installer runs scripts on all nodes simultaneously. It uses SSH to execute commands on remote nodes without a password prompt. Without passwordless SSH between nodes (for both oracle and grid users), the installer will hang waiting for a password.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Run on NODE 1 as oracle user\nsu - oracle\n\n# Step 1 \u2014 Generate SSH key pair on node1\nssh-keygen -t rsa -b 2048\n# Press Enter for all prompts (no passphrase)\n\n# Step 2 \u2014 Copy public key to node2\nssh-copy-id oracle@racnode2\n\n# Step 3 \u2014 Test passwordless SSH from node1 to node2\nssh racnode2 hostname\nssh racnode2 date\n\n# Step 4 \u2014 Test passwordless SSH from node1 to itself (required by GI)\nssh racnode1 hostname<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Repeat on NODE 2 as oracle user\nsu - oracle\nssh-keygen -t rsa -b 2048\nssh-copy-id oracle@racnode1\nssh racnode1 hostname\nssh racnode2 hostname<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Repeat the entire process above for the grid user on BOTH nodes\n# Grid user also needs passwordless SSH for GI installer\nsu - grid\nssh-keygen -t rsa -b 2048\nssh-copy-id grid@racnode1\nssh-copy-id grid@racnode2\nssh racnode1 hostname\nssh racnode2 hostname<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Test SSH in BOTH directions from BOTH nodes. The installer tests all combinations. If any single combination requires a password, the installer will fail.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.10 \u2014 Check Time Synchronization on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Oracle Clusterware requires all nodes to have synchronized clocks. A time difference of more than a few seconds between nodes causes Clusterware to evict nodes from the cluster (a deliberate protection mechanism against split-brain). NTP or Chrony must be configured and working on all nodes.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Check time synchronization service status (run on ALL nodes)\nsystemctl status chronyd\n# OR\nsystemctl status ntpd\n\n# Check current time on all nodes \u2014 must be within seconds of each other\ndate\n\n# Check NTP\/Chrony sync status\nchronyc tracking\n# OR\nntpq -p\n\n# Check time difference between nodes\n# From node1 \u2014 compare date with node2\nssh racnode2 date<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> If time is not synchronized, configure and start chrony before proceeding. GI will explicitly check time synchronization during installation.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Configure chrony if not running (as root on ALL nodes)\nsystemctl enable chronyd\nsystemctl start chronyd\nchronyc makestep    # Force immediate time sync\nchronyc tracking    # Verify synchronized<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.11 \u2014 Verify SCAN DNS Resolution<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> GI installer explicitly checks that SCAN resolves via DNS. This is a hard requirement. If it fails, the installer stops.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Verify SCAN resolves to 1-3 IPs via DNS (run on ALL nodes)\nnslookup rac-scan\n# OR\nhost rac-scan\n# OR\ndig rac-scan\n\n# Must return IP addresses and must NOT use \/etc\/hosts\n# Also verify forward and reverse resolution\nnslookup 192.168.1.15\nnslookup 192.168.1.16\nnslookup 192.168.1.17<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What correct <code>nslookup rac-scan<\/code> output looks like:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Server:   192.168.1.1\nAddress:  192.168.1.1#53\n\nName:     rac-scan.company.com\nAddress:  192.168.1.15\nName:     rac-scan.company.com\nAddress:  192.168.1.16\nName:     rac-scan.company.com\nAddress:  192.168.1.17<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5.12 \u2014 Run Oracle Cluster Verification Utility (cluvfy)<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> <code>cluvfy<\/code> is Oracle&#8217;s own pre-installation checker for RAC. It checks everything in one command \u2014 OS packages, kernel parameters, SSH equivalence, network configuration, disk visibility, and more. It is the most comprehensive pre-check available. Always run it before starting GI installation.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># cluvfy is inside the Grid Infrastructure software\n# First unzip GI software (as grid user) to Grid Home\nsu - grid\ncd \/u01\/app\/19.3.0\/grid\nunzip -q \/stage\/19c\/LINUX.X64_193000_grid_home.zip\n\n# Run pre-installation checks for all nodes\n$ORACLE_HOME\/runcluvfy.sh stage -pre crsinst \\\n    -n racnode1,racnode2 \\\n    -fixup \\\n    -verbose<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>What <code>-fixup<\/code> does:<\/strong> Generates a fixup script that automatically corrects many of the issues it finds. Review and run the fixup script as root on all nodes.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># After cluvfy completes \u2014 review the fixup script if generated\n# Run as root on ALL nodes\n\/tmp\/CVU_&lt;date&gt;\/runfixup.sh<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Do NOT proceed with GI installation until <code>cluvfy<\/code> shows no FAILED checks. WARNING items can sometimes be ignored (cluvfy output explains each one) but FAILED items must be fixed.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">6. Pre-Installation Configuration \u2014 Both Nodes<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Every configuration step must be performed on ALL nodes unless explicitly stated. Always confirm by checking both nodes after each step.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">6.1 \u2014 Create OS Groups on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Same groups as standalone plus additional groups for Grid Infrastructure. GIDs must be identical across all nodes.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Run as root on ALL nodes\ngroupadd -g 54321 oinstall\ngroupadd -g 54322 dba\ngroupadd -g 54323 oper\ngroupadd -g 54324 backupdba\ngroupadd -g 54325 dgdba\ngroupadd -g 54326 kmdba\ngroupadd -g 54327 racdba\ngroupadd -g 54328 asmadmin    # ASM administrator group\ngroupadd -g 54329 asmdba      # ASM SYSDBA group\ngroupadd -g 54330 asmoper     # ASM SYSOPER group\n\n# Verify all groups on BOTH nodes \u2014 output must be identical\ngrep -E \"oinstall|dba|oper|backupdba|dgdba|kmdba|racdba|asmadmin|asmdba|asmoper\" \/etc\/group<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">6.2 \u2014 Create oracle and grid OS Users on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why two users?<\/strong> In RAC, Oracle best practice separates the Grid Infrastructure owner (<code>grid<\/code>) from the database software owner (<code>oracle<\/code>). This provides privilege separation \u2014 the <code>grid<\/code> user owns Clusterware and ASM, the <code>oracle<\/code> user owns the database software. UIDs must be identical across all nodes.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Run as root on ALL nodes\n\n# Create grid user \u2014 owns Grid Infrastructure and ASM\nuseradd -u 54320 \\\n        -g oinstall \\\n        -G dba,asmadmin,asmdba,asmoper \\\n        -d \/home\/grid \\\n        -s \/bin\/bash \\\n        grid\n\npasswd grid\n\n# Create oracle user \u2014 owns database software\nuseradd -u 54321 \\\n        -g oinstall \\\n        -G dba,oper,backupdba,dgdba,kmdba,racdba,asmadmin,asmdba \\\n        -d \/home\/oracle \\\n        -s \/bin\/bash \\\n        oracle\n\npasswd oracle\n\n# Verify both users on BOTH nodes\nid grid\nid oracle<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">6.3 \u2014 Create Directory Structure on All Nodes<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Grid Home and DB Home directories must exist on all nodes with correct ownership. These are local directories \u2014 not shared. Each node has its own copy of the software.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Run as root on ALL nodes\n\n# Convention A\nmkdir -p \/u01\/app\/19.3.0\/grid                        # Grid Infrastructure Home\nmkdir -p \/u01\/app\/oracle\/product\/19.3.0\/dbhome_1     # Database Home\nmkdir -p \/u01\/app\/oraInventory                         # Oracle Inventory\nmkdir -p \/u01\/app\/grid                                 # Grid Base\n\n# Set ownership\nchown -R grid:oinstall    \/u01\/app\/19.3.0\nchown -R grid:oinstall    \/u01\/app\/grid\nchown -R grid:oinstall    \/u01\/app\/oraInventory\nchown -R oracle:oinstall  \/u01\/app\/oracle\n\n# Set permissions\nchmod -R 775 \/u01\/app<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Convention B\nmkdir -p \/oracle\/GRID\/19.31\nmkdir -p \/oracle\/RDBMS\/19.31\nmkdir -p \/oracle\/oraInventory\nmkdir -p \/oracle\/grid\n\nchown -R grid:oinstall    \/oracle\/GRID\nchown -R grid:oinstall    \/oracle\/grid\nchown -R grid:oinstall    \/oracle\/oraInventory\nchown -R oracle:oinstall  \/oracle\/RDBMS<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Verify on ALL nodes\nls -ld \/u01\/app\/19.3.0\/grid\nls -ld \/u01\/app\/oracle\/product\/19.3.0\/dbhome_1\nls -ld \/u01\/app\/oraInventory<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">6.4 \u2014 Configure Environment Profiles on All Nodes<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>For grid user \u2014 add to <code>~\/.bash_profile<\/code> on ALL nodes:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>su - grid\nvi ~\/.bash_profile<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># -------------------------------------------------------\n# Grid Infrastructure Environment \u2014 grid user\n# -------------------------------------------------------\nexport ORACLE_BASE=\/u01\/app\/grid               # Grid Base (separate from oracle base)\nexport ORACLE_HOME=\/u01\/app\/19.3.0\/grid        # Grid Infrastructure Home\nexport ORACLE_SID=+ASM                          # ASM instance SID\nexport NLS_DATE_FORMAT=\"DD-MON-YYYY HH24:MI:SS\"\nexport NLS_LANG=AMERICAN_AMERICA.AL32UTF8\nexport PATH=$ORACLE_HOME\/bin:$ORACLE_HOME\/OPatch:$PATH\nexport LD_LIBRARY_PATH=$ORACLE_HOME\/lib:\/lib:\/usr\/lib\nexport CLASSPATH=$ORACLE_HOME\/jlib:$ORACLE_HOME\/rdbms\/jlib\n\nalias asmcli='asmcmd'\nalias alert='tail -500f $ORACLE_BASE\/diag\/asm\/+asm\/+ASM\/trace\/alert_+ASM.log'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>For oracle user \u2014 add to <code>~\/.bash_profile<\/code> on ALL nodes:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>su - oracle\nvi ~\/.bash_profile<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># -------------------------------------------------------\n# Oracle Database Environment \u2014 oracle user\n# -------------------------------------------------------\nexport ORACLE_BASE=\/u01\/app\/oracle\nexport ORACLE_HOME=\/u01\/app\/oracle\/product\/19.3.0\/dbhome_1\nexport ORACLE_SID=RACDB1                        # Node1: RACDB1, Node2: RACDB2\nexport NLS_DATE_FORMAT=\"DD-MON-YYYY HH24:MI:SS\"\nexport NLS_LANG=AMERICAN_AMERICA.AL32UTF8\nexport PATH=$ORACLE_HOME\/bin:$ORACLE_HOME\/OPatch:$PATH\nexport LD_LIBRARY_PATH=$ORACLE_HOME\/lib:\/lib:\/usr\/lib\nexport CLASSPATH=$ORACLE_HOME\/jlib:$ORACLE_HOME\/rdbms\/jlib\n\nalias sqlp='sqlplus \/ as sysdba'\nalias alert='tail -500f $ORACLE_BASE\/diag\/rdbms\/*\/*\/trace\/alert_*.log'<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Note:<\/strong> <code>ORACLE_SID<\/code> is node-specific in RAC. Node1 uses <code>RACDB1<\/code>, node2 uses <code>RACDB2<\/code>. The DB_NAME is <code>RACDB<\/code> (shared). Each instance name = DB_NAME + node_number.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">6.5 \u2014 Configure Shared Disk Permissions and udev Rules<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> ASM needs to read and write directly to the raw shared disks. By default Linux sets disk permissions to root only. We must change permissions so the <code>grid<\/code> and <code>oracle<\/code> users can access the disks. udev rules make these permissions persistent across reboots.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Step 1 \u2014 Identify the shared disks (run as root)\n# These are the disks your storage team presented for ASM\nlsblk | grep -v sda    # sda is usually the OS disk \u2014 exclude it\n\n# Step 2 \u2014 Check WWIDs for persistent naming (important for SAN disks)\n\/usr\/lib\/udev\/scsi_id --whitelisted --replace-whitespace --device=\/dev\/sdb\n\/usr\/lib\/udev\/scsi_id --whitelisted --replace-whitespace --device=\/dev\/sdc\n# Note the WWID output for each disk\n\n# Step 3 \u2014 Create udev rules file for persistent disk naming and permissions\nvi \/etc\/udev\/rules.d\/99-oracle-asmdevices.rules<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Add one line per shared disk (use your actual WWIDs):<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Oracle ASM Disk udev Rules\n# Format: KERNEL==device, SUBSYSTEM==block, ENV{ID_SERIAL}==WWID, SYMLINK+=name, OWNER=grid, GROUP=asmadmin, MODE=0660\n\n# OCR\/Vote diskgroup disks\nKERNEL==\"sdb\", SUBSYSTEM==\"block\", ENV{ID_SERIAL}==\"&lt;WWID_DISK1&gt;\", SYMLINK+=\"oracleasm\/ocr1\", OWNER=\"grid\", GROUP=\"asmadmin\", MODE=\"0660\"\nKERNEL==\"sdc\", SUBSYSTEM==\"block\", ENV{ID_SERIAL}==\"&lt;WWID_DISK2&gt;\", SYMLINK+=\"oracleasm\/ocr2\", OWNER=\"grid\", GROUP=\"asmadmin\", MODE=\"0660\"\nKERNEL==\"sdd\", SUBSYSTEM==\"block\", ENV{ID_SERIAL}==\"&lt;WWID_DISK3&gt;\", SYMLINK+=\"oracleasm\/ocr3\", OWNER=\"grid\", GROUP=\"asmadmin\", MODE=\"0660\"\n\n# DATA diskgroup disks\nKERNEL==\"sde\", SUBSYSTEM==\"block\", ENV{ID_SERIAL}==\"&lt;WWID_DISK4&gt;\", SYMLINK+=\"oracleasm\/data1\", OWNER=\"grid\", GROUP=\"asmadmin\", MODE=\"0660\"\nKERNEL==\"sdf\", SUBSYSTEM==\"block\", ENV{ID_SERIAL}==\"&lt;WWID_DISK5&gt;\", SYMLINK+=\"oracleasm\/data2\", OWNER=\"grid\", GROUP=\"asmadmin\", MODE=\"0660\"\n\n# FRA diskgroup disks\nKERNEL==\"sdg\", SUBSYSTEM==\"block\", ENV{ID_SERIAL}==\"&lt;WWID_DISK6&gt;\", SYMLINK+=\"oracleasm\/fra1\", OWNER=\"grid\", GROUP=\"asmadmin\", MODE=\"0660\"<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Apply the udev rules immediately (as root on ALL nodes)\nudevadm control --reload-rules\nudevadm trigger\n\n# Verify the symlinks and permissions were created\nls -l \/dev\/oracleasm\/\n# Expected output: all disks listed with owner=grid, group=asmadmin, mode=660<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Alternative \u2014 Use ASM Filter Driver (ASMFD):<\/strong> ASMFD is Oracle&#8217;s recommended approach in 19c instead of raw udev rules. It provides additional protection by filtering out non-ASM I\/O to ASM disks. If your environment uses ASMFD, configure it during GI installation using the <code>asmcmd afd_label<\/code> command. ASMFD setup is covered in the ASMFD section of MOS Doc ID 2292840.1.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">7. Grid Infrastructure Installation<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Grid Infrastructure is installed ONLY FROM NODE 1. The installer automatically connects to other nodes via SSH and installs\/configures on all nodes simultaneously. Never run the GI installer simultaneously on multiple nodes.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">7.1 \u2014 Unzip Grid Infrastructure Software on Node 1<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># As grid user on NODE 1 ONLY\nsu - grid\n\n# GI software must be unzipped INTO Grid Home (same 19c rule as DB software)\ncd $ORACLE_HOME     # \/u01\/app\/19.3.0\/grid\n\n# Unzip GI software directly into Grid Home\nunzip -q \/stage\/19c\/LINUX.X64_193000_grid_home.zip\n\n# Verify key files are present\nls $ORACLE_HOME\/gridSetup.sh      # GI installer (different from runInstaller)\nls $ORACLE_HOME\/install\/response\/<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Grid Infrastructure uses <code>gridSetup.sh<\/code> as the installer, not <code>runInstaller<\/code>. This is different from the database installer.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">7.2 \u2014 Run Grid Infrastructure Installation (Silent)<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why silent?<\/strong> Same reasons as standalone \u2014 no GUI dependency, repeatable, documentable. In production RAC environments GUI is almost never available.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># As grid user on NODE 1 ONLY\nsu - grid\ncd $ORACLE_HOME\n\n# Silent GI installation for a 2-node cluster\n.\/gridSetup.sh -silent \\\n  -responseFile $ORACLE_HOME\/install\/response\/gridsetup.rsp \\\n  INVENTORY_LOCATION=\/u01\/app\/oraInventory \\\n  oracle.install.option=CRS_CONFIG \\\n  ORACLE_BASE=\/u01\/app\/grid \\\n  oracle.install.asm.OSDBA=asmdba \\\n  oracle.install.asm.OSOPER=asmoper \\\n  oracle.install.asm.OSASM=asmadmin \\\n  oracle.install.crs.config.scanName=rac-scan \\\n  oracle.install.crs.config.scanPort=1521 \\\n  oracle.install.crs.config.ClusterName=rac-cluster \\\n  oracle.install.crs.config.clusterNodes=racnode1:racnode1-vip,racnode2:racnode2-vip \\\n  oracle.install.crs.config.networkInterfaceList=eth0:192.168.1.0:1,eth1:192.168.10.0:5 \\\n  oracle.install.crs.config.storageOption=FLEX_ASM_STORAGE \\\n  oracle.install.crs.config.sharedFileSystemStorage.diskDriveList=\/dev\/oracleasm\/ocr1,\/dev\/oracleasm\/ocr2,\/dev\/oracleasm\/ocr3 \\\n  oracle.install.crs.config.useIPMI=false \\\n  oracle.install.asm.diskGroup.name=OCR \\\n  oracle.install.asm.diskGroup.redundancy=NORMAL \\\n  oracle.install.asm.diskGroup.AUSize=4 \\\n  oracle.install.asm.diskGroup.disks=\/dev\/oracleasm\/ocr1,\/dev\/oracleasm\/ocr2,\/dev\/oracleasm\/ocr3 \\\n  oracle.install.asm.diskGroup.diskDiscoveryString=\/dev\/oracleasm\/* \\\n  oracle.install.asm.monitorPassword=Oracle_123 \\\n  oracle.install.crs.rootconfig.executeRootScript=false \\\n  SECURITY_UPDATES_VIA_MYORACLESUPPORT=false \\\n  DECLINE_SECURITY_UPDATES=true<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Key parameters explained:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>oracle.install.crs.config.networkInterfaceList<\/code> \u2192 format is <code>interface:subnet:role<\/code> where role 1=public, 5=private\/ASM, 3=do not use<\/li>\n\n\n\n<li><code>oracle.install.crs.config.clusterNodes<\/code> \u2192 format is <code>hostname:vip-hostname<\/code> for each node<\/li>\n\n\n\n<li><code>oracle.install.crs.config.scanName<\/code> \u2192 must match exactly what DNS resolves<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd Monitor GI installation log in a separate terminal:<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>tail -100f \/tmp\/GridSetupActions*\/gridSetupActions*.log<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">7.3 \u2014 Run Root Scripts on All Nodes (CRITICAL)<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> When the installer prompts, you must run root scripts on ALL nodes. The order is critical \u2014 run on node1 FIRST, wait for it to complete, THEN run on node2. Running simultaneously or in wrong order will corrupt the cluster configuration.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># TERMINAL 1 \u2014 NODE 1 \u2014 as root\n# Step 1 \u2014 Run orainstRoot.sh on node1 first\n\/u01\/app\/oraInventory\/orainstRoot.sh\n\n# Step 2 \u2014 Run root.sh on node1\n# This starts Clusterware on node1 \u2014 takes 5-15 minutes\n\/u01\/app\/19.3.0\/grid\/root.sh<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Wait for node1 <code>root.sh<\/code> to complete fully before touching node2.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># TERMINAL 2 \u2014 NODE 2 \u2014 as root (only after node1 root.sh completes)\n# Step 3 \u2014 Run orainstRoot.sh on node2\n\/u01\/app\/oraInventory\/orainstRoot.sh\n\n# Step 4 \u2014 Run root.sh on node2\n# This joins node2 to the cluster formed by node1\n\/u01\/app\/19.3.0\/grid\/root.sh<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Expected output from <code>root.sh<\/code> on each node:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Performing root user operation.\nThe following environment variables are set as:\n    ORACLE_OWNER= grid\n    ORACLE_HOME=  \/u01\/app\/19.3.0\/grid\nCopying dbhome to \/usr\/local\/bin ...\nCreating \/etc\/oratab file...\nEntries will be added to the \/etc\/oratab file as needed...\nCRS-4402: The CSS daemon was successfully initialized...\nCRS-4000: Command Start completed successfully...<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd After both <code>root.sh<\/code> scripts complete, go back to the installer terminal and click <strong>OK<\/strong> (GUI) or let silent install continue.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">7.4 \u2014 Verify Cluster Formation After GI Installation<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># As grid user on any node\nsu - grid\n\n# Check cluster status \u2014 all nodes must show online\n$ORACLE_HOME\/bin\/crsctl check cluster -all\n\n# Check all CRS resources\n$ORACLE_HOME\/bin\/crsctl stat res -t\n\n# Check cluster nodes\n$ORACLE_HOME\/bin\/olsnodes -n -i -s\n\n# Check SCAN and VIP resources\n$ORACLE_HOME\/bin\/srvctl status scan\n$ORACLE_HOME\/bin\/srvctl status vip -n racnode1\n$ORACLE_HOME\/bin\/srvctl status vip -n racnode2\n\n# Check ASM is running on all nodes\n$ORACLE_HOME\/bin\/srvctl status asm<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Expected output from <code>crsctl check cluster -all<\/code>:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>**************************************************************\nracnode1:\nCRS-4537: Cluster Ready Services is online\nCRS-4529: Cluster Synchronization Services is online\nCRS-4533: Event Manager is online\n**************************************************************\nracnode2:\nCRS-4537: Cluster Ready Services is online\nCRS-4529: Cluster Synchronization Services is online\nCRS-4533: Event Manager is online\n**************************************************************<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">7.5 \u2014 Create Additional ASM Diskgroups (DATA and FRA)<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> The GI installer only creates the OCR diskgroup. We must separately create the DATA and FRA diskgroups that the database will use.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># As grid user \u2014 connect to ASM instance\nsu - grid\nsqlplus \/ as sysasm<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Create +DATA diskgroup for database files\nCREATE DISKGROUP DATA\n    EXTERNAL REDUNDANCY\n    DISK '\/dev\/oracleasm\/data1',\n         '\/dev\/oracleasm\/data2'\n    ATTRIBUTE 'AU_SIZE'          = '4M',\n              'COMPATIBLE.ASM'   = '19.0',\n              'COMPATIBLE.RDBMS' = '19.0';\n\n-- Create +FRA diskgroup for recovery files\nCREATE DISKGROUP FRA\n    EXTERNAL REDUNDANCY\n    DISK '\/dev\/oracleasm\/fra1'\n    ATTRIBUTE 'AU_SIZE'          = '4M',\n              'COMPATIBLE.ASM'   = '19.0',\n              'COMPATIBLE.RDBMS' = '19.0';\n\n-- Verify all diskgroups are mounted\nset linesize 200\nset pagesize 50\ncol name     for a12\ncol state    for a12\ncol type     for a10\ncol total_gb for 99999.99\ncol free_gb  for 99999.99\n\nSELECT name, state, type,\n       total_mb\/1024 total_gb,\n       free_mb\/1024  free_gb\nFROM   v$asm_diskgroup\nORDER BY name;<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Register new diskgroups with CRS so they auto-mount on startup\nsu - grid\n$ORACLE_HOME\/bin\/srvctl add diskgroup -diskgroup DATA -oraclehome $ORACLE_HOME\n$ORACLE_HOME\/bin\/srvctl add diskgroup -diskgroup FRA  -oraclehome $ORACLE_HOME\n$ORACLE_HOME\/bin\/srvctl start diskgroup -diskgroup DATA\n$ORACLE_HOME\/bin\/srvctl start diskgroup -diskgroup FRA\n$ORACLE_HOME\/bin\/srvctl status diskgroup -diskgroup DATA\n$ORACLE_HOME\/bin\/srvctl status diskgroup -diskgroup FRA<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">8. Oracle Database Software Installation on RAC<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Database software installation is run ONLY FROM NODE 1 as the <code>oracle<\/code> user. The installer deploys software to all nodes automatically via SSH.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">8.1 \u2014 Unzip Oracle Database Software on Node 1<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># As oracle user on NODE 1 ONLY\nsu - oracle\n\n# Unzip DB software into DB Oracle Home\ncd $ORACLE_HOME    # \/u01\/app\/oracle\/product\/19.3.0\/dbhome_1\nunzip -q \/stage\/19c\/LINUX.X64_193000_db_home.zip\n\n# Verify\nls $ORACLE_HOME\/runInstaller<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">8.2 \u2014 Install Oracle Database Software (Silent)<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># As oracle user on NODE 1 ONLY\nsu - oracle\ncd $ORACLE_HOME\n\n# Install DB software for RAC (INSTALL_DB_SWONLY \u2014 no DB creation yet)\n.\/runInstaller -silent \\\n  -responseFile $ORACLE_HOME\/install\/response\/db_install.rsp \\\n  oracle.install.option=INSTALL_DB_SWONLY \\\n  UNIX_GROUP_NAME=oinstall \\\n  INVENTORY_LOCATION=\/u01\/app\/oraInventory \\\n  ORACLE_HOME=$ORACLE_HOME \\\n  ORACLE_BASE=\/u01\/app\/oracle \\\n  oracle.install.db.InstallEdition=EE \\\n  oracle.install.db.OSDBA_GROUP=dba \\\n  oracle.install.db.OSOPER_GROUP=oper \\\n  oracle.install.db.OSBACKUPDBA_GROUP=backupdba \\\n  oracle.install.db.OSDGDBA_GROUP=dgdba \\\n  oracle.install.db.OSKMDBA_GROUP=kmdba \\\n  oracle.install.db.OSRACDBA_GROUP=racdba \\\n  oracle.install.db.isRACOneInstall=false \\\n  oracle.install.db.rac.serverpoolCardinality=0 \\\n  oracle.install.db.config.starterdb.type=GENERAL_PURPOSE \\\n  SECURITY_UPDATES_VIA_MYORACLESUPPORT=false \\\n  DECLINE_SECURITY_UPDATES=true<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># Monitor installation\ntail -100f \/tmp\/InstallActions*\/installActions*.log<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">8.3 \u2014 Run root.sh for DB Home on All Nodes<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># As root on NODE 1 first\n\/u01\/app\/oracle\/product\/19.3.0\/dbhome_1\/root.sh\n\n# Then as root on NODE 2\n\/u01\/app\/oracle\/product\/19.3.0\/dbhome_1\/root.sh<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd Unlike GI <code>root.sh<\/code>, the DB home <code>root.sh<\/code> can be run on both nodes in parallel \u2014 it is safe to do so.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">9. RAC Database Creation via DBCA<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why DBCA for RAC?<\/strong> DBCA handles all the RAC-specific database creation steps \u2014 creating the database on shared ASM storage, configuring multiple instances (one per node), setting up the cluster database registry, and configuring SCAN listeners.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">9.1 \u2014 Create RAC Database (Silent DBCA)<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># As oracle user on NODE 1 ONLY\nsu - oracle\n\ndbca -silent \\\n  -createDatabase \\\n  -templateName General_Purpose.dbc \\\n  -gdbName RACDB \\\n  -sid RACDB \\\n  -responseFile NO_VALUE \\\n  -characterSet AL32UTF8 \\\n  -sysPassword Oracle_123 \\\n  -systemPassword Oracle_123 \\\n  -createAsContainerDatabase false \\\n  -databaseType MULTIPURPOSE \\\n  -automaticMemoryManagement false \\\n  -totalMemory 4096 \\\n  -storageType ASM \\\n  -diskGroupName DATA \\\n  -recoveryAreaDestination +FRA \\\n  -recoveryAreaSize 51200 \\\n  -redoLogFileSize 200 \\\n  -emConfiguration NONE \\\n  -nodelist racnode1,racnode2 \\\n  -databaseConfigType RAC \\\n  -enableArchive true \\\n  -archiveLogDest +FRA \\\n  -ignorePreReqs<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Key RAC-specific parameters:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-nodelist racnode1,racnode2<\/code> \u2192 creates database instances on both nodes<\/li>\n\n\n\n<li><code>-databaseConfigType RAC<\/code> \u2192 creates RAC database (not standalone)<\/li>\n\n\n\n<li><code>-storageType ASM<\/code> \u2192 use ASM for storage (required for RAC)<\/li>\n\n\n\n<li><code>-diskGroupName DATA<\/code> \u2192 primary diskgroup for datafiles<\/li>\n\n\n\n<li><code>-recoveryAreaDestination +FRA<\/code> \u2192 FRA diskgroup for recovery files<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># Monitor DBCA progress\ntail -100f \/u01\/app\/oracle\/cfgtoollogs\/dbca\/RACDB\/RACDB*.log<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">9.2 \u2014 Configure RAC Database Services<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why services?<\/strong> In RAC, applications should connect via a named service rather than directly to an instance. Services provide load balancing (connections distributed across nodes) and High Availability (if a node fails, the service starts on surviving nodes automatically).<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code># As oracle user \u2014 create an application service\nsu - oracle\n\n# Add a service that runs on both nodes (preferred on node1, available on node2)\n$ORACLE_HOME\/bin\/srvctl add service \\\n    -db RACDB \\\n    -service RACDB_APP \\\n    -preferred racnode1 \\\n    -available racnode2 \\\n    -failovertype SELECT \\\n    -failovermethod BASIC \\\n    -failoverretry 3 \\\n    -failoverdelay 3\n\n# Start the service\n$ORACLE_HOME\/bin\/srvctl start service -db RACDB -service RACDB_APP\n\n# Verify service status\n$ORACLE_HOME\/bin\/srvctl status service -db RACDB -service RACDB_APP\n\n# List all services\n$ORACLE_HOME\/bin\/srvctl config service -db RACDB<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">10. Post-Installation Checks<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f <strong>IMPORTANT:<\/strong> Post-checks for RAC are more extensive than standalone. You must verify cluster health, all node connectivity, ASM, database, services, and listeners. Do not sign off on a RAC installation without completing every check below.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.1 \u2014 Check Cluster Status<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># As grid user\nsu - grid\n\n# Full cluster status\n$ORACLE_HOME\/bin\/crsctl check cluster -all\n\n# All CRS resources \u2014 everything should be ONLINE\n$ORACLE_HOME\/bin\/crsctl stat res -t\n\n# Cluster nodes list with status\n$ORACLE_HOME\/bin\/olsnodes -n -i -s -t<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.2 \u2014 Check All CRS Resources Are Online<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>su - grid\n\n# Check all resources \u2014 look for any OFFLINE entries\n$ORACLE_HOME\/bin\/crsctl stat res -t | grep -E \"OFFLINE|INTERMEDIATE|UNKNOWN\"\n\n# Check specific resources\n$ORACLE_HOME\/bin\/srvctl status scan\n$ORACLE_HOME\/bin\/srvctl status scan_listener\n$ORACLE_HOME\/bin\/srvctl status listener\n$ORACLE_HOME\/bin\/srvctl status asm\n$ORACLE_HOME\/bin\/srvctl status database -db RACDB\n$ORACLE_HOME\/bin\/srvctl status service  -db RACDB<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What to look for:<\/strong> No resource should show <code>OFFLINE<\/code> except for intentionally stopped ones.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.3 \u2014 Check Database Instances on All Nodes<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Connect from node1\nsqlplus \/ as sysdba\n\nset linesize 200\nset pagesize 100\ncol inst_id       for 999\ncol instance_name for a15\ncol host_name     for a20\ncol status        for a12\ncol version       for a15\ncol db_name       for a12\ncol open_mode     for a15\n\n-- Shows all instances across all RAC nodes\nSELECT inst_id, instance_name, host_name,\n       version, status, database_status\nFROM   gv$instance\nORDER BY inst_id;\n\n-- Check database open mode across all instances\nSELECT inst_id, name, open_mode, log_mode\nFROM   gv$database\nORDER BY inst_id;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What to look for:<\/strong> All instances must show <code>OPEN<\/code> and <code>ACTIVE<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.4 \u2014 Check ASM Diskgroups on All Nodes<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>su - grid\nsqlplus \/ as sysasm\n\nset linesize 200\nset pagesize 100\ncol inst_id      for 999\ncol name         for a12\ncol state        for a12\ncol total_gb     for 99999.99\ncol free_gb      for 99999.99\ncol offline_disks for 999\n\n-- Shows diskgroup status on ALL nodes (gv$ view)\nSELECT inst_id, name, state,\n       total_mb\/1024  total_gb,\n       free_mb\/1024   free_gb,\n       offline_disks\nFROM   gv$asm_diskgroup\nORDER BY name, inst_id;<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.5 \u2014 Check All Datafiles Are Online<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>sqlplus \/ as sysdba\n\nset linesize 200\nset pagesize 100\ncol file#           for 999\ncol tablespace_name for a25\ncol status          for a12\ncol name            for a70\n\nSELECT file#, tablespace_name, status, name\nFROM   v$datafile\nORDER BY file#;<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.6 \u2014 Check SCAN Listener and Services<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>su - grid\n\n# Check SCAN listener status\n$ORACLE_HOME\/bin\/srvctl status scan_listener\n\n# Check services registered with SCAN listener\nlsnrctl status LISTENER_SCAN1\nlsnrctl status LISTENER_SCAN2\nlsnrctl status LISTENER_SCAN3\n\n# Test SCAN connectivity from a client\nsqlplus system\/Oracle_123@rac-scan:1521\/RACDB_APP<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.7 \u2014 Check Voting Disks<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Voting disks are critical for cluster integrity. If the majority of voting disks become unavailable, the cluster shuts down all nodes (to prevent data corruption). Must always have an odd number and majority available.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>su - grid\n\n# List all voting disks and their paths\n$ORACLE_HOME\/bin\/crsctl query css votedisk<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Expected output:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>##  STATE    File Universal Id                File Name Disk group\n--  -----    -----------------                --------- ---------\n 1. ONLINE   &lt;uid&gt;                            (\/dev\/oracleasm\/ocr1) &#91;OCR]\n 2. ONLINE   &lt;uid&gt;                            (\/dev\/oracleasm\/ocr2) &#91;OCR]\n 3. ONLINE   &lt;uid&gt;                            (\/dev\/oracleasm\/ocr3) &#91;OCR]\nLocated 3 voting disk(s).<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.8 \u2014 Check OCR Integrity<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> OCR stores the entire cluster configuration. If OCR is corrupted, the cluster cannot start. Verify its integrity after installation.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>su - grid\n\n# Check OCR integrity\n$ORACLE_HOME\/bin\/ocrcheck\n\n# Show OCR configuration\n$ORACLE_HOME\/bin\/ocrcheck -config\n\n# List OCR backup status\n$ORACLE_HOME\/bin\/ocrconfig -showbackup<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Expected output from <code>ocrcheck<\/code>:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Oracle Registry Integrity check successful!\nDevice\/File Name    : +OCR\nDevice\/File integrity check succeeded\nOverall system integrity check succeeded<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.9 \u2014 Check Interconnect Configuration<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>su - grid\n\n# Show interface configuration used by Clusterware\n$ORACLE_HOME\/bin\/oifcfg getif\n\n# Check cluster interconnect latency\n$ORACLE_HOME\/bin\/cluvfy comp nodecon -n racnode1,racnode2 -verbose<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.10 \u2014 Check Alert Logs on All Nodes<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># Check CRS alert log (Grid\/Cluster alert log)\n# Run on ALL nodes\ntail -200 \/u01\/app\/grid\/diag\/crs\/racnode1\/crs\/trace\/alert.log \\\n     | grep -E \"ORA-|Error|WARNING|EVICTED|RECONFIG\"\n\n# Check ASM alert log on all nodes\ntail -200 \/u01\/app\/oracle\/diag\/asm\/+asm\/+ASM1\/trace\/alert_+ASM1.log \\\n     | grep -E \"ORA-|Error|WARNING\"\n\n# Check DB alert log on all nodes\ntail -200 \/u01\/app\/oracle\/diag\/rdbms\/racdb\/RACDB1\/trace\/alert_RACDB1.log \\\n     | grep -E \"ORA-|Error|WARNING\"<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.11 \u2014 Run cluvfy Post-Installation Check<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>Why?<\/strong> Run <code>cluvfy<\/code> again after installation to confirm the installed cluster meets all requirements. This is your final validation.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>su - grid\n\n# Run post-installation verification\n$ORACLE_HOME\/runcluvfy.sh stage -post crsinst \\\n    -n racnode1,racnode2 \\\n    -verbose<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What to look for:<\/strong> All checks must show <code>PASSED<\/code>. Any <code>FAILED<\/code> item must be investigated and resolved.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.12 \u2014 Check Invalid Objects<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>sqlplus \/ as sysdba\n\nset linesize 180\nset pagesize 100\ncol owner       for a20\ncol object_name for a45\ncol object_type for a25\ncol status      for a10\n\nSELECT owner, object_name, object_type, status\nFROM   dba_objects\nWHERE  status = 'INVALID'\nORDER BY owner, object_type, object_name;\n\nSELECT COUNT(*) invalid_count\nFROM   dba_objects\nWHERE  status = 'INVALID';<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Recompile if needed\n@?\/rdbms\/admin\/utlrp.sql\n\nSELECT COUNT(*) FROM dba_objects WHERE status = 'INVALID';<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10.13 \u2014 Final Component Registry Check<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>set linesize 200\nset pagesize 100\ncol comp_name for a50\ncol version   for a15\ncol status    for a12\n\nSELECT comp_name, version, status\nFROM   dba_registry\nORDER BY comp_name;<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">11. srvctl \u2014 Essential RAC Management Commands<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\ud83d\udcdd <strong>What is srvctl?<\/strong> <code>srvctl<\/code> (Server Control utility) is the primary tool for managing RAC resources \u2014 starting, stopping, and checking the status of databases, instances, listeners, services, ASM, and more. Learn these commands \u2014 you will use them every day in a RAC environment.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>su - oracle   # or grid for cluster-level resources\n\n# -------------------------------------------------------\n# Database Management\n# -------------------------------------------------------\n\n# Start entire RAC database (all instances on all nodes)\nsrvctl start database -db RACDB\n\n# Stop entire RAC database\nsrvctl stop database -db RACDB -stopoption immediate\n\n# Start specific instance on specific node\nsrvctl start instance -db RACDB -instance RACDB1\n\n# Stop specific instance\nsrvctl stop instance -db RACDB -instance RACDB1 -stopoption immediate\n\n# Check database status across all nodes\nsrvctl status database -db RACDB\n\n# Show database configuration\nsrvctl config database -db RACDB\n\n# -------------------------------------------------------\n# Instance Management\n# -------------------------------------------------------\n\n# Check instance status\nsrvctl status instance -db RACDB -instance RACDB1\n\n# -------------------------------------------------------\n# Listener Management\n# -------------------------------------------------------\n\n# Start listeners on all nodes\nsrvctl start listener\n\n# Stop listeners on all nodes\nsrvctl stop listener\n\n# Check listener status\nsrvctl status listener\n\n# Check SCAN listener\nsrvctl status scan_listener\nsrvctl config scan_listener\n\n# -------------------------------------------------------\n# Service Management\n# -------------------------------------------------------\n\n# Start a service\nsrvctl start service -db RACDB -service RACDB_APP\n\n# Stop a service\nsrvctl stop service -db RACDB -service RACDB_APP\n\n# Relocate service from one node to another\nsrvctl relocate service -db RACDB -service RACDB_APP \\\n    -oldinst RACDB1 -newinst RACDB2\n\n# Check service status\nsrvctl status service -db RACDB\n\n# -------------------------------------------------------\n# ASM Management\n# -------------------------------------------------------\n\n# Check ASM status on all nodes\nsrvctl status asm\n\n# Start ASM on all nodes\nsrvctl start asm\n\n# Stop ASM on all nodes\nsrvctl stop asm\n\n# -------------------------------------------------------\n# Node Management\n# -------------------------------------------------------\n\n# Check cluster node status\nolsnodes -n -s -i -t\n\n# Check VIP status for each node\nsrvctl status vip -n racnode1\nsrvctl status vip -n racnode2\n\n# Check SCAN\nsrvctl status scan\nsrvctl config scan<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">12. Quick Reference Card<\/h3>\n\n\n\n<figure class=\"wp-block-table has-small-font-size\"><table><thead><tr><th>Task<\/th><th>Command<\/th><\/tr><\/thead><tbody><tr><td>Check cluster status<\/td><td><code>crsctl check cluster -all<\/code><\/td><\/tr><tr><td>Check all CRS resources<\/td><td><code>crsctl stat res -t<\/code><\/td><\/tr><tr><td>Check cluster nodes<\/td><td><code>olsnodes -n -i -s -t<\/code><\/td><\/tr><tr><td>Start RAC database<\/td><td><code>srvctl start database -db RACDB<\/code><\/td><\/tr><tr><td>Stop RAC database<\/td><td><code>srvctl stop database -db RACDB -stopoption immediate<\/code><\/td><\/tr><tr><td>Start single instance<\/td><td><code>srvctl start instance -db RACDB -instance RACDB1<\/code><\/td><\/tr><tr><td>Check DB status<\/td><td><code>srvctl status database -db RACDB<\/code><\/td><\/tr><tr><td>Check instances (SQL)<\/td><td><code>SELECT inst_id,instance_name,status FROM gv$instance;<\/code><\/td><\/tr><tr><td>Check SCAN<\/td><td><code>srvctl status scan<\/code><\/td><\/tr><tr><td>Check SCAN listener<\/td><td><code>srvctl status scan_listener<\/code><\/td><\/tr><tr><td>Check listeners<\/td><td><code>srvctl status listener<\/code><\/td><\/tr><tr><td>Check services<\/td><td><code>srvctl status service -db RACDB<\/code><\/td><\/tr><tr><td>Start service<\/td><td><code>srvctl start service -db RACDB -service RACDB_APP<\/code><\/td><\/tr><tr><td>Check ASM (all nodes)<\/td><td><code>srvctl status asm<\/code><\/td><\/tr><tr><td>Check voting disks<\/td><td><code>crsctl query css votedisk<\/code><\/td><\/tr><tr><td>Check OCR integrity<\/td><td><code>ocrcheck<\/code><\/td><\/tr><tr><td>OCR backup status<\/td><td><code>ocrconfig -showbackup<\/code><\/td><\/tr><tr><td>Check interconnect<\/td><td><code>oifcfg getif<\/code><\/td><\/tr><tr><td>Pre-install cluvfy<\/td><td><code>runcluvfy.sh stage -pre crsinst -n racnode1,racnode2<\/code><\/td><\/tr><tr><td>Post-install cluvfy<\/td><td><code>runcluvfy.sh stage -post crsinst -n racnode1,racnode2<\/code><\/td><\/tr><tr><td>Invalid objects count<\/td><td><code>SELECT count(*) FROM dba_objects WHERE status='INVALID';<\/code><\/td><\/tr><tr><td>Recompile invalids<\/td><td><code>@?\/rdbms\/admin\/utlrp.sql<\/code><\/td><\/tr><tr><td>Component registry<\/td><td><code>SELECT comp_name,status FROM dba_registry;<\/code><\/td><\/tr><tr><td>CRS alert log<\/td><td><code>tail -200 $GRID_BASE\/diag\/crs\/&lt;node&gt;\/crs\/trace\/alert.log<\/code><\/td><\/tr><tr><td>MOS RAC Install Guide<\/td><td>Doc ID 2329539.1<\/td><\/tr><tr><td>MOS RAC Assurance<\/td><td>Doc ID 1526147.1<\/td><\/tr><tr><td>MOS OPatch Download<\/td><td>Doc ID 6880880.1<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">This SOP covers everything you need to install Oracle RAC 19c on Linux from scratch without referring to any other source. Always complete the IP planning table before touching any server, always run cluvfy before and after installation, and always verify all CRS resources are online before handing over the environment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A complete production-ready SOP for installing Oracle Real Application Clusters (RAC) 19c on Linux from scratch. Covers cluster planning, shared storage setup, Grid Infrastructure installation, ASM diskgroup creation, RAC database creation, services configuration, and full post-installation validation \u2014 with real commands, expected outputs, and consultant-level notes for both standard OFA and enterprise custom path conventions. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":5781,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"googlesitekit_rrm_CAowu461DA:productID":"","footnotes":""},"categories":[1534],"tags":[],"class_list":["post-5758","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle-sop"],"_links":{"self":[{"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/posts\/5758","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/comments?post=5758"}],"version-history":[{"count":2,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/posts\/5758\/revisions"}],"predecessor-version":[{"id":5817,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/posts\/5758\/revisions\/5817"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/media\/5781"}],"wp:attachment":[{"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/media?parent=5758"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/categories?post=5758"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/w3buddy.com\/blog\/wp-json\/wp\/v2\/tags?post=5758"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}