Introduction
Oracle Database True Cache is an in-memory, read-only cache designed to reduce latency and offload read activity from the primary database. It’s comparable to an Active Data Guard standby instance, but it runs mostly in memory.
This feature debuted in Oracle Database 23ai, which has since been rebranded as Oracle AI Database 26ai.
There are several free ways to try this release of Oracle Database and its features, for instance:
• Oracle LiveLabs
• OCI Free Tier trial credits
• The Oracle Database 23ai Free VirtualBox Appliance
In this blog, we’ll walk through a simple True Cache setup using two local VirtualBox VMs. The goal is not deep architecture analysis, but rather:
• to introduce practically what True Cache is
• to show one free, hands-on way to try Oracle AI Database 26ai
We will build two Oracle Linux VMs, install Oracle AI Database 26 on them, create an Oracle Database on the first VM, and its True Cache related instance on the second.
Let’s see how it goes :
1. Build the VirtualBox VMs
1. Download an Oracle Linux Full ISO from: https://yum.oracle.com/oracle-linux-isos.html
In this example, we use the latest Oracle Linux 9 update:
OracleLinux-R9-U6-x86_64-dvd.iso
2. Create a new VM in VirtualBox. Choose the correct OS type and give the VM a name:
3. Assign resources (memory, CPU, disk), then click Finish:
4. Before booting the VM, open Settings > Storage and attach the Oracle Linux Full ISO to the Optical Drive:
5. Start the VM and install Oracle Linux. The installation is standard — just make sure the network interface is connected.
6. After the OS is installed on the first VM, clone it. We’ll use the clone as the second machine (one will run the primary database, the other will run True Cache).
7. Update hostnames and /etc/hosts on both machines so they can resolve each other. Both VMs are attached to a Bridged Adapter in VirtualBox so they’re on the same LAN and can communicate.
-- Machine 1, For the Primary Database [root@orahost1 ~]# hostname orahost1 [root@orahost1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.20.10.3 orahost1.localdomain orahost1 172.20.10.4 orahost2.localdomain orahost2
-- Machine 2, For the True Cache Instance [root@orahost2 ~]# hostname orahost2 [root@orahost1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.20.10.3 orahost1.localdomain orahost1 172.20.10.4 orahost2.localdomain orahost2
And at last, let’s make sure the 1521 port would be open for the SQL *Net communication :
-- (TODO on both machines) [root@orahost1 ~]# firewall-cmd --zone=public --add-port=1521/tcp --permanent success [root@orahost1 ~]# firewall-cmd --reload success [root@orahost1 ~]# firewall-cmd --zone=public --list-ports 1521/tcp
2- Installing Oracle AI Database 26 binaries
Reference : https://www.oracle.com/database/free/get-started/ (Choose the “Oracle Database Free Installation Guide” corresponding to your linux version)
We begin by installing the preinstall package, which will take of all the pre-installation tasks, including the creation of the needed users and groups
-- TODO on both VMs : dnf -y install oracle-ai-database-preinstall-26ai [root@orahost1 ~]# dnf -y install oracle-ai-database-preinstall-26ai Last metadata expiration check: 0:19:59 ago on Mon 27 Oct 2025 01:11:08 PM CET. Dependencies resolved. ============================================================================================================================================================================================= Package Architecture Version Repository Size ============================================================================================================================================================================================= Installing: oracle-ai-database-preinstall-26ai x86_64 1.0-1.el8 ol8_appstream 29 k Installing dependencies: compat-openssl10 x86_64 1:1.0.2o-4.el8_10.1 ol8_appstream 1.1 M glibc-devel x86_64 2.28-251.0.2.el8 ol8_baseos_latest 89 k ksh x86_64 20120801-269.0.1.el8_10 ol8_appstream 924 k libxcrypt-devel x86_64 4.1.1-6.el8 ol8_baseos_latest 25 k lm_sensors-libs x86_64 3.4.0-23.20180522git70f7e08.el8 ol8_baseos_latest 59 k make x86_64 1:4.2.1-11.el8 ol8_baseos_latest 498 k sysstat x86_64 11.7.3-13.0.2.el8_10 ol8_appstream 427 k Transaction Summary ============================================================================================================================================================================================= Install 8 Packages Total download size: 3.1 M Installed size: 9.3 M Downloading Packages: (1/8): libxcrypt-devel-4.1.1-6.el8.x86_64.rpm 37 kB/s | 25 kB 00:00 (2/8): lm_sensors-libs-3.4.0-23.20180522git70f7e08.el8.x86_64.rpm 81 kB/s | 59 kB 00:00 (3/8): glibc-devel-2.28-251.0.2.el8.x86_64.rpm 118 kB/s | 89 kB 00:00 (4/8): make-4.2.1-11.el8.x86_64.rpm 1.6 MB/s | 498 kB 00:00 (5/8): oracle-ai-database-preinstall-26ai-1.0-1.el8.x86_64.rpm 363 kB/s | 29 kB 00:00 (6/8): ksh-20120801-269.0.1.el8_10.x86_64.rpm 2.6 MB/s | 924 kB 00:00 (7/8): sysstat-11.7.3-13.0.2.el8_10.x86_64.rpm 2.4 MB/s | 427 kB 00:00 (8/8): compat-openssl10-1.0.2o-4.el8_10.1.x86_64.rpm 2.2 MB/s | 1.1 MB 00:00 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 2.5 MB/s | 3.1 MB 00:01 Oracle Linux 8 BaseOS Latest (x86_64) 2.8 MB/s | 3.1 kB 00:00 Importing GPG key 0xAD986DA3: Userid : "Oracle OSS group (Open Source Software group) " Fingerprint: 76FD 3DB1 3AB6 7410 B89D B10E 8256 2EA9 AD98 6DA3 From : /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : libxcrypt-devel-4.1.1-6.el8.x86_64 1/8 Installing : glibc-devel-2.28-251.0.2.el8.x86_64 2/8 Running scriptlet: glibc-devel-2.28-251.0.2.el8.x86_64 2/8 Installing : make-1:4.2.1-11.el8.x86_64 3/8 Running scriptlet: make-1:4.2.1-11.el8.x86_64 3/8 Installing : compat-openssl10-1:1.0.2o-4.el8_10.1.x86_64 4/8 Running scriptlet: compat-openssl10-1:1.0.2o-4.el8_10.1.x86_64 4/8 Installing : ksh-20120801-269.0.1.el8_10.x86_64 5/8 Running scriptlet: ksh-20120801-269.0.1.el8_10.x86_64 5/8 Installing : lm_sensors-libs-3.4.0-23.20180522git70f7e08.el8.x86_64 6/8 Running scriptlet: lm_sensors-libs-3.4.0-23.20180522git70f7e08.el8.x86_64 6/8 Installing : sysstat-11.7.3-13.0.2.el8_10.x86_64 7/8 Running scriptlet: sysstat-11.7.3-13.0.2.el8_10.x86_64 7/8 Installing : oracle-ai-database-preinstall-26ai-1.0-1.el8.x86_64 8/8 Running scriptlet: oracle-ai-database-preinstall-26ai-1.0-1.el8.x86_64 8/8 Verifying : glibc-devel-2.28-251.0.2.el8.x86_64 1/8 Verifying : libxcrypt-devel-4.1.1-6.el8.x86_64 2/8 Verifying : lm_sensors-libs-3.4.0-23.20180522git70f7e08.el8.x86_64 3/8 Verifying : make-1:4.2.1-11.el8.x86_64 4/8 Verifying : compat-openssl10-1:1.0.2o-4.el8_10.1.x86_64 5/8 Verifying : ksh-20120801-269.0.1.el8_10.x86_64 6/8 Verifying : oracle-ai-database-preinstall-26ai-1.0-1.el8.x86_64 7/8 Verifying : sysstat-11.7.3-13.0.2.el8_10.x86_64 8/8 Installed: compat-openssl10-1:1.0.2o-4.el8_10.1.x86_64 glibc-devel-2.28-251.0.2.el8.x86_64 ksh-20120801-269.0.1.el8_10.x86_64 libxcrypt-devel-4.1.1-6.el8.x86_64 lm_sensors-libs-3.4.0-23.20180522git70f7e08.el8.x86_64 make-1:4.2.1-11.el8.x86_64 oracle-ai-database-preinstall-26ai-1.0-1.el8.x86_64 sysstat-11.7.3-13.0.2.el8_10.x86_64 Complete!
Next we download and copy the latest free Oracle AI Database 26ai rpm corresponding to the OS version.
From https://www.oracle.com/database/free/get-started/
For me, that would be : oracle-ai-database-free-26ai-23.26.0-1.el9.x86_64.rpm
-- Both Machines , dnf -y install oracle-ai-database-free-26ai-23.26.0-1.el9.x86_64.rpm [root@orahost1 software]# ls -l total 1398208 -rw-r--r--. 1 root root 1431761556 Oct 27 14:10 oracle-ai-database-free-26ai-23.26.0-1.el9.x86_64.rpm [root@orahost1 software]# dnf -y install oracle-ai-database-free-26ai-23.26.0-1.el9.x86_64.rpm Last metadata expiration check: 1:06:41 ago on Mon 27 Oct 2025 01:11:08 PM CET. Dependencies resolved. ============================================================================================================================================================================================= Package Architecture Version Repository Size ============================================================================================================================================================================================= Installing: oracle-ai-database-free-26ai x86_64 23.26.0-1 @commandline 1.3 G Transaction Summary ============================================================================================================================================================================================= Install 1 Package Total size: 1.3 G Installed size: 3.6 G Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Running scriptlet: oracle-ai-database-free-26ai-23.26.0-1.x86_64 1/1 Installing : oracle-ai-database-free-26ai-23.26.0-1.x86_64 1/1 Running scriptlet: oracle-ai-database-free-26ai-23.26.0-1.x86_64 1/1 [INFO] Executing post installation scripts... [INFO] Oracle home installed successfully and ready to be configured. To configure Oracle AI Database Free, optionally modify the parameters in '/etc/sysconfig/oracle-free-26ai.conf' and then run '/etc/init.d/oracle-free-26ai configure' as root. Verifying : oracle-ai-database-free-26ai-23.26.0-1.x86_64 1/1 Installed: oracle-ai-database-free-26ai-23.26.0-1.x86_64 Complete!
3. Create and Configure the Primary Database
On Machine 1 (the future primary database host), still as root, run the configuration script. This creates:
• a CDB with one PDB
• a local listener
-- Only on Machine 1
[root@orahost1 software]# /etc/init.d/oracle-free-26ai configure
Specify a password to be used for database accounts. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9]. Note that the same password will be used for SYS, SYSTEM and PDBADMIN accounts:
Confirm the password:
Configuring Oracle Listener.
Listener configuration succeeded.
Configuring Oracle AI Database FREE.
Enter SYS user password:
*************
Enter SYSTEM user password:
***********
Enter PDBADMIN User Password:
**************
Prepare for db operation
7% complete
Copying database files
29% complete
Creating and starting Oracle instance
30% complete
33% complete
36% complete
39% complete
43% complete
Completing Database Creation
47% complete
49% complete
50% complete
Creating Pluggable Databases
54% complete
71% complete
Executing Post Configuration Actions
93% complete
Running Custom Scripts
100% complete
Database creation complete. For details check the logfiles at:
/opt/oracle/cfgtoollogs/dbca/FREE.
Database Information:
Global Database Name:FREE
System Identifier(SID):FREE
Look at the log file "/opt/oracle/cfgtoollogs/dbca/FREE/FREE.log" for further details.
Connect to Oracle AI Database using one of the connect strings:
Pluggable database: orahost1/FREEPDB1
Multitenant container database: orahost1
Now we have:
• a multitenant FREE database
• a local listener listening on port 1521
[root@orahost1 software]# su - oracle
[oracle@orahost1 ~]$ . oraenv
ORACLE_SID = [oracle] ? FREE
The Oracle base has been set to /opt/oracle
[oracle@orahost1 ~]$ sqlplus / as sysdba
Connected to:
Oracle AI Database 26ai Free Release 23.26.0.0.0 - Develop, Learn, and Run for Free
Version 23.26.0.0.0
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 FREEPDB1 READ WRITE NO
SQL> exit
Disconnected from Oracle AI Database 26ai Free Release 23.26.0.0.0 - Develop, Learn, and Run for Free
Version 23.26.0.0.0
[oracle@orahost1 ~]$ lsnrctl status
LSNRCTL for Linux: Version 23.26.0.0.0 - Production on 27-OCT-2025 14:37:34
Copyright (c) 1991, 2025, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=orahost1.localdomain)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 23.26.0.0.0 - Production
Start Date 27-OCT-2025 14:26:40
Uptime 0 days 0 hr. 10 min. 54 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Default Service FREE
Listener Parameter File /opt/oracle/product/26ai/dbhomeFree/network/admin/listener.ora
Listener Log File /opt/oracle/diag/tnslsnr/orahost1/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=orahost1.localdomain)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "4224ed483625a7e9e063050a14accd4f" has 1 instance(s).
Instance "FREE", status READY, has 1 handler(s) for this service...
Service "FREE" has 1 instance(s).
Instance "FREE", status READY, has 1 handler(s) for this service...
Service "FREEXDB" has 1 instance(s).
Instance "FREE", status READY, has 1 handler(s) for this service...
Service "freepdb1" has 1 instance(s).
Instance "FREE", status READY, has 1 handler(s) for this service...
The command completed successfully
4. Create the True Cache Instance
Next, we create and configure the True Cache instance on Machine 2. We only need to copy the password file from the primary to the True Cache host first:
[oracle@orahost2 bin]$ ll /opt/oracle/tmp/orapwFREE -rw-r-----. 1 oracle oinstall 2048 Sep 17 16:56 /opt/oracle/tmp/orapwFREE
Then we run dbca with the -createTrueCache option:
[oracle@orahost2 bin]$ ./dbca -silent -createTrueCache -gdbName FREE -sourceDBConnectionString orahost1:1521/FREE -passwordFileFromSourceDB /opt/oracle/tmp/orapwFREE -dbUniqueName FREE_TC -sid FREE Enter Remote DB SYS user password: Session ID of the current execution is: 2 ----------------- Running Extract_password_file_from_blob_file job Completed Extract_password_file_from_blob_file job 25% complete ----------------- Running Create_static_listener job Completed Create_static_listener job 38% complete ----------------- Running Register_listener job Completed Register_listener job 50% complete ----------------- Running Extract_tde_wallet_from_blob_file job Skipping. Job is detected as not applicable. 54% complete ----------------- Running Setup_required_directories job Skipping. Job is detected as not applicable. 57% complete ----------------- Running Create_pfile job Completed Create_pfile job 61% complete ----------------- Running Start_nomount_instance job Completed Start_nomount_instance job 64% complete ----------------- Running Create_TDE_wallet job Skipping. Job is detected as not applicable. 68% complete ----------------- Running Create_truecache_instance job Completed Create_truecache_instance job 71% complete ----------------- Running Add_oratab_entry job Completed Add_oratab_entry job 75% complete ----------------- Running Reopen_wallet job Skipping. Job is detected as not applicable. 100% complete Look at the log file "/opt/oracle/cfgtoollogs/dbca/FREE_TC/FREE_TC0.log" for further details.
The instance is created. Let’s confirm its state:
SQL> select open_mode,database_role from v$database; OPEN_MODE DATABASE_ROLE -------------------- ---------------- READ ONLY WITH APPLY TRUE CACHE SQL> select name from v$database; NAME --------- FREE SQL> select db_unique_name from v$database; DB_UNIQUE_NAME ------------------------------ FREE_TC
As you can see, it looks very similar to a Data Guard standby — except there are no datafiles.
SQL> select name from v$controlfile;
NAME
--------------------------------------------------------------------------------
/opt/oracle/oradata/FREE_TC/controlfile/o1_mf_nhz3od6n_.ctl
SQL> show parameter spfile
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
spfile string /opt/oracle/product/23ai/dbhom
eFree/dbs/spfileFREE.ora
SQL> select name from v$datafile;
no rows selected
SQL> select name from v$tempfile;
NAME
--------------------------------------------------------------------------------
/opt/oracle/oradata/S_TEMP_##TC##_FREE#TC_8192_1_3_201_1
/opt/oracle/oradata/S_TEMP_##TC##_FREE#TC_8192_2_3_202_1
/opt/oracle/oradata/S_TEMP_##TC##_FREE#TC_8192_3_3_203_1
5. Configure a True Cache Application Service
Applications can use True Cache in two main ways:
Option 1: The application maintains two physical connections:
• One to the primary database
• One to the True Cache instance
Each connection uses its own database service. The app chooses the connection based on whether it needs to read or write. This works with any language and any existing client drivers.
Option 2: The application maintains one logical connection (to the primary database service). The JDBC Thin driver (starting with Oracle AI Database 26ai) automatically manages physical connections to both the primary and True Cache. This option is for Java applications.
For more details, see:
https://docs.oracle.com/en/database/oracle/oracle-database/26/odbtc/methods-connecting-true-cache.html
In this example, we’ll configure an application service for a hypothetical sales application that queries data in the FREEPDB1 PDB.
Step 1: On the primary database, create and start a service called SALES:
-- On the primary
SQL> alter session set container=FREEPDB1;
Session altered.
SQL> BEGIN
DBMS_SERVICE.CREATE_SERVICE('SALES', 'SALES');
DBMS_SERVICE.START_SERVICE('SALES');
END;
/
Now the service is visible in the primary listener:
[oracle@orahost1 ~]$ lsnrctl status | grep SALES Service "SALES" has 1 instance(s).
Step 2: From the primary host, run dbca again to configure the related True Cache service (sales_tc) on the True Cache instance:
[oracle@orahost1 ~]$ $ORACLE_HOME/bin/dbca -configureDatabase -configureTrueCacheInstanceService -sourceDB FREE -trueCacheConnectString orahost2:1521/FREE_TC -trueCacheServiceName sales_tc -serviceName sales -pdbName FREEPDB1 -silent Session ID of the current execution is: 1 ----------------- Running Initialization job Enter SYS user password: Completed Initialization job 33% complete ----------------- Running Validate_true_cache_instance_connection job Completed Validate_true_cache_instance_connection job 37% complete ----------------- Running Validate_dataguard job Skipping. Job is detected as not applicable. 41% complete ----------------- Running Validate_db_version job Completed Validate_db_version job 44% complete ----------------- Running Validate_true_cache_instance job Completed Validate_true_cache_instance job 48% complete ----------------- Running Validate_archive_log_mode job Completed Validate_archive_log_mode job 52% complete ----------------- Running Validate_pdb job Completed Validate_pdb job 56% complete ----------------- Running Validate_primary_db_service job Completed Validate_primary_db_service job 59% complete ----------------- Running Validate_true_cache_db_service job Completed Validate_true_cache_db_service job 63% complete ----------------- Running Validate_true_cache_instance_open_mode job Completed Validate_true_cache_instance_open_mode job 67% complete ----------------- Running Create_truecache_service job Completed Create_truecache_service job 73% complete ----------------- Running Add_network_entry job Completed Add_network_entry job 80% complete ----------------- Running Modify_primary_service job Completed Modify_primary_service job 87% complete ----------------- Running Start_truecache_service job Completed Start_truecache_service job 93% complete ----------------- Running Enable_service_registration job Completed Enable_service_registration job 100% complete Look at the log file "/opt/oracle/cfgtoollogs/dbca/FREE/FREE0.log" for further details.
The service has been created, we can check on the true cache machine :
[oracle@orahost2 bin]$ lsnrctl status | grep sales_tc
Service "sales_tc" has 1 instance(s).
[oracle@orahost2 bin]$ sqlplus / as sysdba
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 FREEPDB1 READ ONLY NO
SQL> alter session set container=freepdb1;
Session altered.
SQL> select name from v$active_services;
NAME
----------------------------------------------------------------
sales_tc
FREEPDB1
Conclusion
• It’s fast and cheap to build a small lab for Oracle AI Database 26ai and start testing new features on your laptop.
• True Cache is one of those features: it’s easy to set up, designed for offloading read-only workload, and included with Enterprise Edition licensing (unlike Active Data Guard which requires an extra option). It’s definitely worth evaluating for applications that mostly read and don’t or rarely need to update data.