Introduction
This is the third guide in our database auditing series. We've already covered Standard Auditing and FGA Auditing, both of which audit through their own separate mechanisms and trails. Unified Auditing is different: rather than adding a third parallel mechanism, it consolidates standard, fine-grained, and mandatory audit records into a single trail, making it the recommended approach going forward for anyone not tied to the older methods. In this article, we'll configure Unified Auditing end to end, covering enabling it at the binary level, assigning it a dedicated tablespace, creating and managing audit policies, and purging old records.
Environment Used in This Guide
| Hostname | orcl.oraeasy.com |
|---|---|
| Database Name | orcldb |
| Database Version | 19.27 |
| Database Edition | Enterprise Edition |
Prerequisites
- 30 minutes of downtime, since enabling Unified Auditing at the binary level requires a database and listener restart.
- Sufficient space at both the tablespace and OS level for storing audit records.
Now let's proceed to enable Unified Auditing, step by step.
Step 1: Check Whether Unified Auditing Is Enabled
Before making any changes, confirm the current state. The v$option view tells you whether Unified Auditing is active at the binary level, and AUDIT_TRAIL shows what the older auditing mechanism is currently configured to use.
SQL> SHOW PDBS
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCLPDB READ WRITE NO
SQL>
SQL> DEF
DEFINE _DATE = "23-AUG-25" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "orcldc" (CHAR)
DEFINE _USER = "SYS" (CHAR)
DEFINE _PRIVILEGE = "AS SYSDBA" (CHAR)
DEFINE _SQLPLUS_RELEASE = "1927000000" (CHAR)
DEFINE _EDITOR = "vi" (CHAR)
DEFINE _O_VERSION = "Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.27.0.0.0" (CHAR)
DEFINE _O_RELEASE = "1927000000" (CHAR)
SQL> SHOW PARAMETER audit
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest string /u01/app/oracle/admin/orcl/adu
mp
audit_sys_operations boolean TRUE
audit_syslog_level string
audit_trail string DB
unified_audit_common_systemlog string
unified_audit_sga_queue_size integer 1048576
unified_audit_systemlog string
SQL>
SQL> SELECT value FROM v$option WHERE parameter = 'Unified Auditing';
VALUE
-------
FALSE
SQL>
SQL> alter session set container=ORCLPDB;
Session altered.
SQL> SHOW PARAMETER audit
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest string /u01/app/oracle/admin/orcl/adu
mp
audit_sys_operations boolean TRUE
audit_syslog_level string
audit_trail string DB
unified_audit_common_systemlog string
unified_audit_sga_queue_size integer 1048576
unified_audit_systemlog string
SQL> SELECT value FROM v$option WHERE parameter = 'Unified Auditing';
VALUE
--------
FALSE
Since the value returned is FALSE, Unified Auditing is not currently enabled.
Step 2: Enable Unified Auditing at the Binary Level
Unified Auditing has to be linked into the Oracle binary itself using make, which means a database and listener restart is required. We'll also set AUDIT_TRAIL to DB, EXTENDED beforehand so the change takes effect on the same restart.
Now set the AUDIT_TRAIL parameter:
SQL> CREATE PFILE='/home/oracle/pfileorcl.ora' FROM SPFILE;
File created.
SQL> ALTER SYSTEM SET audit_trail=DB, EXTENDED SCOPE=SPFILE;
System altered.
Stop database & listener:
SQL> SHUTDOWN IMMEDIATE;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> exit
[oracle@orcl ~]$ lsnrctl stop
LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 23-AUG-2025 13:49:41
Copyright (c) 1991, 2025, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=orcl.oraeasy.com)(PORT=1521)))
The command completed successfully
[oracle@orcl ~]$
Follow below for unified auditing:
[oracle@orcl ~]$ cd $ORACLE_HOME/rdbms/lib
[oracle@orcl lib]$
[oracle@orcl lib]$ ls -lrth ins_rdbms*
-rw-r--r--. 1 oracle oinstall 43K Apr 15 13:48 ins_rdbms.mk
[oracle@orcl lib]$
[oracle@orcl lib]$ cp ins_rdbms.mk ins_rdbms_bkp.mk
[oracle@orcl lib]$
[oracle@orcl lib]$ make -f ins_rdbms.mk uniaud_on ioracle
/usr/bin/ar d /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a kzanang.o
/usr/bin/ar cr /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/kzaiang.o
chmod 755 /u01/app/oracle/product/19.0.0/dbhome_1/bin
cd /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/;\
/usr/bin/ar r /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a `/usr/bin/ar t /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a` ;
- Linking Oracle
rm -f /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/oracle
/u01/app/oracle/product/19.0.0/dbhome_1/bin/orald -o /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/oracle -m64 -z noexecstack -Wl,--disable-new-dtags -L/u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/ -L/u01/app/oracle/product/19.0.0/dbhome_1/lib/ -L/u01/app/oracle/product/19.0.0/dbhome_1/lib/stubs/ -Wl,-E /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/opimai.o /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/ssoraed.o /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/ttcsoi.o -Wl,--whole-archive -lperfsrv19 -Wl,--no-whole-archive /u01/app/oracle/product/19.0.0/dbhome_1/lib/nautab.o /u01/app/oracle/product/19.0.0/dbhome_1/lib/naeet.o /u01/app/oracle/product/19.0.0/dbhome_1/lib/naect.o /u01/app/oracle/product/19.0.0/dbhome_1/lib/naedhs.o /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/config.o -ldmext -lserver19 -lodm19 -lofs -lcell19 -lnnet19 -lskgxp19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 -lclient19 -lvsnst19 -lcommon19 -lgeneric19 -lknlopt -loraolap19 -lskjcx19 -lslax19 -lpls19 -lrt -lplp19 -ldmext -lserver19 -lclient19 -lvsnst19 -lcommon19 -lgeneric19 `if [ -f /u01/app/oracle/product/19.0.0/dbhome_1/lib/libavserver19.a ] ; then echo "-lavserver19" ; else echo "-lavstub19"; fi` `if [ -f /u01/app/oracle/product/19.0.0/dbhome_1/lib/libavclient19.a ] ; then echo "-lavclient19" ; fi` -lknlopt -lslax19 -lpls19 -lrt -lplp19 -ljavavm19 -lserver19 -lwwg `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/ldflags` -lncrypt19 -lnsgr19 -lnzjs19 -ln19 -lnl19 -lngsmshd19 -lnro19 `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/ldflags` -lncrypt19 -lnsgr19 -lnzjs19 -ln19 -lnl19 -lngsmshd19 -lnnzst19 -lzt19 -lztkg19 -lmm -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 -lztkg19 `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/ldflags` -lncrypt19 -lnsgr19 -lnzjs19 -ln19 -lnl19 -lngsmshd19 -lnro19 `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/ldflags` -lncrypt19 -lnsgr19 -lnzjs19 -ln19 -lnl19 -lngsmshd19 -lnnzst19 -lzt19 -lztkg19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 `if /usr/bin/ar tv /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a | grep "kxmnsd.o" > /dev/null 2>&1 ; then echo " " ; else echo "-lordsdo19 -lserver19"; fi` -L/u01/app/oracle/product/19.0.0/dbhome_1/ctx/lib/ -lctxc19 -lctx19 -lzx19 -lgx19 -lctx19 -lzx19 -lgx19 -lclscest19 -loevm -lclsra19 -ldbcfg19 -lhasgen19 -lskgxn2 -lnnzst19 -lzt19 -lxml19 -lgeneric19 -locr19 -locrb19 -locrutl19 -lhasgen19 -lskgxn2 -lnnzst19 -lzt19 -lxml19 -lgeneric19 -lgeneric19 -lorazip -loraz -llzopro5 -lorabz2 -lorazstd -loralz4 -lipp_z -lipp_bz2 -lippdc -lipps -lippcore -lippcp -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 -lsnls19 -lunls19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 -lasmclnt19 -lcommon19 -lcore19 -ledtn19 -laio -lons -lmql1 -lipc1 -lfthread19 `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/sysliblist` -Wl,-rpath,/u01/app/oracle/product/19.0.0/dbhome_1/lib -lm `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/sysliblist` -ldl -lm -L/u01/app/oracle/product/19.0.0/dbhome_1/lib `test -x /usr/bin/hugeedit -a -r /usr/lib64/libhugetlbfs.so && test -r /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/shugetlbfs.o && echo -Wl,-zcommon-page-size=2097152 -Wl,-zmax-page-size=2097152 -lhugetlbfs`
rm -f /u01/app/oracle/product/19.0.0/dbhome_1/bin/oracle
mv /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/oracle /u01/app/oracle/product/19.0.0/dbhome_1/bin/oracle
chmod 6751 /u01/app/oracle/product/19.0.0/dbhome_1/bin/oracle
(if [ ! -f /u01/app/oracle/product/19.0.0/dbhome_1/bin/crsd.bin ]; then \
getcrshome="/u01/app/oracle/product/19.0.0/dbhome_1/srvm/admin/getcrshome" ; \
if [ -f "$getcrshome" ]; then \
crshome="`$getcrshome`"; \
if [ -n "$crshome" ]; then \
if [ $crshome != /u01/app/oracle/product/19.0.0/dbhome_1 ]; then \
oracle="/u01/app/oracle/product/19.0.0/dbhome_1/bin/oracle"; \
$crshome/bin/setasmgidwrap oracle_binary_path=$oracle; \
fi \
fi \
fi \
fi\
);
[oracle@orcl lib]$
Start database & listener:
SQL> STARTUP
ORACLE instance started.
Total System Global Area 524284552 bytes
Fixed Size 9179784 bytes
Variable Size 432013312 bytes
Database Buffers 75497472 bytes
Redo Buffers 7593984 bytes
Database mounted.
Database opened.
SQL>
SQL> SELECT value FROM v$option WHERE parameter = 'Unified Auditing';
VALUE
--------
TRUE
SQL> SHOW PARAMETER audit
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest string /u01/app/oracle/admin/orcl/adu
mp
audit_sys_operations boolean TRUE
audit_syslog_level string
audit_trail string DB, EXTENDED
unified_audit_common_systemlog string
unified_audit_sga_queue_size integer 1048576
unified_audit_systemlog string
SQL>
SQL> SHOW PDBS
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCLPDB READ WRITE NO
SQL>
SQL> ALTER SESSION SET CONTAINER=ORCLPDB;
Session altered.
SQL> SHOW PARAMETER audit
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest string /u01/app/oracle/admin/orcl/adu
mp
audit_sys_operations boolean TRUE
audit_syslog_level string
audit_trail string DB, EXTENDED
unified_audit_common_systemlog string
unified_audit_sga_queue_size integer 1048576
unified_audit_systemlog string
SQL>
SQL> SELECT value FROM v$option WHERE parameter = 'Unified Auditing';
VALUE
--------
TRUE
SQL> exit
[oracle@orcl ~]$ lsnrctl start
LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 23-AUG-2025 14:00:05
Copyright (c) 1991, 2025, Oracle. All rights reserved.
Starting /u01/app/oracle/product/19.0.0/dbhome_1/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 19.0.0.0.0 - Production
System parameter file is /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/listener.ora
Log messages written to /u01/app/oracle/diag/tnslsnr/orcl/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=orcl.oraeasy.com)(PORT=1521)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=orcl.oraeasy.com)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 19.0.0.0.0 - Production
Start Date 23-AUG-2025 14:00:05
Uptime 0 days 0 hr. 0 min. 0 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/listener.ora
Listener Log File /u01/app/oracle/diag/tnslsnr/orcl/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=orcl.oraeasy.com)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
The listener supports no services
The command completed successfully
[oracle@orcl ~]$
Step 3: Assign a Tablespace for Audit Data
By default, unified audit records land in the SYSAUX tablespace, which isn't ideal for high audit volumes. Use DBMS_AUDIT_MGMT to point the audit trail at a dedicated tablespace instead, keeping audit growth from crowding SYSAUX.
SQL> SET LINESIZE 333 PAGESIZE 333
SQL> COLUMN owner FORMAT A15
SQL> COLUMN table_name FORMAT A20
SQL> COLUMN interval FORMAT A30
SQL> SELECT owner,
table_name,
interval,
partitioning_type,
partition_count,
def_tablespace_name
FROM dba_part_tables
WHERE owner = 'AUDSYS';
OWNER TABLE_NAME INTERVAL PARTITION PARTITION_COUNT DEF_TABLESPACE_NAME
--------------- -------------------- ------------------------------ --------- --------------- ------------------------------
AUDSYS AUD$UNIFIED INTERVAL '1' MONTH RANGE 1048575 SYSAUX
SQL> CREATE TABLESPACE audit_data DATAFILE '/u01/app/oracle/oradata/ORCL/orclpdb/audit_data01.dbf' SIZE 1G AUTOEXTEND on;
Tablespace created.
SQL> select FILE_NAME,TABLESPACE_NAME,BYTES/1024/1024,STATUS,AUTOEXTENSIBLE from dba_data_files where TABLESPACE_NAME in ('AUDIT_DATA');
FILE_NAME TABLESPACE_NAME BYTES/1024/1024 STATUS AUT
-------------------------------------------------------------------------------- ------------------------------ --------------- --------- ---
/u01/app/oracle/oradata/ORCL/orclpdb/audit_data01.dbf AUDIT_DATA 1024 AVAILABLE YES
SQL>
BEGIN
DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
audit_trail_location_value => 'AUDIT_DATA'
);
END;
/
PL/SQL procedure successfully completed.
SQL> SELECT owner,
table_name,
interval,
partitioning_type,
partition_count,
def_tablespace_name
FROM dba_part_tables
WHERE owner = 'AUDSYS';
OWNER TABLE_NAME INTERVAL PARTITION PARTITION_COUNT DEF_TABLESPACE_NAME
--------------- -------------------- ------------------------------ --------- --------------- ------------------------------
AUDSYS AUD$UNIFIED INTERVAL '1' MONTH RANGE 1048575 AUDIT_DATA
Step 4: Create an Audit Policy
With Unified Auditing enabled and a tablespace assigned, we can start creating policies. Here we'll enable DDL auditing, tracking table, view, procedure, sequence, trigger, user, role, and synonym changes, while excluding actions performed by SYS.
SQL> SHOW PDBS
CON_ID CON_NAME OPEN MODE RESTRICTED
--- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCLPDB READ WRITE NO
SQL>
SQL> ALTER SESSION SET CONTAINER=ORCLPDB
Session altered.
SQL> CREATE AUDIT POLICY ddl_audit_policy
ACTIONS CREATE TABLE, ALTER TABLE, DROP TABLE,
CREATE VIEW, DROP VIEW,
CREATE PROCEDURE, ALTER PROCEDURE, DROP PROCEDURE,
CREATE SEQUENCE, DROP SEQUENCE,
CREATE TRIGGER, DROP TRIGGER,
CREATE USER, DROP USER, ALTER USER,
CREATE ROLE, DROP ROLE, GRANT, REVOKE,
CREATE SYNONYM, DROP SYNONYM
WHEN 'SYS_CONTEXT(''USERENV'',''SESSION_USER'') <> ''SYS'''
EVALUATE PER STATEMENT;
Audit policy created.
Step 5: Enable the Policy
Creating a policy doesn't activate it. The separate AUDIT POLICY statement is what actually turns it on.
SQL> AUDIT POLICY ddl_audit_policy;
Audit succeeded.
Step 6: Check the Enabled Audit Policy
ORA_SECURECONFIG and ORA_LOGON_FAILURES are Oracle-defined policies that are enabled by default, alongside the new DDL_AUDIT_POLICY we just created.
SQL> SET LINESIZE 333 PAGESIZE 333
SQL> COLUMN policy_name FORMAT A25
SQL> COLUMN entity_name FORMAT A15
SQL> COLUMN success FORMAT A10
SQL> COLUMN failure FORMAT A10
SQL> SELECT * FROM audit_unified_enabled_policies;
POLICY_NAME ENABLED_OPTION ENTITY_NAME ENTITY_ SUCCESS FAILURE
------------------------- --------------- --------------- ------- ---------- ----------
ORA_SECURECONFIG BY USER ALL USERS USER YES YES
ORA_LOGON_FAILURES BY USER ALL USERS USER NO YES
DDL_AUDIT_POLICY BY USER ALL USERS USER YES YES
SQL>
SQL> COLUMN audit_condition FORMAT A50
SQL> COLUMN object_name FORMAT A20
SQL> COLUMN audit_option FORMAT A30
SQL> SELECT policy_name,
audit_condition,
object_name,
object_type,
audit_option
FROM audit_unified_policies
WHERE policy_name = 'DDL_AUDIT_POLICY';
POLICY_NAME AUDIT_CONDITION OBJECT_NAME OBJECT_TYPE AUDIT_OPTION
------------------------- -------------------------------------------------- ----------- ------------ ------------------
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE CREATE TABLE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE DROP TABLE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE CREATE SEQUENCE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE ALTER TABLE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE DROP SEQUENCE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE CREATE SYNONYM
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE DROP SYNONYM
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE CREATE VIEW
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE DROP VIEW
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE CREATE PROCEDURE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE ALTER PROCEDURE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE ALTER USER
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE CREATE USER
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE CREATE ROLE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE DROP USER
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE DROP ROLE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE CREATE TRIGGER
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE DROP TRIGGER
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE DROP PROCEDURE
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE GRANT
DDL_AUDIT_POLICY SYS_CONTEXT('USERENV','SESSION_USER') <> 'SYS' NONE NONE REVOKE
SQL>
Step 7: Generate Some DDL Activity
Create a test user and run a few DDL statements as that user, so we have something to see in the audit trail once we check it.
SQL> CREATE USER testaudit IDENTIFIED BY your@Password;
User created.
SQL> GRANT connect, resource TO testaudit;
Grant succeeded.
SQL> GRANT unlimited tablespace TO testaudit;
Grant succeeded.
SQL> GRANT create view TO testaudit;
Grant succeeded.
With TESTAUDIT user:
SQL> SHOW USER
USER is "TESTAUDIT"
SQL> DEF
DEFINE _DATE = "23-AUG-25" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "orclpdb" (CHAR)
DEFINE _USER = "TESTAUDIT" (CHAR)
DEFINE _PRIVILEGE = "" (CHAR)
DEFINE _SQLPLUS_RELEASE = "1927000000" (CHAR)
DEFINE _EDITOR = "vi" (CHAR)
DEFINE _O_VERSION = "Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.27.0.0.0" (CHAR)
DEFINE _O_RELEASE = "1927000000" (CHAR)
SQL> CREATE TABLE company (
emp_id INT,
name VARCHAR(255),
company VARCHAR(255)
);
Table created.
SQL> ALTER TABLE company ADD city VARCHAR2(20);
Table altered.
SQL> DROP TABLE company;
Table dropped.
SQL> CREATE TABLE company (
emp_id INT,
name VARCHAR(255),
company VARCHAR(255)
);
Table created.
Step 8: Check the Captured Audit Records
Querying unified_audit_trail as SYS confirms every DDL statement from the previous step was captured, along with the exact SQL text.
SQL> SET LINESIZE 333 PAGESIZE 333
SQL> COLUMN event_timestamp FORMAT A40
SQL> COLUMN action_name FORMAT A15
SQL> COLUMN sql_text FORMAT A60
SQL> COLUMN dbusername FORMAT A20
SQL> SELECT event_timestamp,
dbusername,
action_name,
sql_text
FROM unified_audit_trail
ORDER BY event_timestamp DESC;
EVENT_TIMESTAMP DBUSERNAME ACTION_NAME SQL_TEXT
---------------------------------------- -------------------- --------------- ------------------------------------------------------------
23-AUG-25 07.25.04.140615 PM TESTAUDIT CREATE TABLE CREATE TABLE COMPANY (EMP_ID INT,NAME VARCHAR(255), COMPANY
VARCHAR(255))
23-AUG-25 07.24.55.252860 PM TESTAUDIT DROP TABLE drop table COMPANY
23-AUG-25 07.24.28.117447 PM TESTAUDIT ALTER TABLE alter table COMPANY add city varchar2(20)
23-AUG-25 07.24.05.784920 PM TESTAUDIT CREATE TABLE CREATE TABLE COMPANY (EMP_ID INT,NAME VARCHAR(255), COMPANY
VARCHAR(255))
23-AUG-25 07.19.11.847290 PM SYS GRANT grant connect,resource to testaudit
23-AUG-25 07.18.58.518906 PM SYS CREATE USER create user testaudit identified by *
Step 9: Enable DML Auditing in a Similar Way
The same policy mechanism works for DML. Here we audit inserts, updates, and deletes against a specific table, testaudit.company.
SQL> CREATE AUDIT POLICY company_dml_audit
ACTIONS INSERT, UPDATE, DELETE ON testaudit.company;
Audit policy created.
SQL> AUDIT POLICY company_dml_audit;
Audit succeeded.
Now check the DML audit policy:
SQL> SET LINESIZE 333 PAGESIZE 333
SQL> COLUMN policy_name FORMAT A25
SQL> COLUMN entity_name FORMAT A15
SQL> COLUMN success FORMAT A10
SQL> COLUMN failure FORMAT A10
SQL> SELECT * FROM audit_unified_enabled_policies;
POLICY_NAME ENABLED_OPTION ENTITY_NAME ENTITY_ SUCCESS FAILURE
------------------------- --------------- --------------- ------- ---------- ----------
ORA_SECURECONFIG BY USER ALL USERS USER YES YES
ORA_LOGON_FAILURES BY USER ALL USERS USER NO YES
DDL_AUDIT_POLICY BY USER ALL USERS USER YES YES
COMPANY_DML_AUDIT BY USER ALL USERS USER YES YES
SQL> COLUMN audit_condition FORMAT A50
SQL> COLUMN object_name FORMAT A20
SQL> COLUMN audit_option FORMAT A30
SQL> SELECT policy_name,
audit_condition,
object_name,
object_type,
audit_option
FROM audit_unified_policies
WHERE policy_name = 'COMPANY_DML_AUDIT';
POLICY_NAME AUDIT_CONDITION OBJECT_NAME OBJECT_TYPE AUDIT_OPTION
------------------------- ------------------ -------------------- ----------------------- ---------------
COMPANY_DML_AUDIT NONE NONE NONE INSERT
COMPANY_DML_AUDIT NONE NONE NONE UPDATE
COMPANY_DML_AUDIT NONE COMPANY TABLE DELETE
Step 10: Take a Fresh Login and Perform DML
SQL> SHOW USER
USER is "TESTAUDIT"
SQL> DEF
DEFINE _DATE = "23-AUG-25" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "orclpdb" (CHAR)
DEFINE _USER = "TESTAUDIT" (CHAR)
DEFINE _PRIVILEGE = "" (CHAR)
DEFINE _SQLPLUS_RELEASE = "1927000000" (CHAR)
DEFINE _EDITOR = "vi" (CHAR)
DEFINE _O_VERSION = "Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.27.0.0.0" (CHAR)
DEFINE _O_RELEASE = "1927000000" (CHAR)
SQL> INSERT INTO company VALUES (101, 'Yash', 'WIPRO');
1 row created.
SQL> UPDATE company SET name = 'RAJ' WHERE emp_id = 101;
1 row updated.
SQL> DELETE FROM company;
1 row deleted.
SQL> COMMIT;
Commit complete.
Step 11: Check the Captured DML Audit Records
SQL> SET LINESIZE 333 PAGESIZE 333
SQL> COLUMN event_timestamp FORMAT A40
SQL> COLUMN action_name FORMAT A15
SQL> COLUMN sql_text FORMAT A60
SQL> COLUMN dbusername FORMAT A20
SQL> SELECT event_timestamp,
dbusername,
action_name,
sql_text
FROM unified_audit_trail
ORDER BY event_timestamp DESC;
EVENT_TIMESTAMP DBUSERNAME ACTION_NAME SQL_TEXT
---------------------------------------- -------------------- --------------- ------------------------------------------------------------
23-AUG-25 07.47.34.662020 PM TESTAUDIT DELETE delete from COMPANY
23-AUG-25 07.47.15.582965 PM TESTAUDIT UPDATE update COMPANY set NAME='RAJ' where EMP_ID=101
23-AUG-25 07.46.44.250120 PM TESTAUDIT INSERT INSERT INTO COMPANY VALUES (101,'Yash','WIPRO')
23-AUG-25 07.45.12.454288 PM SYS AUDIT AUDIT POLICY company_dml_audit
23-AUG-25 07.45.02.679294 PM SYS CREATE AUDIT PO CREATE AUDIT POLICY company_dml_audit
LICY ACTIONS INSERT, UPDATE, DELETE ON testau
23-AUG-25 07.42.24.140615 PM TESTAUDIT CREATE TABLE CREATE TABLE COMPANY (EMP_ID INT,NAME VARCHAR(255), COMPANY
VARCHAR(255))
23-AUG-25 07.41.54.033706 PM SYS CREATE AUDIT PO CREATE AUDIT POLICY company_dml_audit
LICY ACTIONS INSERT, UPDATE, DELETE ON testau
23-AUG-25 07.24.55.252860 PM TESTAUDIT DROP TABLE drop table COMPANY
23-AUG-25 07.24.28.117447 PM TESTAUDIT ALTER TABLE alter table COMPANY add city varchar2(20)
23-AUG-25 07.24.05.784920 PM TESTAUDIT CREATE TABLE CREATE TABLE COMPANY (EMP_ID INT,NAME VARCHAR(255), COMPANY
VARCHAR(255))
23-AUG-25 07.19.11.847290 PM SYS GRANT grant connect,resource to testaudit
23-AUG-25 07.18.58.518906 PM SYS CREATE USER create user testaudit identified by *
Step 12: Disable or Drop a Policy
If you need to turn a policy off, or remove it entirely, both are straightforward statements.
To disable:
SQL> NOAUDIT POLICY COMPANY_DML_AUDIT BY TEST;
Noaudit succeeded.
SQL> NOAUDIT POLICY COMPANY_DML_AUDIT;
Noaudit succeeded.
To dro:.
SQL> DROP AUDIT POLICY COMPANY_DML_AUDIT;
Audit Policy dropped.
SQL>
Step 13: Disable Unified Auditing at the Binary Level
If you ever need to revert, the process mirrors Step 2 exactly, but with uniaud_off instead of uniaud_on.
Stop database & listener:
SQL> SHUTDOWN IMMEDIATE;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> exit
[oracle@orcl ~]$ lsnrctl stop
LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 30-AUG-2025 12:45:22
Copyright (c) 1991, 2025, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=orcl.oraeasy.com)(PORT=1521)))
The command completed successfully
[oracle@orcl ~]$
Follow below to disable unified auditing:
[oracle@orcl ~]$ cd $ORACLE_HOME/rdbms/lib
[oracle@orcl lib]$
[oracle@orcl lib]$ ls -lrth ins_rdbms*
-rw-r--r--. 1 oracle oinstall 43K Apr 15 13:48 ins_rdbms.mk
-rw-r--r--. 1 oracle oinstall 43K Aug 23 13:52 ins_rdbms_bkp.mk
[oracle@orcl lib]$
[oracle@orcl lib]$ make -f ins_rdbms.mk uniaud_off ioracle
/usr/bin/ar d /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a kzaiang.o
/usr/bin/ar cr /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/kzanang.o
chmod 755 /u01/app/oracle/product/19.0.0/dbhome_1/bin
cd /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/;\
/usr/bin/ar r /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a `/usr/bin/ar t /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a` ;
- Linking Oracle
rm -f /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/oracle
/u01/app/oracle/product/19.0.0/dbhome_1/bin/orald -o /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/oracle -m64 -z noexecstack -Wl,--disable-new-dtags -L/u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/ -L/u01/app/oracle/product/19.0.0/dbhome_1/lib/ -L/u01/app/oracle/product/19.0.0/dbhome_1/lib/stubs/ -Wl,-E /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/opimai.o /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/ssoraed.o /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/ttcsoi.o -Wl,--whole-archive -lperfsrv19 -Wl,--no-whole-archive /u01/app/oracle/product/19.0.0/dbhome_1/lib/nautab.o /u01/app/oracle/product/19.0.0/dbhome_1/lib/naeet.o /u01/app/oracle/product/19.0.0/dbhome_1/lib/naect.o /u01/app/oracle/product/19.0.0/dbhome_1/lib/naedhs.o /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/config.o -ldmext -lserver19 -lodm19 -lofs -lcell19 -lnnet19 -lskgxp19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 -lclient19 -lvsnst19 -lcommon19 -lgeneric19 -lknlopt -loraolap19 -lskjcx19 -lslax19 -lpls19 -lrt -lplp19 -ldmext -lserver19 -lclient19 -lvsnst19 -lcommon19 -lgeneric19 `if [ -f /u01/app/oracle/product/19.0.0/dbhome_1/lib/libavserver19.a ] ; then echo "-lavserver19" ; else echo "-lavstub19"; fi` `if [ -f /u01/app/oracle/product/19.0.0/dbhome_1/lib/libavclient19.a ] ; then echo "-lavclient19" ; fi` -lknlopt -lslax19 -lpls19 -lrt -lplp19 -ljavavm19 -lserver19 -lwwg `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/ldflags` -lncrypt19 -lnsgr19 -lnzjs19 -ln19 -lnl19 -lngsmshd19 -lnro19 `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/ldflags` -lncrypt19 -lnsgr19 -lnzjs19 -ln19 -lnl19 -lngsmshd19 -lnnzst19 -lzt19 -lztkg19 -lmm -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 -lztkg19 `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/ldflags` -lncrypt19 -lnsgr19 -lnzjs19 -ln19 -lnl19 -lngsmshd19 -lnro19 `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/ldflags` -lncrypt19 -lnsgr19 -lnzjs19 -ln19 -lnl19 -lngsmshd19 -lnnzst19 -lzt19 -lztkg19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 `if /usr/bin/ar tv /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/libknlopt.a | grep "kxmnsd.o" > /dev/null 2>&1 ; then echo " " ; else echo "-lordsdo19 -lserver19"; fi` -L/u01/app/oracle/product/19.0.0/dbhome_1/ctx/lib/ -lctxc19 -lctx19 -lzx19 -lgx19 -lctx19 -lzx19 -lgx19 -lclscest19 -loevm -lclsra19 -ldbcfg19 -lhasgen19 -lskgxn2 -lnnzst19 -lzt19 -lxml19 -lgeneric19 -locr19 -locrb19 -locrutl19 -lhasgen19 -lskgxn2 -lnnzst19 -lzt19 -lxml19 -lgeneric19 -lgeneric19 -lorazip -loraz -llzopro5 -lorabz2 -lorazstd -loralz4 -lipp_z -lipp_bz2 -lippdc -lipps -lippcore -lippcp -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 -lsnls19 -lunls19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lcore19 -lsnls19 -lnls19 -lxml19 -lcore19 -lunls19 -lsnls19 -lnls19 -lcore19 -lnls19 -lasmclnt19 -lcommon19 -lcore19 -ledtn19 -laio -lons -lmql1 -lipc1 -lfthread19 `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/sysliblist` -Wl,-rpath,/u01/app/oracle/product/19.0.0/dbhome_1/lib -lm `cat /u01/app/oracle/product/19.0.0/dbhome_1/lib/sysliblist` -ldl -lm -L/u01/app/oracle/product/19.0.0/dbhome_1/lib `test -x /usr/bin/hugeedit -a -r /usr/lib64/libhugetlbfs.so && test -r /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/shugetlbfs.o && echo -Wl,-zcommon-page-size=2097152 -Wl,-zmax-page-size=2097152 -lhugetlbfs`
rm -f /u01/app/oracle/product/19.0.0/dbhome_1/bin/oracle
mv /u01/app/oracle/product/19.0.0/dbhome_1/rdbms/lib/oracle /u01/app/oracle/product/19.0.0/dbhome_1/bin/oracle
chmod 6751 /u01/app/oracle/product/19.0.0/dbhome_1/bin/oracle
(if [ ! -f /u01/app/oracle/product/19.0.0/dbhome_1/bin/crsd.bin ]; then \
getcrshome="/u01/app/oracle/product/19.0.0/dbhome_1/srvm/admin/getcrshome" ; \
if [ -f "$getcrshome" ]; then \
crshome="`$getcrshome`"; \
if [ -n "$crshome" ]; then \
if [ $crshome != /u01/app/oracle/product/19.0.0/dbhome_1 ]; then \
oracle="/u01/app/oracle/product/19.0.0/dbhome_1/bin/oracle"; \
$crshome/bin/setasmgidwrap oracle_binary_path=$oracle; \
fi \
fi \
fi \
fi\
);
[oracle@orcl lib]$
Start database & listener:
SQL> STARTUP
ORACLE instance started.
Total System Global Area 524284552 bytes
Fixed Size 9179784 bytes
Variable Size 432013312 bytes
Database Buffers 75497472 bytes
Redo Buffers 7593984 bytes
Database mounted.
Database opened.
SQL>
SQL> SELECT value FROM v$option WHERE parameter = 'Unified Auditing';
VALUE
--------
FALSE
SQL> SHOW PDBS
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCLPDB READ WRITE NO
SQL>
SQL> ALTER SESSION SET CONTAINER=ORCLPDB;
Session altered.
SQL>
SQL> SELECT value FROM v$option WHERE parameter = 'Unified Auditing';
VALUE
--------
FALSE
Purge Audit Data
Audit tables grow continuously, so periodically purging older records with DBMS_AUDIT_MGMT keeps the audit trail manageable. Here's the process, from checking current volume through confirming the purge.
Step 1: Check the Current Audit Record Count
SQL> SELECT COUNT(*) FROM unified_audit_trail;
COUNT(*)
----------
11818
SQL> SELECT COUNT(*) FROM unified_audit_trail
WHERE event_timestamp < SYSTIMESTAMP - 5;
COUNT(*)
----------
4113
Step 2: Set the Last Archive Timestamp
DBMS_AUDIT_MGMT uses this timestamp as the cutoff for what counts as "already archived" and safe to purge. Setting it to five days back means anything older than that becomes eligible for cleanup.
SQL> BEGIN
DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
last_archive_time => SYSTIMESTAMP - 5
);
END;
/
PL/SQL procedure successfully completed.
SQL> COLUMN audit_trail FORMAT A20
SQL> COLUMN last_archive_ts FORMAT A40
SQL> SELECT * FROM dba_audit_mgmt_last_arch_ts;
AUDIT_TRAIL RAC_INSTANCE LAST_ARCHIVE_TS DATABASE_ID CONTAINER_GUID
-------------------- ------------ ---------------------------------------- ----------- ---------------------------------
FGA AUDIT TRAIL 0 14-AUG-25 07.47.58.000000 PM +00:00 1593504508 2C3D6BACF692345BE0633350A8C050ED
STANDARD AUDIT TRAIL 0 03-AUG-25 07.46.26.000000 PM +00:00 1593504508 2C3D6BACF692345BE0633350A8C050ED
UNIFIED AUDIT TRAIL 0 25-AUG-25 10.52.41.000000 AM +00:00 1593504508 2C3D6BACF692345BE0633350A8C050ED
Step 3: Purge Records Older Than 5 Days
SQL> BEGIN
DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
use_last_arch_timestamp => TRUE
);
END;
/
PL/SQL procedure successfully completed.
SQL>
Step 4: Verify the Purge
The count of records older than five days drops to zero, confirming the purge only removed what was eligible and left recent activity intact.
SQL> SELECT COUNT(*) FROM unified_audit_trail;
COUNT(*)
----------
7710
SQL> SELECT COUNT(*) FROM unified_audit_trail
WHERE event_timestamp < SYSTIMESTAMP - 5;
COUNT(*)
----------
0
SQL>
Troubleshooting and Tips
Issue: Audit Data Still Landing in SYSAUX Instead of the New Tablespace
If you set the tablespace in Step 3 but audit data keeps showing up in SYSAUX anyway, check the partition interval on AUD$UNIFIED. By default it's set to monthly, which means the current partition (created before you changed the tablespace) keeps being used until the next interval rolls over. You can shorten the interval with DBMS_AUDIT_MGMT so new partitions, and the new tablespace, take effect sooner.
To check the current partition interval:
SQL> SELECT owner,
table_name,
interval,
partitioning_type,
partition_count,
def_tablespace_name
FROM dba_part_tables
WHERE table_name = 'AUD$UNIFIED';
OWNER TABLE_NAME INTERVAL PARTITION PARTITION_COUNT DEF_TABLESPACE_NAME
--------------- -------------------- ------------------------------ --------- --------------- ------------------------------
AUDSYS AUD$UNIFIED INTERVAL '1' MONTH RANGE 1048575 AUDIT_DATA
To change the interval for 1 day:
SQL> BEGIN
DBMS_AUDIT_MGMT.ALTER_PARTITION_INTERVAL(
interval_number => 1,
interval_frequency => 'DAY'
);
END;
/
PL/SQL procedure successfully completed.
SQL> SELECT owner,
table_name,
interval,
partitioning_type,
partition_count,
def_tablespace_name
FROM dba_part_tables
WHERE table_name = 'AUD$UNIFIED';
OWNER TABLE_NAME INTERVAL PARTITION PARTITION_COUNT DEF_TABLESPACE_NAME
--------------- -------------------- ------------------------------ --------- --------------- ------------------------------
AUDSYS AUD$UNIFIED NUMTODSINTERVAL(1, 'DAY') RANGE 1048575 AUDIT_DATA
Tip: Querying Large Audit Tables Directly by Partition
Once audit data grows large, querying the unified_audit_trail view directly can get slow. Querying the specific partition of the underlying AUD$UNIFIED table that covers your date range is much faster.
To check the available partition:
SQL> COLUMN table_name FORMAT A15
SQL> COLUMN partition_name FORMAT A15
SQL> COLUMN high_value FORMAT A15
SQL> SELECT table_name,
partition_name,
partition_position,
high_value,
num_rows,
tablespace_name
FROM dba_tab_partitions
WHERE table_owner = 'AUDSYS'
AND table_name = 'AUD$UNIFIED'
ORDER BY partition_position;
TABLE_NAME PARTITION_NAME PARTITION_POSITION HIGH_VALUE NUM_ROWS TABLESPACE_NAME
--------------- --------------- ------------------ ------------------------------ ---------- ------------------------------
AUD$UNIFIED SYS_P668 1 TIMESTAMP' 2025-09-01 00:00:00 4428 AUDIT_DATA
To query the particular partition:
SQL> SELECT count(*) FROM AUDSYS.AUD$UNIFIED PARTITION (SYS_P668);
COUNT(*)
----------
7714
Note that column names differ between the AUD$UNIFIED table and the unified_audit_trail view, so expect to do a bit of research on column names to find the data you need when querying the table directly.
How This Compares to Standard and FGA Auditing
Across the series: Standard Auditing is the simplest to set up and works on both Standard and Enterprise Edition, but records land in its own separate trail. FGA adds row and column-level conditions for sensitive data access, at the cost of Enterprise-only availability and a third separate trail to manage. Unified Auditing, covered here, consolidates all of it, standard, fine-grained, and mandatory auditing, into one trail and one policy framework, making it the more maintainable long-term choice if you're on Enterprise Edition and can absorb the one-time downtime to enable it at the binary level.
Thank you for reading!
I hope this content has been helpful to you. Your feedback and suggestions are always welcome, feel free to leave a comment or reach out with any queries.
Abhishek Shrivastava
Oracle DBA with hands-on experience managing production Data Guard, RAC, GoldenGate, and APEX environments. I write practical, tested installation and troubleshooting guides based on real deployment work.

Comments
Post a Comment