## Where This Fits

This is Part 1 of the Oracle RAC 26ai installation on Linux: Grid Infrastructure and ASM — the cluster foundation every RAC database sits on. Part 2 covers the RAC database software and DBCA. You cannot skip this half. RAC databases depend entirely on Grid Infrastructure (GI), which provides Oracle Clusterware, Automatic Storage Management (ASM), the cluster's virtual IPs, and the SCAN.

One version fact to settle up front: Oracle AI Database 26ai reports its technical version as 23.26.x (for example, 23.26.1.0.0 in SQL*Plus). "26ai" is the marketing name on the 23.x code line — GI, ASM, and the database all show 23.26.x. This guide reflects a real two-node 26ai cluster on Oracle Linux 9; the paths, commands, and screen flow match what you actually encounter.

A naming change worth internalizing: starting with 26ai, the Cluster Verification Utility is renamed the Configuration Verification Utility. Same `cluvfy` / `runcluvfy` tooling, new name.

## The Layout This Guide Uses

Two nodes, rac1 and rac2, on Oracle Linux 9. A single OS user, oracle, owns both the Grid home and the database home — a common and fully supported arrangement, using separate environment files to switch between the ASM (+ASM) and database contexts. The homes:

```text
Grid home     /u01/app/grid/26ai/grid_1     (ORACLE_SID +ASM1 / +ASM2)
Database home /u01/app/oracle/26ai/db_1     (ORACLE_SID raccdb1 / raccdb2)
```

Networking uses three layers per node — public, private interconnect, and VIP — plus a three-address SCAN.

## Step 1: Prepare the First Node

Start with one node built to spec: Oracle Linux 8 or 9, at least 8 GB RAM for production (labs often run less), 8 GB swap, and a roomy /u01 (50 GB+). Confirm basic health and internet access, then install the Oracle preinstall RPM, which configures kernel parameters, shell limits, and the base users and groups in one move:

```bash
dnf -y install oracle-ai-database-preinstall-26ai
```

Note the exact package name for 26ai: `oracle-ai-database-preinstall-26ai` (the "ai" is part of the name now). This RPM creates the oracle user and the core groups (oinstall, dba, and others) automatically.

## Step 2: Add the ASM Groups and Set the Oracle Password

The preinstall RPM creates the standard groups, but you must add the ASM-specific groups and put oracle into them, then set the password:

```bash
groupadd -g 54331 asmadmin
groupadd -g 54332 asmdba
groupadd -g 54333 asmoper
usermod -a -G asmadmin,asmdba,asmoper oracle
passwd oracle
```

Use identical group IDs on both nodes. The asmdba group is what the ASM disk devices will be owned by, so it matters that oracle is a member on every node.

## Step 3: Create the Home Directories

Create the Grid and database home paths and hand ownership to oracle:oinstall:

```bash
mkdir -p /u01/app/grid/26ai/grid_1
mkdir -p /u01/grid                       # ORACLE_BASE for the grid/ASM side
mkdir -p /u01/app/oracle/26ai/db_1
chown -R oracle:oinstall /u01
chmod -R 775 /u01
```

## Step 4: Relax SELinux and Disable the Firewall

For the install, set SELinux to permissive and stop the firewall (in production you configure the firewall for the RAC ports rather than disabling it):

```bash
# /etc/selinux/config — change SELINUX=enforcing to permissive
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

systemctl stop firewalld
systemctl disable firewalld
```

## Step 5: Configure /etc/hosts

Add the public, VIP, private, and SCAN entries. In a lab without DNS you can place the SCAN's three addresses in /etc/hosts; in production the SCAN should resolve through DNS round-robin instead (all three addresses under one name), because /etc/hosts can only really serve one address per lookup.

```text
# Public
192.168.80.11  rac1.example.com  rac1
192.168.80.12  rac2.example.com  rac2
# Virtual (VIP)
192.168.80.21  rac1-vip.example.com  rac1-vip
192.168.80.22  rac2-vip.example.com  rac2-vip
# SCAN (three addresses)
192.168.80.31  rac-scan.example.com  rac-scan
192.168.80.32  rac-scan.example.com  rac-scan
192.168.80.33  rac-scan.example.com  rac-scan
# Private interconnect (separate subnet)
192.168.10.11  rac1-priv.example.com  rac1-priv
192.168.10.12  rac2-priv.example.com  rac2-priv
```

The private interconnect must live on its own subnet with a dedicated NIC — cache fusion traffic is latency-sensitive and should never share the public network.

## Step 6: Create the Environment Files

As oracle, create two environment files so you can switch cleanly between the ASM (grid) and database contexts. The grid file points ORACLE_SID at the ASM instance (+ASM1 on node1, +ASM2 on node2) and ORACLE_HOME at the Grid home:

```bash
# ~/.grid.env  (node1 shown; use +ASM2 on node2)
export ORACLE_SID=+ASM1
export ORACLE_BASE=/u01/grid
export ORACLE_HOME=/u01/app/grid/26ai/grid_1
export PATH=$ORACLE_HOME/bin:$PATH

# ~/.db.env  (node1 shown; use raccdb2 on node2)
export ORACLE_SID=raccdb1
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/26ai/db_1
export PATH=$ORACLE_HOME/bin:$PATH
```

Source whichever one matches the task at hand (`. ~/.grid.env` before running ASM/clusterware tools).

## Step 7: Build the Second Node

The fastest way to get an identical second node is to configure networking (two additional NICs — public and private — beyond the management interface), then clone the VM. After cloning, on rac2: fix the hostname, set its public and private IPs, and adjust the environment files to +ASM2 and raccdb2. Verify both nodes can reach each other on both the public and private names before going further:

```bash
ping -c 3 rac2          # from rac1
ping -c 3 rac2-priv     # from rac1
ping -c 3 rac1          # from rac2
ping -c 3 rac1-priv     # from rac2
```

## Step 8: Present and Partition Shared Storage

ASM needs shared disks visible to both nodes. In a virtual lab this is a pre-allocated virtual disk marked shareable and attached to both VMs; on physical hardware it is SAN/iSCSI LUNs presented identically to each node. With one 80 GB shared disk, partition it (on one node only) into the pieces you need — for example a large DATA partition, a medium FRA/RECO partition, and a small CRS (OCR/voting) partition:

```bash
fdisk /dev/sdb
# n -> primary -> +45G  (DATA)
# n -> primary -> +25G  (FRA)
# n -> primary -> (rest, ~10G)  (CRS)
# w to write
```

Both nodes then see /dev/sdb1, /dev/sdb2, /dev/sdb3.

## Step 9: Give the ASM Disks Stable Names with udev

Raw device names (/dev/sdb1) are not guaranteed stable across reboots and won't have the right ownership for ASM. On Oracle Linux 8/9, udev rules are the common, built-in way to fix both — they pin a persistent symlink, owner, and permissions to each partition. (ASM Filter Driver is the other supported option; udev is simpler for most environments.)

First get a unique identifier for each partition — the partition UUID is reliable when the disk's serial is shared across partitions:

```bash
udevadm info --query=all --name=/dev/sdb1 | grep PART_ENTRY_UUID
udevadm info --query=all --name=/dev/sdb2 | grep PART_ENTRY_UUID
udevadm info --query=all --name=/dev/sdb3 | grep PART_ENTRY_UUID
```

Then write a rules file keyed on those UUIDs, owned by oracle:asmdba, mode 0660:

```text
# /etc/udev/rules.d/99-oracle-asm.rules
KERNEL=="sd*", ENV{ID_PART_ENTRY_UUID}=="<uuid-1>", SYMLINK+="asm-data1", OWNER="oracle", GROUP="asmdba", MODE="0660"
KERNEL=="sd*", ENV{ID_PART_ENTRY_UUID}=="<uuid-2>", SYMLINK+="asm-fra1",  OWNER="oracle", GROUP="asmdba", MODE="0660"
KERNEL=="sd*", ENV{ID_PART_ENTRY_UUID}=="<uuid-3>", SYMLINK+="asm-crs1",  OWNER="oracle", GROUP="asmdba", MODE="0660"
```

Copy the same rules file to the second node, then reload and trigger udev on both:

```bash
udevadm control --reload-rules
udevadm trigger
ls -l /dev/asm-*        # should show asm-data1, asm-fra1, asm-crs1
ls -l /dev/sdb[123]     # should show owner oracle, group asmdba, mode brw-rw----
```

Getting this ownership right on both nodes is the single most common thing to check when ASM disks later fail to appear in the installer.

## Step 10: Set Up Passwordless SSH

Grid Infrastructure needs passwordless SSH between the nodes for the oracle user. Oracle ships a helper script for exactly this inside the (already-extracted) Grid home — cleaner than wiring keys by hand:

```bash
# after extracting the Grid image (Step 11), as oracle:
cd $ORACLE_HOME/oui/prov/resources/scripts
./sshUserSetup.sh -user oracle -hosts "rac1 rac2" -noPromptPassphrase -confirm -advanced
```

The script sets up and then verifies equivalence in every direction (node-to-node and node-to-self), running `date` over SSH on each host — you should see only the date returned, never a password prompt. Confirm manually too: `ssh rac2` from rac1 and `ssh rac1` from rac2 should log in without a password.

## Step 11: Extract the Grid Infrastructure Image

Grid Infrastructure ships as an image you unzip directly into the Grid home (there is no separate "install from staging" step since 18c). As oracle, on node1:

```bash
unzip /home/oracle/software/LINUX.X64_2326100_grid_home.zip -d /u01/app/grid/26ai/grid_1
```

After extraction the home contains gridSetup.sh, runcluvfy.sh/runcluvfy.pl, and the bin tools. The installer propagates the software to node2 during setup.

## Step 12: Run Configuration Verification (Pre-Check)

Before launching the installer, run the Configuration Verification Utility to catch prerequisite gaps. Both a shell and a Perl form exist; the Perl script may need execute permission first:

```bash
. ~/.grid.env
cd $ORACLE_HOME/bin
chmod +x runcluvfy.pl
./runcluvfy.pl stage -pre crsinst -n rac1,rac2 -verbose
```

Read every FAILED. On a lab you can knowingly ignore two of them — the physical memory check (if you're under 8 GB deliberately) and resolv.conf integrity (if you're using /etc/hosts instead of DNS). Everything else should be fixed. The two you will almost always have to address are:

- avahi-daemon running (PRVG-1359/1360) — it hijacks interconnect multicast: `systemctl stop avahi-daemon && systemctl disable avahi-daemon` on both nodes
- policycoreutils version (PRVF-7533) — update it: `dnf install -y policycoreutils policycoreutils-python-utils` on both nodes

Re-run the pre-check until only the knowingly-ignored items remain.

## Step 13: Launch gridSetup and Configure the Cluster

From the Grid home, start the installer:

```bash
. ~/.grid.env
cd $ORACLE_HOME
./gridSetup.sh
```

Work through the wizard:

- Configuration Option -> "Configure Oracle Grid Infrastructure for a New Cluster"
- Cluster Type -> "Configure an Oracle Standalone Cluster," and select "Configure Cluster to Manage Oracle RAC databases"
- Cluster / SCAN -> enter the cluster name, SCAN name, and SCAN port
- Cluster Nodes -> add the second node (public + VIP hostnames), then use SSH Connectivity with the oracle user/password and Test to confirm equivalence
- Network Interface Usage -> mark the public interface Public, the private interface "ASM & Private" (interconnect), and leave the management interface "Do Not Use"
- Storage -> "Use Oracle Flex ASM for storage"

## Step 14: Create the OCR/Voting Disk Group in the Installer

Still in the wizard, create the first ASM disk group — the one holding the OCR and voting files:

- Disk group name CRS, redundancy External in a single-disk lab (use Normal or High in production, which needs three or five failure groups for voting quorum)
- Select the small CRS disk (/dev/sdb3 / asm-crs1) — it appears if the udev ownership from Step 9 is correct
- Set the ASM SYS password
- Enable Automatic Self Correction, and skip the Intelligent Data Placement / GIMR options for a standard build

Provide the OS groups (ASM admin/DBA/oper), the Grid base (/u01/grid), and the inventory location, then choose to run the root scripts manually when prompted. Let it run the prerequisite checks; you can Ignore the knowingly-accepted lab items, then Install.

## Step 15: Run the Root Scripts (First Node, Then Second)

The installer pauses for two root scripts on each node. The ordering is strict: node1 first, wait for it to finish, then node2.

```bash
# node1, as root — run and WAIT for completion
/u01/oraInventory/orainstRoot.sh
/u01/app/grid/26ai/grid_1/root.sh
```

On node1, root.sh runs an 18-step sequence (rootcrs.pl) that validates the environment, configures the Oracle Local Registry and OHASD, adds the voting disk to the CRS disk group, installs the Autonomous Health Framework, and starts the Clusterware stack — it takes several minutes and ends with "Configure Oracle Grid Infrastructure for a Cluster … succeeded." Only then run node2:

```bash
# node2, as root — only after node1 finished
/u01/oraInventory/orainstRoot.sh
/u01/app/grid/26ai/grid_1/root.sh
```

Node2's run explicitly waits on node1's progress (you'll see it pause at "awaiting the progress of root script on the installer node") before completing its own steps.

## Step 16: Verify Clusterware and ASM

Once both root scripts finish and the installer completes, confirm the cluster is healthy:

```bash
. ~/.grid.env
olsnodes                          # both nodes listed
ps -ef | grep pmon                # asm_pmon_+ASM1 / +ASM2 running
crsctl check crs                  # OHAS, CRS, CSS, EVM all online
crsctl check has
crsctl stat res -t                # every resource ONLINE
```

You should see the ASM instances, the local and SCAN listeners, the VIPs, and the CRS disk group all ONLINE across both nodes. Anything OFFLINE or INTERMEDIATE means a half-formed cluster — diagnose it before layering the database on top.

## Step 17: Create the DATA and RECO Disk Groups

The CRS disk group exists from the install; create DATA and FRA/RECO now with ASMCA (or SQL*Plus as sysasm). ASMCA's GUI lets you pick the remaining disks and set redundancy per group:

```bash
. ~/.grid.env
asmca        # create DATA (from asm-data1) and FRA (from asm-fra1)
```

Confirm all three disk groups are mounted and sized as expected:

```sql
sqlplus / as sysasm
SQL> SELECT name, state, total_mb/1024 total_gb, free_mb/1024 free_gb
     FROM v$asm_diskgroup ORDER BY name;
```

You should see CRS, DATA, and FRA all MOUNTED, visible from both ASM instances. This is exactly what Part 2 needs: a running cluster with healthy ASM disk groups for the database files and recovery area.

## Common GI/ASM Failures You Will Actually Hit

**ASM disks don't appear in the installer** — the udev ownership or symlinks didn't take on one node. Recheck `ls -l /dev/sdb[123]` on both nodes for oracle:asmdba and mode 0660, and confirm the rules file and `udevadm trigger` ran everywhere.

**avahi flagged by Configuration Verification (PRVG-1359/1360)** — the avahi daemon is still running; stop and disable it on both nodes and re-run the pre-check.

**policycoreutils version failure (PRVF-7533)** — the installed package predates the required version; `dnf install -y policycoreutils policycoreutils-python-utils` on both nodes.

**SCAN / resolv.conf failures (PRVG-10048)** — expected and ignorable in a /etc/hosts-only lab; in production it means DNS isn't resolving the SCAN's three addresses, which must be fixed.

**root.sh on node1 fails mid-sequence (CRS-41xx)** — almost always the voting disk not being visible (ASM disk ownership) or the private interconnect not reachable between nodes. Check the rootcrs log under the Grid home and confirm the CRS disk and private pings.

**root.sh order** — never run node2's root.sh until node1's has fully completed; node2 depends on the cluster configuration node1 creates.

## Next: Part 2 — The RAC Database

With Grid Infrastructure and ASM installed and verified — Clusterware online on both nodes, ASM serving CRS/DATA/FRA — the foundation is done. Part 2 installs the Oracle RAC 26ai database software and creates the clustered, multitenant database with DBCA, then validates that the cluster actually fails over. The hard, detail-heavy part is behind you: a healthy GI/ASM install is the bulk of the work in standing up a RAC cluster.
