An Oracle multitenant application container can house multiple applications. These applications may be shared by various application PDBs within the container. Each of these applications can have common application user(s) associated with it, which are created as part of the application install/upgrade action. However, it is not possible to identify common application users associated with a specific application by looking at DBA_USERS, as it does not have any column indicating the application. Regarding this, I contacted Connor McDonald, Developer Advocate at Oracle Corporation, who subsequently reached out to the Multitenant PM and got this back:
DBA_USERS has these columns: COMMON, INHERITED, IMPLICIT,
For the schema created within an Application Begin/End block, you should see 'YES', 'NO', 'NO' for these columns.
DBA_USERS does not indicate which Application created the user, but USER$.SPARE10 column has the Application ID of the Application that created the user.
In this article, I will demonstrate how we can identify common application users associated with an application using the USER$.SPARE10 column.
Current scenario
Here, we have an Oracle Database 12.2.0.1 CDB called orclcdb, having
- CDB seed PDB pdb$seed
- A regular PDB orcl
- An application container app_roothaving
- Application PDBs app_pdb1 and app_pdb2
- Applications
- sales_app with application users sales_app_user1 and sales_app_user2 created within the Application Begin/End block
- hr_app with application user hr_app_user created within the Application Begin/End block
We will learn how to identify the mapping between
- Common application users sales_app_user1, sales_app_user2 and hr_app_user
and
- Applications sales_app and hr_app.
Demonstration
Let us first connect to CDB orclcdb and verify that there is a regular PDB orcl, and an application container app_root in this CDB.
SQL> conn sys/oracle@orclcdb as sysdba
set sqlprompt CDB$ROOT>
sho con_name
CON_NAME
------------------------------
CDB$ROOT
CDB$ROOT>SELECT con_id, name, open_mode, application_root app_root,
application_pdb app_pdb, application_seed app_seed
from v$containers
where application_root = 'NO' and application_PDb = 'NO'
and application_seed = 'NO';
CON_ID NAME OPEN_MODE APP_ROOT APP_PDB APP_SEED
---------- ---------- ---------- -------- -------- --------
1 CDB$ROOT READ WRITE NO NO NO
2 PDB$SEED READ ONLY NO NO NO
3 ORCL READ WRITE NO NO NO
CDB$ROOT>SELECT con_id, name, open_mode, application_root app_root,
application_pdb app_pdb, application_seed app_seed
from v$containers
where application_root = 'YES' and application_pdb = 'NO';
CON_ID NAME OPEN_MODE APP_ROOT APP_PDB APP_SEED
---------- ---------- ---------- -------- -------- --------
6 APP_ROOT READ WRITE YES NO NO
Connect to application root app_root and note that there are two application PDBs app_pdb1 and app_pdb2 associated with it.
APP_ROOT>@get_app_containers
CON_ID NAME OPEN_MODE APP_ROOT APP_PDB APP_SEED APP_ROOT_CLONE
---------- ---------- ---------- -------- -------- -------- -----------------
4 APP_PDB1 READ WRITE NO YES NO NO
6 APP_ROOT READ WRITE YES NO NO NO
10 APP_PDB2 READ WRITE NO YES NO NO
Besides an implicit application, two other applications sales_app and hr_app are currently installed in this container.
APP_ROOT>@get_app_status
APP_NAME APP_VERSION APP_ID APP_STATUS IMPLICIT
-------------------------------------- ------------ ------ ------------ ------
APP$62CB609B7509C23AE05364C909C0AE0E 1.0 2 NORMAL Y
SALES_APP 1.4 21 NORMAL N
HR_APP 1.0 41 NORMAL N
Let us find out the common application users created in application root app_root.
APP_ROOT>select username, common from dba_users
where common = 'YES' and inherited = 'NO';
USERNAME COMMON
------------------------------ ----------
SALES_APP_USER2 YES
SALES_APP_USER1 YES
HR_APP_USER YES
From the output, we learn that there are three common application users in application root app_root but it is not possible to identify which application user is associated with which application, as there is no application-related column in data dictionary view DBA_USERS. However, in the base table user$, the SPARE10 column has the application ID of the application that created the user.
Let us join dba_applications with USER$ to find out the mapping between common application users and applications.
APP_ROOT>Select s.name username, a.app_name from user$ s, dba_applications a
where s.spare10 = a.app_id;
USERNAME APP_NAME
------------------------------ --------------------------------------
SALES_APP_USER1 SALES_APP
SALES_APP_USER2 SALES_APP
HR_APP_USER HR_APP
Now, we learn that the users sales_app_user1 and sales_app_user2 are associated with the sales_app application and the user hr_app_user is associated with the hr_app application.
Thus, the undocumented column SPARE10 of data dictionary base table USER$ can be used to identify the application which created the application user(s).
Summary
- An Oracle multitenant application container can house multiple applications.
- Each of these applications can have common application user(s) associated with it that are created as part of the application install/upgrade action.
- It is not possible to identify common application users associated with a specific application by looking at DBA_USERS, as it does not have any column indicating the application.
- We can identify common application users associated with an application using the USER$.SPARE10 column which stores the application ID of the application that created the user.
Scripts used in this article
get_app_containers.sql
-- Find out the containers in an application root when executed from application root
SELECT con_id, name, open_mode, application_root app_root,
application_pdb app_pdb, application_seed app_seed
from v$containers
order by con_id;
get_app_status.sql
-- Find out the status of various applications in an application container when executed from an application root
select app_name, app_version, app_id, app_status, app_implicit implicit from dba_applications;
Start the discussion at forums.toadworld.com