Od
Databases AWS

Oracle Database 19c SE2 on AWS User Guide

| Product: Oracle Database 19c SE2 on AWS

Overview

This image runs Oracle Database 19c Long Term Support Standard Edition 2 on Oracle Linux 8. Oracle Database 19c is Oracle's Long Term Support release covered by Oracle Extended Support through April 2027 and is the recommended target for new Oracle Database deployments that do not yet need the 23ai feature set. Standard Edition 2 provides the core relational engine within the SE2 licensing envelope of two sockets and sixteen user threads, suitable for line of business systems, application back ends, and development databases.

The image ships with the binaries patched to the current Database Release Update applied via OPatch at build time, so the customer launches into a release that is already patched against the public CVE set covered by the Oracle DBRU cycle. A starter non container database named ORCL is preconfigured, the SQL*Plus command line client is available in the Oracle home, and the Oracle listener on port 1521 is bound to the loopback address 127.0.0.1 only, so the database is not reachable from the network until you decide to make it so. SQL Developer and JDBC clients on your workstation connect through an SSH tunnel (Step 7), and Step 7 also explains how to open port 1521 deliberately, with network encryption, if you need direct connections. The Oracle binaries and datafiles live on a dedicated 30 GiB EBS gp3 volume mounted at /opt/oracle, separate from the operating system disk, so the database tier is independently resizable. A systemd unit oracle-db.service starts the database on boot via Oracle's dbstart script, and only once first boot has completed.

The image ships with no usable credentials. On the first boot of every launched instance, a one shot service named oracle-db-19c-firstboot.service runs before the database is reachable. With no listener running, it sets a unique random 24 character password on the SYS and SYSTEM accounts, and re-keys every other password account (such as DBSNMP and the sample schemas) with a random value and leaves it locked and expired. It then starts the listener on 127.0.0.1 only, proves that each new password works and that the historic and default passwords are refused, and checks that no plaintext password reached the audit trail or the trace files. Only then does it write the passwords to /root/oracle-db-credentials.txt with mode 0600, so that only the root user can read them, followed by the ready marker /var/lib/cloudimg/oracle-db-19c-firstboot.done. oracle-db.service starts only after that marker exists. Two instances launched from the same image never share credentials.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network. Port 1521 does not need to be open: the listener is bound to 127.0.0.1 and remote tools reach it through an SSH tunnel
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Oracle Database. Select the cloudimg listing for Oracle Database 19c SE2 on Oracle Linux 8 and choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large (2 vCPUs / 8 GiB RAM) or larger. The starter database is sized for m5.large, which is the recommended baseline. On AWS, Oracle licenses Standard Edition 2 only on instances of up to 8 vCPUs, so m5.large, m5.xlarge (4 vCPUs / 16 GiB) and m5.2xlarge (8 vCPUs / 32 GiB) are within the SE2 limit; larger shapes such as m5.4xlarge (16 vCPUs) are not. On a larger instance, raise the database memory as described in Step 8. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network only. The default security group of this listing opens port 22 only: the listener is bound to 127.0.0.1, so port 1521 does not need to be open. Step 7 covers the SSH tunnel, and how to open port 1521 deliberately if you need to. Never open port 1521 to the public internet.

Leave the root volume at the default size. The image adds a second 30 GiB gp3 EBS volume at /opt/oracle automatically; that is where the Oracle home and the ORCL datafiles live.

Select Launch instance. First boot initialisation takes several minutes after the instance state becomes Running and the status checks pass, a few minutes longer than a plain database start, because the firstboot service sets and then proves every credential before the database is allowed to start. SSH can become available before first boot has finished; Step 3 shows how to tell when it is done.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg Oracle Database 19c SE2 Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 from your management network, as described above. Port 1521 stays closed.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":50,"VolumeType":"gp3"}},{"DeviceName":"/dev/sdb","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=oracle-db-19c-01}]'

The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.

Step 3: Connect over SSH and Retrieve the Credentials

Wait for the EC2 instance to reach 2/2 status checks and for first boot to complete. Connect over SSH with the key pair you selected, using the ec2-user login name:

ssh -i <your-key.pem> ec2-user@<public-ip>

Once you are on the instance, confirm that first boot has completed. The ready marker exists only after every password has been set and proven:

sudo test -f /var/lib/cloudimg/oracle-db-19c-firstboot.done && echo "first boot complete"

If the command prints nothing, first boot is still running; follow its progress with sudo journalctl -u oracle-db-19c-firstboot.service -b -f, and see If first boot fails below if it does not finish. When it has completed, read the credentials file with sudo:

sudo cat /root/oracle-db-credentials.txt

The file contains the per instance SYS and SYSTEM passwords, the Oracle SID (ORCL), and the listener address (127.0.0.1:1521). Sample contents:

# Oracle Database 19c Standard Edition 2 - per-instance credentials (cloudimg)
# Generated Sun Oct 18 15:30:00 UTC 2026 on i-0123456789abcdef0. Root-only (0600). Unique to this instance.

SYS_PASSWORD=TmKwQ8YzBnA9hSdF2pXRqLe4
SYSTEM_PASSWORD=EhYrkP1QmW9XnZA8tLpVcGu7

ORACLE_SID=ORCL
LISTENER=127.0.0.1:1521 (localhost only - use an SSH tunnel, or see the guide to open it deliberately with encryption)

Every other database account is locked and expired with a random password.
Connect: sudo su - oracle ; . ~/setEnv.sh ; sqlplus /nolog ; then CONNECT system@//localhost:1521/ORCL

Copy these values somewhere secure such as a password manager or an encrypted vault, and do not commit them to source control. Every command block in this guide that talks to Oracle begins by reading the SYSTEM password from the credentials file into a SYSPWD shell variable, so every block is self contained.

The file uses KEY=value lines. Images released before October 2026 wrote KEY= value, with a space after the equals sign; the extraction used throughout this guide handles both forms:

SYSPWD=$(sudo awk -F'= *' '/^SYSTEM_PASSWORD=/{print $2}' /root/oracle-db-credentials.txt)
test -n "$SYSPWD" && echo "SYSTEM password read (${#SYSPWD} characters)"

Every other account is locked

Only SYS and SYSTEM can log in. Every other password account in the database, including DBSNMP and the sample schemas, was given a random password that nobody knows and is locked and expired. To use one of these accounts, set your own password and unlock it as SYSDBA:

ALTER USER <name> IDENTIFIED BY "<new-strong-password>" ACCOUNT UNLOCK;

If first boot fails

First boot fails closed. If it cannot complete every step, it stops the database and the listener on purpose, writes no credentials file, and leaves /root/oracle-db-FIRSTBOOT-FAILED.txt explaining what happened. Read the notice and the service journal, then reboot once to retry; first boot runs again on every boot until it succeeds:

sudo cat /root/oracle-db-FIRSTBOOT-FAILED.txt
sudo journalctl -u oracle-db-19c-firstboot.service -b
sudo reboot

If it fails again, contact cloudimg support with the journal output.

Run the security self-test

The image includes a self-test that re-proves the security state of the instance: each password in the credentials file works and the historic and default passwords are refused, every other account is locked, the listener is bound to 127.0.0.1 only, and no listener started before the passwords were set:

sudo /usr/local/sbin/cloudimg-oracle-selftest

Each check prints a PASS line and the run ends with SELFTEST_OK. Abridged sample output:

PASS: ready marker present
PASS: no first-boot error notice
PASS: /root/oracle-db-credentials.txt is 0600 root:root
PASS: SYS@ORCL refuses a historic/default password
PASS: SYS@ORCL accepts its per-instance password
PASS: SYSTEM@ORCL refuses a historic/default password
PASS: SYSTEM@ORCL accepts its per-instance password
PASS: every other password account is locked
PASS: listener.ora binds 127.0.0.1 only
PASS: no database socket on a non-loopback address
PASS: oracle-db.service gated on the ready marker
PASS: memory fits m5.large: sga_target 2304M, pga_aggregate_target 768M
...
SELFTEST_OK

The self-test checks the instance as delivered. After you rotate a password, open port 1521 or raise the database memory as described in this guide, the matching checks report FAIL by design.

Step 4: Verify the Listener is Running

Oracle's TNS listener is the network endpoint for all client connections. Confirm it is up and serving the ORCL service:

sudo -u oracle bash -c "
    export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
    export ORACLE_SID=ORCL
    export PATH=\$ORACLE_HOME/bin:\$PATH
    export LD_LIBRARY_PATH=\$ORACLE_HOME/lib
    lsnrctl status
"

The expected response confirms the listener is bound to the loopback address 127.0.0.1 on TCP port 1521 and that the ORCL service has registered with it:

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 28-MAY-2026 15:30:00

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "ORCL" has 1 instance(s).
  Instance "ORCL", status READY, has 1 handler(s) for this service...
The command completed successfully

The kernel level confirmation that port 1521 is listening on the loopback address only. The command prints the local address of every socket listening on port 1521:

sudo ss -Hltn 'sport = :1521' | awk '{print $4}'

Returns:

127.0.0.1:1521

Step 5: Connect Locally with SQL*Plus

The simplest way to talk to the database from the instance is the SQL*Plus client that ships with the Oracle Database installation. Read the SYSTEM password from the credentials file, then connect to the ORCL service over the listener:

SYSPWD=$(sudo awk -F'= *' '/^SYSTEM_PASSWORD=/{print $2}' /root/oracle-db-credentials.txt)
sudo -u oracle bash -c "
    export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
    export ORACLE_SID=ORCL
    export PATH=\$ORACLE_HOME/bin:\$PATH
    export LD_LIBRARY_PATH=\$ORACLE_HOME/lib
    cat > /tmp/version-query.sql <<EOF
SELECT banner FROM v\\\$version WHERE banner LIKE 'Oracle%';
EXIT;
EOF
    sqlplus -S system/${SYSPWD}@localhost:1521/ORCL @/tmp/version-query.sql
    rm /tmp/version-query.sql
"

The expected response confirms the installed Oracle Database release with the applied DBRU patch level:

BANNER
--------------------------------------------------------------------------------
Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production

You can also connect interactively. Switch to the oracle OS user and run sqlplus from that shell:

sudo su - oracle
export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
export ORACLE_SID=ORCL
export PATH=$ORACLE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
sqlplus / as sysdba

In an interactive session, type EXIT; to leave SQL*Plus.

Step 6: Run a Sample Query

Create a small table, insert two rows, read them back, then drop the table. This exercise confirms that the database is writable and that the SYSTEM user has the standard DDL grants:

SYSPWD=$(sudo awk -F'= *' '/^SYSTEM_PASSWORD=/{print $2}' /root/oracle-db-credentials.txt)
sudo -u oracle bash -c "
    export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
    export ORACLE_SID=ORCL
    export PATH=\$ORACLE_HOME/bin:\$PATH
    export LD_LIBRARY_PATH=\$ORACLE_HOME/lib
    cat > /tmp/demo.sql <<EOF
CREATE TABLE demo_users (id NUMBER, name VARCHAR2(50), created_at DATE);
INSERT INTO demo_users VALUES (1, 'Alice', SYSDATE);
INSERT INTO demo_users VALUES (2, 'Bob',   SYSDATE);
COMMIT;
SELECT id, name, TO_CHAR(created_at,'YYYY-MM-DD') AS created_at FROM demo_users;
DROP TABLE demo_users;
EXIT;
EOF
    sqlplus -S system/${SYSPWD}@localhost:1521/ORCL @/tmp/demo.sql
    rm /tmp/demo.sql
"

Expected response:

Table created.

1 row created.

1 row created.

Commit complete.

        ID NAME                                               CREATED_AT
---------- -------------------------------------------------- ----------
         1 Alice                                              2026-05-28
         2 Bob                                                2026-05-28

Table dropped.

Step 7: Connect from a Remote Machine

The listener is bound to 127.0.0.1, and the default security group opens port 22 only, so the database is not reachable from the network. The recommended way to connect a client on your workstation is an SSH tunnel, which carries the Oracle traffic inside your existing SSH connection and needs no change to the instance or the security group.

Connect through an SSH tunnel

On your workstation, open a tunnel that forwards local port 1521 to the listener on the instance, and leave it running while you work:

ssh -i <your-key.pem> -N -L 1521:127.0.0.1:1521 ec2-user@<public-ip>

While the tunnel is open, localhost:1521 on your workstation reaches the database. From a host with sqlplus installed (the Oracle Instant Client tarball contains it), supply the SYSTEM password from /root/oracle-db-credentials.txt and connect using Oracle's "Easy Connect" syntax:

sqlplus system@localhost:1521/ORCL

SQL*Plus prompts for the password, which keeps it out of your shell history. The connection string localhost:1521/ORCL is equivalent to the following TNS descriptor, which you would use from an application that reads a tnsnames.ora file:

ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ORCL)
    )
  )

For JDBC, use the URL jdbc:oracle:thin:@//localhost:1521/ORCL.

Or use SQL Developer

Oracle SQL Developer is a free graphical client published by Oracle. With the SSH tunnel open, launch SQL Developer locally and create a new connection with the values below:

Setting Value
Connection Name cloudimg-oracle-19c (or any name you choose)
Authentication Default
Username SYSTEM
Password Value of SYSTEM_PASSWORD from /root/oracle-db-credentials.txt
Connection Type Basic
Role default
Hostname localhost (through the SSH tunnel)
Port 1521
Service Name ORCL

Click Test, and while the SSH tunnel is running the status bar reports Success. Click Connect to open a SQL Worksheet.

Opening port 1521 deliberately

If your applications must connect directly rather than through a tunnel, open the listener deliberately, in three steps, and only to your own network. Run these commands yourself; none of them is needed for the SSH tunnel.

1. Require Oracle native network encryption and integrity. As the oracle user, append the following to $ORACLE_HOME/network/admin/sqlnet.ora:

sudo su - oracle
export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
cat >> $ORACLE_HOME/network/admin/sqlnet.ora <<'EOF'
SQLNET.ENCRYPTION_SERVER = required
SQLNET.ENCRYPTION_TYPES_SERVER = (AES256)
SQLNET.CRYPTO_CHECKSUM_SERVER = required
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA256)
EOF

Alternatively, configure TCPS (TLS) with an Oracle wallet instead; see "Configuring Transport Layer Security Authentication" in the Oracle Database 19c Security Guide at https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/configuring-transport-layer-security-authentication.html.

2. Bind the listener to all interfaces. In $ORACLE_HOME/network/admin/listener.ora, change (HOST = 127.0.0.1) to (HOST = 0.0.0.0), then restart the listener as the oracle user. The database registers with the restarted listener within a minute:

sudo su - oracle
export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
sed -i 's/(HOST = 127.0.0.1)/(HOST = 0.0.0.0)/' $ORACLE_HOME/network/admin/listener.ora
lsnrctl stop
lsnrctl start

3. Allow TCP 1521 from your own network only. Add a security group rule for your management or application CIDR. Never use 0.0.0.0/0:

aws ec2 authorize-security-group-ingress --group-id <security-group-id> --protocol tcp --port 1521 --cidr <your-mgmt-cidr>

Clients then connect to <public-ip>:1521/ORCL (or the private IP from inside the VPC) and must also use encryption. The JDBC thin driver, and therefore SQL Developer, negotiates it automatically when the server requires it; other Oracle clients do the same with their default sqlnet.ora settings.

Instances launched from earlier images

On instances launched from images released before October 2026, the listener binds 0.0.0.0 and the old default security group opened port 1521 to the internet. To bring such an instance in line with the current image, remove that security group rule, then set the listener back to 127.0.0.1 in the same listener.ora file and restart it:

aws ec2 revoke-security-group-ingress --group-id <security-group-id> --protocol tcp --port 1521 --cidr 0.0.0.0/0

sudo su - oracle
export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
sed -i 's/(HOST = 0.0.0.0)/(HOST = 127.0.0.1)/' $ORACLE_HOME/network/admin/listener.ora
lsnrctl stop
lsnrctl start

Check that the HOST entry in listener.ora now reads 127.0.0.1, then connect through the SSH tunnel described above. If you need direct access instead, follow Opening port 1521 deliberately.

Step 8: Manage the Oracle Service

The database is started on boot by the systemd unit oracle-db.service, which delegates to Oracle's dbstart script in $ORACLE_HOME/bin. Manage the service with the standard systemctl commands:

sudo systemctl status oracle-db.service --no-pager

Returns:

oracle-db.service - Oracle Database 19c Standard Edition 2 (cloudimg) - starts only after first boot has set per-instance credentials
   Loaded: loaded (/etc/systemd/system/oracle-db.service; enabled; vendor preset: disabled)
   Active: active (running)
  Process: 14909 ExecStart=/opt/oracle/product/19.0.0/dbhome_1/bin/dbstart /opt/oracle/product/19.0.0/dbhome_1 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/oracle-db.service
           ├─ ora_pmon_ORCL
           ├─ ora_psp0_ORCL
           ├─ ora_vktm_ORCL
           ...

To stop the database and listener cleanly:

sudo systemctl stop oracle-db.service

To start them again:

sudo systemctl start oracle-db.service

There is also a one shot unit oracle-db-19c-firstboot.service whose only job is to set the per instance credentials on the very first boot. It runs before oracle-db.service, which will not start until the ready marker /var/lib/cloudimg/oracle-db-19c-firstboot.done exists. Once the marker is present, the first boot unit exits immediately on every subsequent boot.

Database memory and instance size

The starter database is sized for the recommended m5.large (8 GiB): it uses automatic shared memory management with 3072 MB in total, which gives an sga_target of about 2.3 GiB and a pga_aggregate_target of about 768 MiB, leaving room for the operating system. On m5.xlarge or a larger instance for production, raise the database memory as SYSDBA, for example:

ALTER SYSTEM SET sga_max_size=6G SCOPE=SPFILE;
ALTER SYSTEM SET sga_target=6G SCOPE=SPFILE;
ALTER SYSTEM SET pga_aggregate_target=2G SCOPE=BOTH;

Then restart the database so the new SGA size takes effect:

sudo systemctl restart oracle-db.service

Choose values that leave at least 2 GiB of the instance memory for the operating system.

Step 9: Filesystem Layout

The Oracle home and the ORCL database files live on the dedicated 30 GiB gp3 EBS volume mounted at /opt/oracle. This separation is intentional: the database tier can be resized independently of the operating system disk, and it can be snapshotted on its own for backup.

df -h /opt/oracle

Returns:

Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme1n1     30G   16G   13G  56% /opt/oracle

The main directories the image exposes:

  • /opt/oracle/product/19.0.0/dbhome_1 — the Oracle Database 19c home, owned by the oracle user
  • /opt/oracle/product/19.0.0/dbhome_1/bin — Oracle binaries, including sqlplus, lsnrctl, dbstart, dbshut
  • /opt/oracle/product/19.0.0/dbhome_1/network/admin — listener configuration (listener.ora) and TNS naming (tnsnames.ora)
  • /opt/oracle/oradata/ORCL — datafiles, control file, online redo logs for the ORCL database
  • /opt/oracle/diag — Automatic Diagnostic Repository, with the alert log under /opt/oracle/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log
  • /opt/oracle/oraInventory — the Oracle Universal Installer inventory
  • /root/oracle-db-credentials.txt — per instance SYS and SYSTEM passwords, mode 0600 root only
  • /usr/local/sbin/cloudimg-oracle-selftest — the security self-test described in Step 3

Sample listing of the datafile directory:

sudo ls -la /opt/oracle/oradata/ORCL/

Returns:

-rw-r----- 1 oracle oinstall   9748480 May 28 15:30 control01.ctl
-rw-r----- 1 oracle oinstall  52429312 May 28 15:30 redo01.log
-rw-r----- 1 oracle oinstall  52429312 May 28 15:30 redo02.log
-rw-r----- 1 oracle oinstall  52429312 May 28 15:30 redo03.log
-rw-r----- 1 oracle oinstall 765411328 May 28 15:30 sysaux01.dbf
-rw-r----- 1 oracle oinstall 943718400 May 28 15:30 system01.dbf
-rw-r----- 1 oracle oinstall  62914560 May 28 15:30 temp01.dbf
-rw-r----- 1 oracle oinstall  78651392 May 28 15:30 undotbs01.dbf
-rw-r----- 1 oracle oinstall   5251072 May 28 15:30 users01.dbf

Step 10: Server Components

Component Version Source
Oracle Database 19c Long Term Support, Standard Edition 2 (patched to current DBRU) Oracle 19c installation media + p36233263 DBRU
Oracle Linux 8 cloudimg golden base image
SQL*Plus 19c bundled in $ORACLE_HOME/bin
systemd unit oracle-db.service baked into the image
Firstboot unit oracle-db-19c-firstboot.service baked into the image

Step 11: Confirm the Applied DBRU Patch Level

This image is shipped with the current Oracle Database Release Update applied to the binaries at build time via OPatch. Confirm the applied patches with the Oracle OPatch utility:

sudo -u oracle bash -c "
    export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
    \$ORACLE_HOME/OPatch/opatch lsinventory -bugs_fixed | head -20
"

The sqlplus banner reports the patched release:

SYSPWD=$(sudo awk -F'= *' '/^SYSTEM_PASSWORD=/{print $2}' /root/oracle-db-credentials.txt)
sudo -u oracle bash -c "
    export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
    export ORACLE_SID=ORCL
    export PATH=\$ORACLE_HOME/bin:\$PATH
    export LD_LIBRARY_PATH=\$ORACLE_HOME/lib
    cat > /tmp/vfull.sql <<EOF
SET HEADING OFF FEEDBACK OFF PAGESIZE 0
SELECT VERSION_FULL FROM V\\\$INSTANCE;
EXIT;
EOF
    sqlplus -S / as sysdba @/tmp/vfull.sql
    rm /tmp/vfull.sql
"

Returns the patched release identifier, for example 19.22.0.0.0 for the DBRU applied at this image's build time.

Step 12: Rotate the SYSTEM and SYS Passwords

For a production deployment, rotate the SYSTEM and SYS passwords that the first boot service generated. Connect as SYSDBA with operating system authentication and issue ALTER USER:

sudo -u oracle bash -c "
    export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
    export ORACLE_SID=ORCL
    export PATH=\$ORACLE_HOME/bin:\$PATH
    export LD_LIBRARY_PATH=\$ORACLE_HOME/lib
    sqlplus -S / as sysdba <<EOF
ALTER USER SYSTEM IDENTIFIED BY \"<new-system-password>\";
ALTER USER SYS    IDENTIFIED BY \"<new-sys-password>\";
EXIT;
EOF
"

Store the new values in your secrets manager immediately. The file /root/oracle-db-credentials.txt is the per instance bootstrap record and should not be considered your source of truth after the first rotation.

Step 13: Tablespaces and Datafile Layout

The starter ORCL database has the standard Oracle tablespace layout: SYSTEM, SYSAUX, UNDOTBS1, USERS, and TEMP. The datafiles live under /opt/oracle/oradata/ORCL, which is on the dedicated 30 GiB gp3 EBS volume. As your workload grows, create application-specific tablespaces on the same volume and grow the volume in place.

SYSPWD=$(sudo awk -F'= *' '/^SYSTEM_PASSWORD=/{print $2}' /root/oracle-db-credentials.txt)
sudo -u oracle bash -c "
    export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
    export ORACLE_SID=ORCL
    export PATH=\$ORACLE_HOME/bin:\$PATH
    export LD_LIBRARY_PATH=\$ORACLE_HOME/lib
    cat > /tmp/tspaces.sql <<EOF
SET PAGESIZE 100 LINESIZE 200
COLUMN tablespace_name FORMAT A20
COLUMN file_name FORMAT A55
SELECT tablespace_name, ROUND(bytes/1024/1024) AS mb, file_name
FROM dba_data_files ORDER BY tablespace_name;
EXIT;
EOF
    sqlplus -S system/${SYSPWD}@localhost:1521/ORCL @/tmp/tspaces.sql
    rm /tmp/tspaces.sql
"

To add a new application tablespace with autoextend:

sudo -u oracle bash -c "
    export ORACLE_HOME=/opt/oracle/product/19.0.0/dbhome_1
    export ORACLE_SID=ORCL
    export PATH=\$ORACLE_HOME/bin:\$PATH
    export LD_LIBRARY_PATH=\$ORACLE_HOME/lib
    sqlplus -S / as sysdba <<EOF
CREATE TABLESPACE app_data
  DATAFILE '/opt/oracle/oradata/ORCL/app_data01.dbf' SIZE 1G
  AUTOEXTEND ON NEXT 256M MAXSIZE 16G;
EXIT;
EOF
"

Step 14: Backup Recommendations

Oracle Database 19c supports a range of backup strategies. For a single-instance image like this one, the two pragmatic options are filesystem snapshot of the EBS data volume and Oracle's own Recovery Manager (RMAN).

For a quick consistent backup, stop the database cleanly, snapshot the /opt/oracle EBS volume from the AWS Console or CLI, then start the database again:

sudo systemctl stop oracle-db.service
aws ec2 create-snapshot --volume-id <volume-id-of-/opt/oracle> \
  --description "oracle-db-19c $(date +%F)" \
  --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=oracle-data}]'
sudo systemctl start oracle-db.service

For a hot, point-in-time backup, configure RMAN to back up to an attached EBS volume or to S3 via an S3-compatible RMAN channel. RMAN integrates with Oracle's archive log mode and supports incremental backups. The full RMAN documentation is at the Oracle Database 19c Backup and Recovery User's Guide.

Step 15: Security Recommendations

Oracle Database 19c is the Long Term Support release covered by Oracle Extended Support through April 2027. Apply the following recommendations on a production deployment:

  • Keep port 1521 closed. The listener is bound to 127.0.0.1 and the default security group opens port 22 only; connect through an SSH tunnel. If you must open the port, follow Opening port 1521 deliberately in Step 7: require network encryption and allow only your own network. Never open the listener to the public internet.
  • Leave unused accounts locked. Every account other than SYS and SYSTEM is locked and expired with a random password; unlock only the accounts you need, with a new strong password.
  • Rotate the SYSTEM and SYS passwords using the rotation step above, and store the new values in your secrets manager.
  • Create per-application schema users with only the grants the application needs, instead of using SYSTEM for application traffic.
  • Apply the next Oracle Database Release Update when published by Oracle, by downloading the DBRU bundle from My Oracle Support and applying with OPatch and datapatch. This image is shipped with the current DBRU at build time, but Oracle publishes a new DBRU on a quarterly cadence.
  • Enable Oracle auditing if your compliance regime requires it: ALTER SYSTEM SET audit_trail=DB SCOPE=SPFILE; followed by a restart, then AUDIT statements as needed.
  • Require Oracle Native Network Encryption in sqlnet.ora (or TCPS) whenever the listener is reachable from the network, as shown in Step 7. The full set of encryption settings is documented in the Oracle Database Net Services Reference.
  • Apply OS security patches by running sudo dnf update -y on a regular maintenance schedule. Reboot the instance after a kernel update.
  • Take regular EBS snapshots of the /opt/oracle volume and store them in a separate account or Region.
  • Limit SSH access to a small management CIDR; do not leave port 22 open to 0.0.0.0/0 in production.

Screenshots

The following screenshots are taken from a running Oracle Database 19c SE2 instance launched from this image.

SQL*Plus 19c client version output confirming the Oracle Database 19c installation patched to current DBRU

Oracle TNS Listener status on port 1521 with the ORCL service registered

Sample SQL query selecting from a demo table created and dropped via sqlplus

Support

cloudimg provides 24/7/365 expert technical support for this image. Guaranteed response within 24 hours, one hour average for critical issues. Contact support@cloudimg.co.uk.

For general Oracle Database questions, performance tuning, and migration help, consult the official Oracle Database 19c documentation set at https://docs.oracle.com/en/database/oracle/oracle-database/19/index.html.

Oracle, Oracle Database, and related marks are trademarks or registered trademarks of Oracle Corporation. Use of them does not imply any affiliation with or endorsement by Oracle Corporation.