Search notes:

Installing Oracle 21c in a Windows Subsystem for Linux guest

Install Oracle Linux 8.7

Check if Oracle 8.7 is available in the Microsoft Store …
PS:> wsl -l --online
… and install it:
PS:> wsl --install OracleLinux_8_7

Update 2025-07-14

When I tried to install Oracle 21c on Windows 11 in July 2025, I found an Oracle 8.10 distribution with wsl -l -o.

Check WSL version

I am running WSL version 2:
PS:> [Console]::OutputEncoding = [Text.Encoding]::Unicode
PS:>  wsl -l -v | select-string 'VERSION|OracleLinux_8_7'

  NAME               STATE           VERSION
  OracleLinux_8_7    Running         2
See here why I set [Console]::OutputEncoding before running select-string.

Login to new WSL guest as root:

PS:> wsl -d OracleLinux_8_7 -u root
Check some files (just for the fun of it):
# cat /etc/oracle-release
Oracle Linux Server release 8.7

# cat /etc/redhat-release
Red Hat Enterprise Linux release 8.7 (Ootpa)

# cat /etc/os-release
NAME="Oracle Linux Server"
VERSION="8.7"
ID="ol"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="8.7"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Oracle Linux Server 8.7"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:oracle:linux:8:7:server"
HOME_URL="https://linux.oracle.com/"
BUG_REPORT_URL="https://bugzilla.oracle.com/"

ORACLE_BUGZILLA_PRODUCT="Oracle Linux 8"
ORACLE_BUGZILLA_PRODUCT_VERSION=8.7
ORACLE_SUPPORT_PRODUCT="Oracle Linux"
ORACLE_SUPPORT_PRODUCT_VERSION=8.7

Test nameserver lookup

# ping download.oracle.com
ping: download.oracle.com: Name or service not known

# ping yum.oracle.com
ping: yum.oracle.com: Name or service not known
I cannot look up internet domains, proabably because WSL generates /etc/resolv.conf.
This behvavior can be configured in /etc/wsl.conf
I have no such file …
# ls /etc/wsl.conf
ls: cannot access '/etc/wsl.conf': No such file or directory
… thus I can safely create it. I use this occasion to also set two settings of the [interop] section:
# echo '[network]
# generateHosts      = false
  generateResolvConf = false

[interop]
  enabled           = false
  appendWindowsPath = false' > /etc/wsl.conf

Restart the guest and create /etc/resolv.conf

# exit
PS:> wsl --shutdown
PS:> wsl -d OracleLinux_8_7 -u root

# echo 'nameserver 8.8.8.8' > /etc/resolv.conf

# ping yum.oracle.com
PING e10877.dscd.akamaiedge.net (23.32.113.146) 56(84) bytes of data.
64 bytes from a23-32-113-146.deploy.static.akamaitechnologies.com (23.32.113.146): icmp_seq=1 ttl=58 time=77.9 ms
^C

# ping download.oracle.com
PING e2875.d.akamaiedge.net (23.32.112.105) 56(84) bytes of data.
64 bytes from a23-32-112-105.deploy.static.akamaitechnologies.com (23.32.112.105): icmp_seq=1 ttl=58 time=78.5 ms
^C

Install prerequisites

# dnf install -y oracle-database-preinstall-21c
This preinstallatin package
Check kernel parameters (I believe these were set with the prerequisite package
# grep -vPh '#|;' /etc/sysctl.conf /etc/sysctl.d/* | sort -u

fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.panic_on_oops = 1
kernel.sem = 250 32000 100 128
kernel.shmall = 1073741824
kernel.shmmax = 4398046511104
kernel.shmmni = 4096
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.ip_local_port_range = 9000 65500
After the installation, see also the stat name GLOBAL_SEND_SIZE_MAX (select * from v$osstat where comments like '%net.core.wmem_max%';).
Check other settings as well:
# grep '^oracle' /etc/security/limits.d/oracle-database-preinstall-21c.conf
oracle   soft   nofile    1024
oracle   hard   nofile    65536
oracle   soft   nproc    16384
oracle   hard   nproc    16384
oracle   soft   stack    10240
oracle   hard   stack    32768
oracle   hard   memlock    134217728
oracle   soft   memlock    134217728
oracle   soft   data    unlimited
oracle   hard   data    unlimited

Change oracle's password

The preinstallation has also created the oracle user.
Let's change his password:
# echo 'oracle:tercesElCaro'  | chpasswd

Create some directories

# mkdir -p /u01/app/oracle/product/21.0.0/dbhome_1          # /u01/app/oracle is $ORACLE_BASE
# mkdir -p /u02/oradata
# chown -R oracle:oinstall /u01 /u02
# chmod -R 775 /u01 /u02

Become oracle

The next steps need to be performed as user oracle:
# su - oracle

Create scripts for environment variables etc

$ mkdir $HOME/scripts
$ cat > $HOME/scripts/setEnv.sh <<EOF
# Oracle Settings
export TMP=/tmp
export TMPDIR=\$TMP
# -
export ORACLE_HOSTNAME=ol8-21.localdomain
export ORACLE_UNQNAME=cdb1
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=\$ORACLE_BASE/product/21.0.0/dbhome_1
export ORA_INVENTORY=/u01/app/oraInventory
export ORACLE_SID=cdb1
export PDB_NAME=pdb1
export DATA_DIR=/u02/oradata
# -
# export PATH=/usr/sbin:/usr/local/bin:\$PATH
export PATH=\$ORACLE_HOME/bin:\$PATH
# -
export LD_LIBRARY_PATH=\$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=\$ORACLE_HOME/jlib:\$ORACLE_HOME/rdbms/jlib
EOF
$ cat > $HOME/scripts/start_all.sh <<EOF
#!/bin/bash
. /home/oracle/scripts/setEnv.sh

export ORAENV_ASK=NO
. oraenv
export ORAENV_ASK=YES

dbstart \$ORACLE_HOME
EOF
cat > $HOME/scripts/stop_all.sh <<EOF
#!/bin/bash
. /home/oracle/scripts/setEnv.sh

export ORAENV_ASK=NO
. oraenv
export ORAENV_ASK=YES

dbshut \$ORACLE_HOME
EOF
chown -R oracle:oinstall /home/oracle/scripts
chmod u+x /home/oracle/scripts/*.sh
Add setEnv.sh to ~/.bash_profile:
echo '. $HOME/scripts/setEnv.sh' >> ~/.bash_profile

Download Oracle binaries

Find LINUX.X64_213000_db_home.zip at https://www.oracle.com/database/technologies/oracle21c-linux-downloads.html
Export $ORACLE_HOME because it is not set yet (this is used below in the cd command).
$ . $HOME/scripts/setEnv.sh
$ wget https://download.oracle.com/otn/linux/oracle21c/LINUX.X64_213000_db_home.zip?AuthParam=<REPLACE HERE> -O /tmp/LINUX.X64_213000_db_home.zip

$ cd $ORACLE_HOME

$ unzip -oq /tmp/LINUX.X64_213000_db_home.zip

Run installation

$ ./runInstaller -ignorePrereq -waitforcompletion -silent                      \
    -responseFile ${ORACLE_HOME}/install/response/db_install.rsp               \
    oracle.install.option=INSTALL_DB_SWONLY                                    \
    ORACLE_HOSTNAME=${ORACLE_HOSTNAME}                                         \
    UNIX_GROUP_NAME=oinstall                                                   \
    INVENTORY_LOCATION=${ORA_INVENTORY}                                        \
    SELECTED_LANGUAGES=en,en_GB                                                \
    ORACLE_HOME=${ORACLE_HOME}                                                 \
    ORACLE_BASE=${ORACLE_BASE}                                                 \
    oracle.install.db.InstallEdition=EE                                        \
    oracle.install.db.OSDBA_GROUP=dba                                          \
    oracle.install.db.OSBACKUPDBA_GROUP=dba                                    \
    oracle.install.db.OSDGDBA_GROUP=dba                                        \
    oracle.install.db.OSKMDBA_GROUP=dba                                        \
    oracle.install.db.OSRACDBA_GROUP=dba                                       \
    SECURITY_UPDATES_VIA_MYORACLESUPPORT=false                                 \
    DECLINE_SECURITY_UPDATES=true
Output:
[WARNING] [INS-13014] Target environment does not meet some optional requirements.
   CAUSE: Some of the optional prerequisites are not met. See logs for details. installActions2024-12-27_03-04-11PM.log
   ACTION: Identify the list of failed prerequisite checks from the log: installActions2024-12-27_03-04-11PM.log. Then either from the log file or from installation manual find the appropriate configuration to meet the prerequisites and fix it manually.
The response file for this session can be found at:
 /u01/app/oracle/product/21.0.0/dbhome_1/install/response/db_2024-12-27_03-04-11PM.rsp

You can find the log of this install session at:
 /tmp/InstallActions2024-12-27_03-04-11PM/installActions2024-12-27_03-04-11PM.log


As a root user, execute the following script(s):
        1. /u01/app/oraInventory/orainstRoot.sh
        2. /u01/app/oracle/product/21.0.0/dbhome_1/root.sh


Successfully Setup Software with warning(s).
Moved the install session logs to:
 /u01/app/oraInventory/logs/InstallActions2024-12-27_03-04-11PM

Become root again

$ exit
Run the first mentioned script (orainstRoot.sh):
# /u01/app/oraInventory/orainstRoot.sh
The execution of the script is complete.
Run the second mentioned script:
# /u01/app/oracle/product/21.0.0/dbhome_1/root.sh
Check /u01/app/oracle/product/21.0.0/dbhome_1/install/root_LIGS10019_2024-12-27_15-57-03-373919026.log for the output of root script

Determine host's IP Address

In order to be able to connect to the new database from the WSL host, I need to determine the guest's IP address. This requires the hostname executable which is not:
# dnf install -y hostname

Start listnener

I change to oracle again:
# su - oracle
$ lsnrctl start

Create a database

$ dbca -silent -createDatabase                                                 \
     -templateName General_Purpose.dbc                                         \
     -gdbname                   ${ORACLE_SID}                                  \
     -sid                       ${ORACLE_SID} -responseFile NO_VALUE           \
     -characterSet              AL32UTF8                                       \
     -sysPassword               SysPassword1                                   \
     -systemPassword            SysPassword1                                   \
     -createAsContainerDatabase true                                           \
     -numberOfPDBs              1                                              \
     -pdbName                   ${PDB_NAME}                                    \
     -pdbAdminPassword          PdbPassword1                                   \
     -databaseType              MULTIPURPOSE                                   \
     -memoryMgmtType            auto_sga                                       \
     -totalMemory               2000                                           \
     -storageType               FS                                             \
     -datafileDestination      "${DATA_DIR}"                                   \
     -redoLogFileSize           50                                             \
     -emConfiguration            NONE                                          \
     -ignorePreReqs
As per MOS Note 235965.1, the following warning can be safeily ignored:
[WARNING] [DBT-11217] Unable to check available shared memory on specified node(s) ([null]).

Connect from host

hostname -I determines a WSL guest's' IP address:
$ hostname -I
172.25.11.143
Now, with this IP address, I can connect from the WSL host (if it has Oracle client installed):
PS:> sqlplus sys/SysPassword1@172.25.11.143:1521/cdb1 as sysdba

/etc/oratab

dbc1 does not automatically start:
$ grep -v '^\s*$\|^\s*#' /etc/oratab
cdb1:/u01/app/oracle/product/21.0.0/dbhome_1:N
Change it (as root (to prevent in place error )):
# sed -i '/^cdb1:/s/N *$/Y/' /etc/oratab

Make sure PDB starts also when the instance starts

I don't want to execute alter pluggble database pdb1 open every time when the instance starts again (run as oracle):
$ sqlplus / as sysdba <<EOF
alter pluggable database ${PDB_NAME} save state;
exit
EOF
This change should be reflected in dba_pdb_saved_states.

TODO

Enable Oracle Managed Files (OMF) … (run as oracle):
$ sqlplus / as sysdba <<EOF
alter system set db_create_file_dest='${DATA_DIR}';
EOF

Shutdown, restart

PS:> wsl --shutdown

PS:> sqlplus sys/SysPassword1@172.25.11.143:1521/cdb1 as sysdba
ERROR:
ORA-12170: TNS:Connect timeout occurred
PS:> wsl -d OracleLinux_8_7 -u oracle

... use script to start database

See also

Oracle: Create a database within a shell

Index

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php:78 Stack trace: #0 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(78): PDOStatement->execute(Array) #1 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(30): insert_webrequest_('/notes/developm...', 1758210296, '216.73.216.150', 'Mozilla/5.0 App...', NULL) #2 /home/httpd/vhosts/renenyffenegger.ch/httpsdocs/notes/development/databases/Oracle/adminstration/installation/WSL/21c(446): insert_webrequest() #3 {main} thrown in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php on line 78