This is a guest blog by Oracle ACE Pro Deepak Vohra. Deepak is an Oracle Database 10g Administrator Certified Associate (OCA), and has published six containerization (Docker & Kubernetes) related books.

 

The Oracle Database 23c Free – Developer Release has been available free since April this year. It is a full-featured database that can be used on Oracle Linux and RHEL. If you are using Docker as your platform, or using a Linux distribution that is not listed in downloads, such as Ubuntu, you would still be able to use the new Oracle Database 23c Free with the Docker image for Oracle Database 23c Free. 

In this article we shall discuss how to use a new feature in the Oracle Database 23c Free – Developer Release that introduces the new Hybrid Read-Only mode for pluggable databases (PDBs).  The article has the following sections:

  • What is the Hybrid Read-Only Mode
  • Get the Docker Image
  • Create your first Oracle Database 23c in a Docker Container
  • Start an interactive Bash Shell
  • Start a SQL* Plus Session
  • The Database is a Container database
  • Create a new CDB Common user 
  • Create a PDB Local User
  • Connect as CDB Common User to the PDB that is in READ WRITE Mode
  • Connect as the PDB Local User
  • Change PDB Open Mode to READ ONLY
  • Set PDB Open Mode to HYBRID READ ONLY
  • Stop and start container

 

What is the Hybrid Read-Only Mode

Prior to Oracle Database 23c Free, pluggable databases (PDBs) in a multitenant container database could be opened in one of two modes : Read Write, or Read Only; the default being Read Write. Oracle Database 23c introduces a new mode called the Hybrid Read-Only mode. If the Hybrid Read-Only mode has been set, the effective open mode in a user session is different based on who the user is. The following table lists the effective open mode in a user session for PDB local user & CDB common user corresponding to the three different PDB open mode settings.

Open Mode

Effective Open Mode for PDB local user, and Application common user

Effective Open Mode for CDB common user

READ WRITE

READ WRITE

READ WRITE

READ ONLY

READ ONLY

READ ONLY

HYBRID READ ONLY

READ ONLY

READ WRITE

 

Note that in the HYBRID READ ONLY mode the effective open mode is READ WRITE for a CDB common user while it is READ ONLY for a PDB local user. Necessary read, write privileges still need to be granted to the users, CDB common user or PDB local user to be able to perform the read write operations.

What is the benefit of the HYBRID READ ONLY mode? It lets a database administrator perform maintenance and patching on pluggable databases (PDBs) while a PDB is open for read-only queries to local users. As an example,  a PDB local user PDB_LOCAL can read but not make content changes to a pluggable database PDB1 while the database is being maintained by a CDB common user C##DBA with a commonly granted DBA role.

The Hybrid Read-Only mode has been implemented by introducing some  changes, specifically:

  1. The ALTER PLUGGABLE DATABASE supports a new clause HYBRID READ ONLY
  2. The V$CONTAINER_TOPOLOGY dynamic view has a new column called IS_HYBRID_READ_ONLY

The DESCRIBE command on the dynamic view V$CONTAINER_TOPOLOGY lists the new column IS_HYBRID_READ_ONLY:

SQL> DESCRIBE V$CONTAINER_TOPOLOGY;

 Name                                                              Null?    Type

 —————————————– ——– —————————-

 INSTANCE_NUMBER                                                NUMBER

 CON_NAME                                                    VARCHAR2(128)

 OPEN_MODE                                                              VARCHAR2(10)

 CPU_COUNT                                                               NUMBER

 CON_ID                                                            NUMBER

 RESTRICTED                                                    VARCHAR2(3)

 IS_HYBRID_READ_ONLY                                          VARCHAR2(3)

In the Hybrid Read-Only mode, the open_mode column in the dynamic view V$PDBS still shows READ WRITE to CDB root user. 

Get the Docker Image

First, you need to download, or pull in containerization parlance, the Docker image for Oracle Database 23c Free edition with the following docker pull command:

sudo docker pull container-registry.oracle.com/database/free

Using default tag: latest

latest: Pulling from database/free

def8df68f6e5: Pull complete 

4f739c567988: Pull complete 

579d0ff24aa5: Pull complete 

480f5079c729: Pull complete 

Digest: sha256:73ecc82314a625122bb283e2cb3d6778899e62d9e21792da03ac4fea74c017b9

Status: Downloaded newer image for container-registry.oracle.com/database/free:latest

container-registry.oracle.com/database/free:latest

List the Docker images with the docker images command, and the downloaded image should be listed.

sudo docker images

 

REPOSITORY                                    TAG               IMAGE ID       CREATED         SIZE

container-registry.oracle.com/database/free   latest            7c64410c08d5   2 months ago    10.3GB

 

The Docker image has some environment variables pre-configured as listed in table with corresponding values:

Environment Variable

Value

ORACLE_BASE

/opt/oracle

ORACLE_HOME

 /opt/oracle/product/23c/dbhomeFree

RUN_FILE

runOracle.sh

PWD_FILE

setPassword.sh

CREATE_DB_FILE

createDB.sh

USER_SCRIPTS_FILE

runUserScripts.sh

CONF_FILE

oracle-free-23c.conf

CHECK_SPACE_FILE

checkSpace.sh

CHECK_DB_FILE

checkDBStatus.sh

SETUP_LINUX_FILE

setupLinuxEnv.sh

CONFIG_TCPS_FILE

configTcps.sh

INSTALL_DIR

/install

ORACLE_DOCKER_INSTALL

true

CHECKPOINT_FILE_EXTN

.created

ENABLE_ARCHIVELOG

false

ORACLE_SID

FREE

ORACLE_PDB

FREEPDB1

ORACLE_PWD

 

AUTO_MEM_CALCULATION

false

The environment variables may be obtained with the command  docker image inspect container-registry.oracle.com/database/free.

 

Create your first Oracle Database 23c in a Docker Container

To use the Oracle Database 23c Free, create a Docker container for it from the Docker image downloaded earlier using the following docker run command that sets a password for the new database instance:

sudo docker run –name orcl \

-p 1521:1521 \

-v /opt/oracle/oradata \

-e ORACLE_SID=FREE \

-e ORACLE_PDB=FREEPDB1 \

-e ORACLE_PWD=ORCLPWD23 \

container-registry.oracle.com/database/free

As the command output lists the Oracle Database instance FREE gets started, and becomes available for use.

Starting Oracle Net Listener.

Oracle Net Listener started.

Starting Oracle Database instance FREE.

Oracle Database instance FREE started.

The Oracle base remains unchanged with value /opt/oracle

SQL*Plus: Release 23.0.0.0.0 – Developer-Release on Wed May 31 17:01:43 2023

Version 23.2.0.0.0

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Connected to:

Oracle Database 23c Free, Release 23.0.0.0.0 – Developer-Release

Version 23.2.0.0.0

SQL> 

User altered.

SQL> 

User altered.

SQL> 

Session altered.

SQL> 

User altered.

SQL> Disconnected from Oracle Database 23c Free, Release 23.0.0.0.0 – Developer-Release

Version 23.2.0.0.0

The Oracle base remains unchanged with value /opt/oracle

#########################

DATABASE IS READY TO USE!

#########################

The following output is now a tail of the alert.log:

Completed: Pluggable database FREEPDB1 opened read write 

Completed: ALTER DATABASE OPEN

2023-05-31T17:01:45.381896+00:00

===========================================================

Dumping current patch information

===========================================================

No patches have been applied

===========================================================

2023-05-31T17:01:51.431835+00:00

FREEPDB1(3):TABLE AUDSYS.AUD$UNIFIED: ADDED INTERVAL PARTITION SYS_P411 (3257) VALUES LESS THAN (TIMESTAMP’ 2023-06-01 00:00:00′)

List the running Docker containers with the docker ps command and the newly created container  called orcl gets listed.

sudo docker ps

CONTAINER ID   IMAGE                                         COMMAND                  CREATED         STATUS                   PORTS                                       NAMES

27b0465f6cda   container-registry.oracle.com/database/free   “/bin/sh -c ‘exec $O…”   7 minutes ago   Up 5 minutes (healthy)   0.0.0.0:1521->1521/tcp, :::1521->1521/tcp   orcl

Start an interactive Bash Shell

To be able to access the database in the container run the following docker exec command to start an interactive bash shell session within the container.

sudo docker exec -it orcl sh

At the sh command prompt, any database related command may be run. First, verify the listener status with the lsnrctl status command:

sh-4.4$ lsnrctl status

LSNRCTL for Linux: Version 23.0.0.0.0 – Developer-Release on 31-MAY-2023 17:07:51

Copyright (c) 1991, 2023, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_FREE)))

STATUS of the LISTENER

————————

Alias                     LISTENER

Version                   TNSLSNR for Linux: Version 23.0.0.0.0 – Developer-Release

Start Date                31-MAY-2023 17:00:36

Uptime                    0 days 0 hr. 7 min. 18 sec

Trace Level               off

Security                  ON: Local OS Authentication

SNMP                      OFF

Default Service           FREE

Listener Parameter File   /opt/oracle/product/23c/dbhomeFree/network/admin/listener.ora

Listener Log File         /opt/oracle/diag/tnslsnr/27b0465f6cda/listener/alert/log.xml

Listening Endpoints Summary…

  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC_FOR_FREE)))

  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))

Services Summary…

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 “PLSExtProc” has 1 instance(s).

  Instance “PLSExtProc”, status UNKNOWN, has 1 handler(s) for this service…

Service “f7f6d3d36c1809a9e0536402000a3c5a” 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

sh-4.4$

The value of the environment variables set in the container may be listed, as an example:

sh-4.4$ echo $ORACLE_SID

FREE

sh-4.4$  echo $ORACLE_PDB

FREEPDB1

 

Start a SQL* Plus Session

Next, start a SQL* Plus session with the sqlplus command.

sh-4.4$ sqlplus

SQL*Plus: Release 23.0.0.0.0 – Developer-Release on Wed May 31 17:15:37 2023

Version 23.2.0.0.0

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

When prompted for user name specify SYS AS SYSDBA.

Enter user-name: SYS AS SYSDBA

When prompted for password specify the password configured when starting the container orcl.

Enter password:

As the output indicates the SYS user gets connected.

Connected to:

Oracle Database 23c Free, Release 23.0.0.0.0 – Developer-Release

Version 23.2.0.0.0

 

The Database is a Container database

Starting with Oracle Database 21c Oracle Database is available only as a multitenant CDB database, and support for the non-CDB database has been discontinued. A non-CDB database may be upgraded to a CDB as discussed in the upgrade guide. Verify from the CDB column in the v$database view whether the database is a CDB (container database).

SQL> 

SELECT CDB from v$database;

SQL> SELECT CDB from v$database;

CDB

YES

Display the current container name, and the root container gets listed.

SQL> SHOW CON_NAME

CON_NAME

——————————

CDB$ROOT

List the container id.

SQL> SHOW CON_ID

CON_ID

——————————

1

List the PDBs (pluggable databases) from the v$pdbs view, and the FREEPDB1 should get listed. The other PDB listed PDB$SEED is the seed PDB.

SQL> select con_id, dbid, name from v$pdbs;

    CON_ID     DBID

———- ———-

NAME

——————————————————————————–

             2  871956951

PDB$SEED

             3 1511376183

FREEPDB1

SQL>

Verify that the open_mode for the FREEPDB1 is READ WRITE, which is the default and needed to be able to both read and write to the PDB, from the v$pdbs view column open_mode with the following command:

SQL> select name, open_mode from v$pdbs;

NAME

——————————————————————————–

OPEN_MODE

———-

PDB$SEED

READ ONLY

FREEPDB1

READ WRITE

The datafiles for the different container databases may be listed from the v$datafile view.

SQL> select name from v$datafile;

NAME

——————————————————————————–

/opt/oracle/oradata/FREE/system01.dbf

/opt/oracle/oradata/FREE/pdbseed/system01.dbf

/opt/oracle/oradata/FREE/sysaux01.dbf

/opt/oracle/oradata/FREE/pdbseed/sysaux01.dbf

/opt/oracle/oradata/FREE/users01.dbf

/opt/oracle/oradata/FREE/pdbseed/undotbs01.dbf

/opt/oracle/oradata/FREE/undotbs01.dbf

/opt/oracle/oradata/FREE/FREEPDB1/system01.dbf

/opt/oracle/oradata/FREE/FREEPDB1/sysaux01.dbf

/opt/oracle/oradata/FREE/FREEPDB1/undotbs01.dbf

/opt/oracle/oradata/FREE/FREEPDB1/users01.dbf

11 rows selected.

The tempfiles may also be listed from the v$tempfile view.

SQL> select con_id,name from v$tempfile;

    CON_ID

———-

NAME

——————————————————————————–

             1

/opt/oracle/oradata/FREE/temp01.dbf

             2

/opt/oracle/oradata/FREE/pdbseed/temp01.dbf

             3

/opt/oracle/oradata/FREE/FREEPDB1/temp01.dbf

By default the IS_HYBRID_READ_ONLY column shows NO for all container databases. The column name is truncated to IS_ in the SELECT output.

SQL> SELECT * from V$CONTAINER_TOPOLOGY;

INSTANCE_NUMBER

—————

CON_NAME

——————————————————————————–

OPEN_MODE   CPU_COUNT         CON_ID RES IS_

———- ———- ———- — —

                  1

CDB$ROOT

READ WRITE     2           1 NO  NO

                  1

PDB$SEED

READ ONLY      2           2 NO  NO

INSTANCE_NUMBER

—————

CON_NAME

——————————————————————————–

OPEN_MODE   CPU_COUNT         CON_ID RES IS_

———- ———- ———- — —

                  1

FREEPDB1

READ WRITE     2           3 NO  NO

 

Create a new CDB Common user

A CDB common user can be used in all the PDBs within a CDB. Create a new CDB common user with the CREATE USER command. Connected to the root CDB, a common user (a user for all the PDBs within the CDB) can be created with the CONTAINER clause set to ALL.

SQL> CREATE USER C##u1 IDENTIFIED BY pwd1 DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP QUOTA UNLIMITED ON USERS CONTAINER=ALL;

User created.

Grant CREATE SESSION and CREATE TABLE privileges to the common user. A privilege can be granted commonly by setting CONTAINER=ALL in the GRANT statement. The common user name must start with the value set in the initialization parameter COMMON_USER_PREFIX, C## by default.

SQL> GRANT CREATE SESSION, CREATE TABLE  TO C##U1 CONTAINER=ALL;

Grant succeeded.

If the prefix is not included for a CDB common user name, the CREATE USER command fails as follows.

SQL> CREATE USER u1 IDENTIFIED BY p1 CONTAINER=ALL;

CREATE USER u1 IDENTIFIED BY p1 CONTAINER=ALL           *

ERROR at line 1:

ORA-65096: common user or role name must start with prefix C##

 

Create a PDB Local User

To use the PDB called FREEPDB1 run the ALTER SESSION command to set the container to FREEPDB1.

SQL> alter session set container = FREEPDB1;

Session altered.

The session should have changed to the PDB.

SQL> SHOW CON_NAME;

CON_NAME

——————————

FREEPDB1

The system privileges granted to the root user connected to the PDB may be listed from the SESSION_PRIVS table. A subset of the privileges are listed:

SQL> SELECT * FROM SESSION_PRIVS;;

PRIVILEGE

—————————————-

ALTER DATABASE

ALTER ANY ROLE

GRANT ANY ROLE

DROP ANY ROLE

CREATE ROLE

DROP PUBLIC DATABASE LINK

CREATE PUBLIC DATABASE LINK

CREATE DATABASE LINK

SELECT ANY SEQUENCE

DROP ANY SEQUENCE

ALTER ANY SEQUENCE

CREATE ANY SEQUENCE

DROP ANY INDEX

ALTER ANY INDEX

CREATE ANY INDEX

DELETE ANY TABLE

UPDATE ANY TABLE

INSERT ANY TABLE

SELECT ANY TABLE

ALTER ANY TABLE

CREATE ANY TABLE

CREATE TABLE

DROP USER

ALTER USER

BECOME USER

CREATE USER

UNLIMITED TABLESPACE

DROP TABLESPACE

ALTER SESSION

CREATE SESSION

AUDIT SYSTEM

ALTER SYSTEM

278 rows selected.

Create a PDB local user called orcl_pdb. The CONTAINER clause is set to CURRENT to indicate that the PDB user is a local user for the current container database.

SQL> CREATE USER orcl_pdb

    IDENTIFIED BY pwd1

    DEFAULT TABLESPACE USERS

    TEMPORARY TABLESPACE TEMP

    QUOTA UNLIMITED ON USERS CONTAINER=CURRENT; 

User created.

Grant CREATE SESSION and CREATE TABLE privileges to the PDB local user with CONTAINER clause set to CURRENT.

SQL> GRANT CREATE SESSION, CREATE TABLE TO orcl_pdb CONTAINER=CURRENT;

Grant succeeded.

 

Connect as CDB Common User to the PDB that is in READ WRITE Mode

The default open mode being READ WRITE,  a CDB common user is able to perform DDL (Data Definition Language), DML (Data Manipulation Language), DQL (Data Query Language), and DCL (Data Control Language)  operations

Next, connect to the PDB as a CDB common user. Specify password when prompted.

SQL> CONNECT C##U1@FREEPDB1 

Enter password: 

Connected.

As the CDB common user, create a new table, and add data to the table.

SQL> CREATE TABLE wlslog(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255));

Table created.

SQL> INSERT INTO wlslog(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:16-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STANDBY’);

1 row created.

 

Create a PDB Local User

Next, create a PDB local user while connected as a user that has privileges to create a user.As an example, connect SYS AS SYSDBA.

SQL> connect SYS AS SYSDBA

Enter password: 

Connected.

Switch session to the pluggable container database FREEPDB1.

SQL> ALTER SESSION SET CONTAINER=FREEPDB1;

Session altered.

The session name should list the FREEPDB1.

SQL> SHOW CON_NAME;

CON_NAME

——————————

FREEPDB1

Create a new user with the CREATE USER command. Set the CONTAINER clause to CURRENT for the user to be for the current container only.

SQL> CREATE USER orcl_pdb

    IDENTIFIED BY pwd1

    DEFAULT TABLESPACE USERS

    TEMPORARY TABLESPACE TEMP

    QUOTA UNLIMITED ON USERS CONTAINER=CURRENT;   

 

User created.

Grant CREATE SESSION and CREATE TABLE privileges to the orcl_pdb user, again with CONTAINER clause set to CURRENT.

SQL> GRANT CREATE SESSION, CREATE TABLE TO orcl_pdb CONTAINER=CURRENT;

Grant succeeded.

Connect as the PDB Local User

Next, connect to the FREEPDB1 as the new local user orcl_pdb.

SQL> CONNECT orcl_pdb@FREEPDB1

Enter password: 

Connected.

The default open mode being READ WRITE a PDB local user is able to perform read-write operations. As an example, create a new table and add data to the table.

SQL> CREATE TABLE wlslog(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255));

Table created.

SQL> INSERT INTO wlslog(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:16-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STANDBY’);

1 row created.

Change PDB Open Mode to READ ONLY

Next, we shall change the PDB open mode to READ ONLY and demonstrate that it affects both a CDB common user and a PDB local user.  Connected with SYS AS SYSDBA, the following ALTER PLUGGABLE database command sets the open mode of the FREEPDB1 to mounted. 

SQL> CONNECT SYS AS SYSDBA

Enter password: 

Connected.

If already connected as a user with the necessary privileges,  any uncommitted transactions must be committed before running the ALTER PLUGGABLE statement.

SQL> COMMIT;

Commit complete.

SQL> ALTER PLUGGABLE DATABASE FREEPDB1 CLOSE IMMEDIATE;

Pluggable database altered.

Next, set the open mode of the FREEPDB1 to READ ONLY.

SQL> 

SQL> ALTER PLUGGABLE DATABASE FREEPDB1 OPEN READ ONLY;

Pluggable database altered.

In the READ ONLY open mode neither of CDB common users or PDB local users are able to perform any write operations, which includes DDL and DML, but not DQL.

To demonstrate, connect as the CDB common user C##U1 and create a table, or rather try to create a new table.

SQL> CONNECT C##U1@FREEPDB1

Enter password: 

Connected.

SQL> CREATE TABLE wlslog_copy(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255));

An error message gets generated, which is expected in the READ ONLY mode.

CREATE TABLE wlslog_copy(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255))

*

ERROR at line 1:

ORA-16000: Attempting to modify database or pluggable database that is open for

read-only access.

Try to add some data to an existing table.

SQL> INSERT INTO wlslog(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:17-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STARTING’);

Again, an error message gets generated, which is expected in the READ ONLY mode.

INSERT INTO wlslog(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:17-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STARTING’)

            *

ERROR at line 1:

ORA-16000: Attempting to modify database or pluggable database that is open for

read-only access.

The CDB common user is able to perform a read with a SELECT statement.

SQL> SELECT time_stamp || ‘ ‘ || category || ‘ ‘ || type || ‘ ‘ || servername || ‘ ‘ ||code || ‘ ‘ || msg  from wlslog;

TIME_STAMP||”||CATEGORY||”||TYPE||”||SERVERNAME||”||CODE||”||MSG

——————————————————————————–

Apr-8-2014-7:06:16-PM-PDT Notice WebLogicServer AdminServer BEA-000365 Server st

ate changed to STANDBY

Next, connect to the PDB that is in READ ONLY mode as a PDB local user and try to perform DDL and DML operations.

SQL> CONNECT orcl_pdb@FREEPDB1

Enter password: 

Connected.

Try to create a new table.

SQL> CREATE TABLE wlslog_copy(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255));

An error message gets generated indicating that the CREATE TABLE statement cannot be run because the database is open in read-only  mode.

CREATE TABLE wlslog_copy(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255))

*

ERROR at line 1:

ORA-16000: Attempting to modify database or pluggable database that is open for

read-only access.

Try to add some data to an existing table.

SQL> INSERT INTO wlslog(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:17-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STARTING’);

Again, an error message gets generated, as expected.

INSERT INTO wlslog(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:17-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STARTING’)

            *

ERROR at line 1:

ORA-16000: Attempting to modify database or pluggable database that is open for

read-only access.

A DQL SELECT statement, however, runs without an error.

SQL> SELECT time_stamp || ‘ ‘ || category || ‘ ‘ || type || ‘ ‘ || servername || ‘ ‘ ||code || ‘ ‘ || msg  from wlslog;

TIME_STAMP||”||CATEGORY||”||TYPE||”||SERVERNAME||”||CODE||”||MSG

——————————————————————————–

Apr-8-2014-7:06:16-PM-PDT Notice WebLogicServer AdminServer BEA-000365 Server st

ate changed to STANDBY

 

In the READ ONLY open mode, the IS_HYBRID_READ_ONLY column in the dynamic view V$CONTAINER_TOPOLOGY still shows NO for the FREEPDB1.

SQL> CONNECT SYS AS SYSDBA

Enter password: 

Connected.

SQL>  SELECT * from V$CONTAINER_TOPOLOGY;

 

INSTANCE_NUMBER

—————

CON_NAME

——————————————————————————–

OPEN_MODE   CPU_COUNT         CON_ID RES IS_

———- ———- ———- — —

                  1

CDB$ROOT

READ WRITE     2           1 NO  NO

                  1

PDB$SEED

READ ONLY      2           2 NO  NO

INSTANCE_NUMBER

—————

CON_NAME

——————————————————————————–

OPEN_MODE   CPU_COUNT         CON_ID RES IS_

———- ———- ———- — —

                  1

FREEPDB1

READ ONLY      2           3 NO  NO

The open_mode in the v$pdbs dynamic view gets listed as READ ONLY.

SQL> select name, open_mode from v$pdbs;

NAME

——————————————————————————–

OPEN_MODE

———-

PDB$SEED

READ ONLY

 

FREEPDB1

READ ONLY

Set PDB Open Mode to HYBRID READ ONLY

As before, connect as a user with the requisite privileges, such as SYS AS SYSDBA, and close the pluggable database with ALTER PLUGGABLE DATABASE statement.

SQL> CONNECT SYS AS SYSDBA

Enter password: 

Connected.

SQL> ALTER PLUGGABLE DATABASE FREEPDB1 CLOSE IMMEDIATE;

Pluggable database altered.

The database state changes to mounted. Open the pluggable database FREEPDB1 in HYBRID READ ONLY mode.

SQL> ALTER PLUGGABLE DATABASE FREEPDB1 OPEN HYBRID READ ONLY;

Pluggable database altered.

The server log lists the details of when the database is opened in HYBRID READ ONLY mode.

ALTER PLUGGABLE DATABASE FREEPDB1 OPEN HYBRID READ ONLY

2023-06-01T00:15:17.430416+00:00

FREEPDB1(3):SUPLOG: Initialize PDB SUPLOG SGA, old value 0x0, new value 0x18

FREEPDB1(3):Autotune of undo retention is turned on. 

FREEPDB1(3):Undo initialization recovery: Parallel FPTR complete: start:9629505 end:9629507 diff:2 ms (0.0 seconds)

FREEPDB1(3):[1571] Successfully onlined Undo Tablespace 2.

2023-06-01T00:15:18.716710+00:00

FREEPDB1(3):SUPLOG: Set PDB SUPLOG SGA at PDB OPEN, old 0x18, new 0x0 (no suplog)

FREEPDB1(3):Opening pdb with Resource Manager plan: DEFAULT_PLAN

2023-06-01T00:15:19.772842+00:00

Completed: Pluggable database FREEPDB1 opened read write 

Completed: ALTER PLUGGABLE DATABASE FREEPDB1 OPEN HYBRID READ ONLY

In the HYBRID READ ONLY open mode, the IS_HYBRID_READ_ONLY column in the dynamic view V$CONTAINER_TOPOLOGY shows YES for the FREEPDB1.

SQL> SELECT * from V$CONTAINER_TOPOLOGY;

INSTANCE_NUMBER

—————

CON_NAME

——————————————————————————–

OPEN_MODE   CPU_COUNT         CON_ID RES IS_

———- ———- ———- — —

                  1

CDB$ROOT

READ WRITE     2           1 NO  NO

                  1

PDB$SEED

READ ONLY      2           2 NO  NO

INSTANCE_NUMBER

—————

CON_NAME

——————————————————————————–

OPEN_MODE   CPU_COUNT         CON_ID RES IS_

———- ———- ———- — —

                  1

FREEPDB1

READ WRITE     2           3 NO  YES

The IS_HYBRID_READ_ONLY column value may be selected separately, and it should be listed as YES for the third row, which is for the FREEPDB1.

SQL> SQL> SELECT IS_HYBRID_READ_ONLY FROM V$CONTAINER_TOPOLOGY;

IS_

NO

NO

YES

The open_mode column in the dynamic view v$pdbs shows READ WRITE in the root CDB.

SQL> select name, open_mode from v$pdbs;

 

NAME

——————————————————————————–

OPEN_MODE

———-

PDB$SEED

READ ONLY

FREEPDB1

READ WRITE

Next, we shall demonstrate that a CDB common user is still able to perform DDL, and DML operations in the PDB that is opened in HYBRID READ ONLY mode, but a PDB local user is not.

Connect as the PDB local user orcl_pdb  that we created earlier.

 

SQL> CONNECT orcl_pdb@FREEPDB1

Enter password: 

Connected.

Run a DQL SELECT statement, and it returns the query result.

SQL> SELECT time_stamp || ‘ ‘ || category || ‘ ‘ || type || ‘ ‘ || servername || ‘ ‘ ||code || ‘ ‘ || msg  from wlslog;

TIME_STAMP||”||CATEGORY||”||TYPE||”||SERVERNAME||”||CODE||”||MSG

——————————————————————————–

Apr-8-2014-7:06:16-PM-PDT Notice WebLogicServer AdminServer BEA-000365 Server st

ate changed to STANDBY

Try running a DDL statement such as CREATE TABLE.

SQL> CREATE TABLE wlslog_copy(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255));

An error message is returned indicating that the pluggable database is open for read-only access.

CREATE TABLE wlslog_copy(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255))

*

ERROR at line 1:

ORA-16000: Attempting to modify database or pluggable database that is open for

read-only access.

Try to run a DML statement such as an INSERT INTO statement.

SQL> INSERT INTO wlslog(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:17-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STARTING’);

Again, an error message indicates that the database cannot be modified as it is open in read-only access.

INSERT INTO wlslog(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:17-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STARTING’)

            *

ERROR at line 1:

ORA-16000: Attempting to modify database or pluggable database that is open for

read-only access.

The FREEPDB1 is open for read-only access only for the PDB local user, and not so for a CDB common user. Connect as the CDB common user C##U1.

SQL> CONNECT C##U1@FREEPDB1 

Enter password: 

Connected.

Try to run a DDL statement, such as a CREATE TABLE and the table gets created.

SQL> CREATE TABLE wlslog_copy(time_stamp VARCHAR2(255) PRIMARY KEY,category VARCHAR2(255),type VARCHAR2(255),servername VARCHAR2(255), code VARCHAR2(255),msg VARCHAR2(255));

Table created.

Try to run a DML statement such as INSERT and the data gets added.

SQL> INSERT INTO wlslog_copy(time_stamp,category,type,servername,code,msg) VALUES(‘Apr-8-2014-7:06:17-PM-PDT’,’Notice’,’WebLogicServer’,’AdminServer’,’BEA-000365′,’Server state changed to STARTING’);

1 row created.

 

Stop and start container

The Docker container for the Oracle Database 23 may be stopped and started as needed. To stop the container run the docker stop command.

~$ sudo docker stop orcl

Orcl

Subsequently, the docker ps command shouldn’t list the container if it has been stopped.

~$ sudo docker ps

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

The stopped container may be started again with docker start command.

~$ sudo docker start orcl;

Orcl

The container gets listed as running.

~$ sudo docker ps

CONTAINER ID   IMAGE                                         COMMAND                  CREATED       STATUS                            PORTS                                       NAMES

27b0465f6cda   container-registry.oracle.com/database/free   “/bin/sh -c ‘exec $O…”   2 hours ago   Up 7 seconds (health: starting)   0.0.0.0:1521->1521/tcp, :::1521->1521/tcp   orcl

 

In this article we discussed using the new Oracle Database 23c Free edition with Docker. We also discussed a new feature in Oracle Database 23 – the new HYBRID READ ONLY open mode for PDBs.

 

For further reference: