User, Role and Privilege management in Oracle 12c

User creation, Roles and privileges in 12c.

User creation and role & privilege management changes slightly on Oracle 12c.

Now we have two types of user and roles & privileges such as Local and Common.

* Local User
* Common User
* Local roles and privileges
* Common roles and privileges.

Below are some points about this topic.

A CDB can contain only common User. By default any user created in a CBD is a common user.

Let’s create a Common User.

SQL>
SQL> create user c##testuser1 identified by oracle;

User created.

SQL>
SQL> L
1* select username,user_id,account_status,profile,common,oracle_maintained from dba_users where oracle_maintained='N'
SQL> /

USERNAME	USER_ID ACCOUNT_STATUS	PROFILE COM O
--------------- ---------- -------------------- ---------- --- -
C##TESTUSER1	105 OPEN DEFAULT YES N
C##CDB_USER	102 OPEN DEFAULT YES N
C##TEST1	104 OPEN DEFAULT YES N

SQL>

– A common user is visible and accessible on the root container and all pdb container.

Let’s check whether the common user is visible at PDB level.

Login to any PDB or switch to any PDB and check the dba_users dictionary view.

SQL> alter session set container=PDB20;
Session altered.

SQL> sho con_name
CON_NAME
------------------------------
PDB20
SQL> set lines 200 pages 2000
SQL> col username for a20

SQL> select username,account_status,common from dba_users where oracle_maintained='N';
USERNAME             ACCOUNT_STATUS                   COM
-------------------- -------------------------------- ---
TEST3                OPEN                             NO
TEST2                OPEN                             NO
TEST1                OPEN                             NO
PDB_ADM              OPEN                             NO
C##TESTUSER1         OPEN                             YES
C##DEEPAK            OPEN                             YES
C##SREE              OPEN                             YES
C##DEEPAK2           OPEN                             YES

8 rows selected.

SQL> select username,account_status,common from dba_users where username='C##TESTUSER1';
USERNAME             ACCOUNT_STATUS                   COM
-------------------- -------------------------------- ---
C##TESTUSER1         OPEN                             YES

SQL>

– A common user can perform administrative action on root container and PDB containers only if provided with necessary roles and privileges.

Let’s try to login to a containter with the newly created common user.

SQL>
SQL> conn c##testuser1/deepak@localhost:1521/pdb20
ERROR:
ORA-01045: user C##TESTUSER1 lacks CREATE SESSION privilege; logon denied

Warning: You are no longer connected to ORACLE.
SQL>

As per the above snippet we are not able to even login to the PDB without necessary privilege.

– A common user name always start with the string “c##”, for example “c##tester”
– By default it is not possible to create without string “C##”, it is possible to create user with regular name only by setting the undocumented parameter “_ORACLE_SCRIPT”. (Ofcourse it is not recommended to set underscore parameter without consent from Oracle Support. Your database may be desupported if you set undocumented parameter without directive from Oracle support.)

Now let’s try to create common user without the C## string.

SQL> show parameter _Oracle_script
SQL>
SQL>
SQL> create user testuser2 identified by deepak;
create user testuser2 identified by deepak
            *
ERROR at line 1:
ORA-65096: invalid common user or role name

SQL>

The undocumented parameter “_ORACLE_SCRIPT” is not set and we tried to create a cmmon user without the string, we encountered an error.

SQL>
SQL> alter session set "_ORACLE_SCRIPT"=TRUE;

Session altered.

SQL> create user testuser1 identified by oracle;

User created.

SQL>

After setting the parameter we are able to create user without c## string.

Let’s check the user is whether common user and it is accessible from PDB level.

CDB level.

SQL> SET LINES 200 PAGES 2000
SQL> COL USERNAME FOR A20
SQL> select username,account_status,common from dba_users where username='TESTUSER1';

USERNAME             ACCOUNT_STATUS                   COM
-------------------- -------------------------------- ---
TESTUSER1            OPEN                             YES

SQL> SHO CON_NAME

CON_NAME
------------------------------
CDB$ROOT
SQL>

At PDB level

SQL> alter session set container=PDB20;

Session altered.

SQL> SHO CON_NAME

CON_NAME
------------------------------
PDB20
SQL> SET LINES 200 PAGES 2000
SQL> COL USERNAME FOR A20
SQL> select username,account_status,common from dba_users where username='TESTUSER1';

no rows selected

SQL>

Common users created without c## is not visible at PDB level.

When trying to login with this common user, we get invalid user instead of missing Create session privilege

SQL> conn testuser1/oracle@localhost:1521/pdb20
ERROR:
ORA-01017: invalid username/password; logon denied

Warning: You are no longer connected to ORACLE.
SQL>

– After creating a common user we must provide necessary privilege to the common user.
– It is possible to restrict the common role and privilege for a common user to only a subset of PDB, and it is also possible to provide Common role and privilege to all PDBs at once.
– It is possible to provide common users different privilege in different containers.

Now let’s provide create session privilege to only the PDB20 container and check the login behaviour at various containers.

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDBORCL                        READ WRITE NO
         4 DEEPAK1                        READ WRITE NO
         5 PDB20                          READ WRITE NO
         6 PDB21                          READ WRITE NO
SQL>

SQL> grant create session to c##testuser1;

Grant succeeded.

SQL> select grantee,privilege,common,con_id from cdb_sys_privs  where grantee='C##TESTUSER1';

GRANTEE         PRIVILEGE                                COM     CON_ID
--------------- ---------------------------------------- --- ----------
C##TESTUSER1    CREATE SESSION                           NO           1

SQL>

As checked in the cdb_sys_privs the privilege is granted only in the container 1 which is root container.

Let’s try logging into some PDBs.

We have tried to login to the containers PDB20 and PDB21, but we are not able to login as the role provided was local to CDB$ROOT container.

SQL>
SQL> conn c##testuser1/deepak@localhost:1521/pdb20;
ERROR:
ORA-01045: user C##TESTUSER1 lacks CREATE SESSION privilege; logon denied

Warning: You are no longer connected to ORACLE.
SQL> conn c##testuser1/deepak@localhost:1521/pdb21;
ERROR:
ORA-01045: user C##TESTUSER1 lacks CREATE SESSION privilege; logon denied

SQL>

We can provide common role to common user with either the option CONTAINER=ALL or CONTAINER=CURRENT.

Below examples shows how to set privilege at specific container level, for example PDB20

SQL> CONN / AS SYSDBA
Connected.
SQL>
SQL> SHOW CON_NAME

CON_NAME
------------------------------
CDB$ROOT
SQL> ALTER SESSION SET CONTAINER=PDB20;

Session altered.

SQL> SHOW CON_NAME

CON_NAME
------------------------------
PDB20
SQL> GRANT CREATE SESSION TO C##TESTUSER1 CONTAINER=CURRENT;

Grant succeeded.

SQL> select grantee,privilege,common,con_id from cdb_sys_privs  where grantee='C##TESTUSER1';

GRANTEE         PRIVILEGE                                COM     CON_ID
--------------- ---------------------------------------- --- ----------
C##TESTUSER1    CREATE SESSION                           NO           5

SQL> alter session set container=cdb$root;

Session altered.

SQL> select grantee,privilege,common,con_id from cdb_sys_privs  where grantee='C##TESTUSER1';

GRANTEE         PRIVILEGE                                COM     CON_ID
--------------- ---------------------------------------- --- ----------
C##TESTUSER1    CREATE SESSION                           NO           1
C##TESTUSER1    CREATE SESSION                           NO           5

NOTE: Please not that the above privilege is not a Common privilege which is shown by the column COMMON.

Now create session has been granted to cdb$root and PDB20 containers. Let’s try to login to few PDBs.

SQL> show con_name

CON_NAME
------------------------------
CDB$ROOT
SQL> conn c##testuser1/deepak@localhost:1521/pdb20
Connected.
SQL>
SQL> show con_name

CON_NAME
------------------------------
PDB20
SQL>
SQL> disc
Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL>
SQL>
SQL> conn c##testuser1/deepak@localhost:1521/pdb21
ERROR:
ORA-01045: user C##TESTUSER1 lacks CREATE SESSION privilege; logon denied

SQL>

We are not able to login to the container PDB21 since we have not granted create session privilege to c##testuser1 for the container PDB21.

Now let’s give create session privilege to c##testuser1 with CONTAINER=ALL option and try the same.

SQL> conn / as sysdba
Connected.
SQL> show con_name

CON_NAME
------------------------------
CDB$ROOT
SQL>
SQL> grant create session to c##testuser1 container=all;

Grant succeeded.

SQL> select grantee,privilege,common,con_id from cdb_sys_privs  where grantee='C##TESTUSER1';

GRANTEE         PRIVILEGE                                COM     CON_ID
--------------- ---------------------------------------- --- ----------
C##TESTUSER1    CREATE SESSION                           NO           1
C##TESTUSER1    CREATE SESSION                           YES          1
C##TESTUSER1    CREATE SESSION                           YES          4
C##TESTUSER1    CREATE SESSION                           YES          3
C##TESTUSER1    CREATE SESSION                           YES          6
C##TESTUSER1    CREATE SESSION                           NO           5
C##TESTUSER1    CREATE SESSION                           YES          5

7 rows selected.

SQL>

Note that the privilege we grant with container=all option created a record in the above view for all the available containers (except PDB$SEED).

Try logging some PDBs.

SQL> conn c##testuser1/deepak@localhost:1521/pdb20
Connected.
SQL> disc
Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL> conn c##testuser1/deepak@localhost:1521/pdb21
Connected.
SQL> disc
Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL> conn c##testuser1/deepak@localhost:1521/pdborcl
Connected.
SQL> disc
Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL>

We are able to login to all PDBs without problem.

Also note that if you grant a privilege with option CONTAINER=ALL to an username without preceeding c## string, it will NOT obtain privilege for all the containers. It will obtain the privilege only for the Root container (CDB).

Let’s create a common user without preceeding c## string at the root container. After creation we will grant create session with CONTAINER=ALL option. After granting the privilege check the dcitionary view cdb_sys_privs to confirm on which containers privilege are granted.

SQL> 
SQL> ALTER SESSION SET "_ORACLE_SCRIPT"=TRUE;

Session altered.

SQL> CREATE USER TESTER IDENTIFIED BY deepak;

User created.

SQL> grant create session to tester container=all;

Grant succeeded.

SQL> desc cdb_sys_privs
 Name					   Null?    Type
 ----------------------------------------- -------- ----------------------------
 GRANTEE					    VARCHAR2(128)
 PRIVILEGE					    VARCHAR2(40)
 ADMIN_OPTION					    VARCHAR2(3)
 COMMON 					    VARCHAR2(3)
 CON_ID 					    NUMBER

SQL> select grantee,privilege,common,con_id from cdb_sys_privs where grantee='TESTER';

GRANTEE		PRIVILEGE				 COM	 CON_ID
---------------------------------------- --- ----------
TESTER		CREATE SESSION				 YES	      1


SQL> 

– A user which is created in a PDB is a local user.
– It is not possible to create a common user at PDB level.
– There is no restriction like the string “C##” while creating a local user. We can create users with regular name as usual.
– Its not possible to create a common user at a PDB, try doing so will result in error.
– The role and privlege that is provided at a PDB is local role and local privilege.
– It is not possible to provide common role and common privilege at PDB level. Trying do so will result in error.

DB Cache Size, Oracle Blocks, Tablespace with non standard block size.

The basic unit of disk I/O performed by Oracle is an Oracle Block. Each Oracle block is a combination of several OS blocks and the number of OS block per Oracle block is OS dependent.

The default size of oracle block is specified by the parameter DB_BLOCK_SIZE which is non modifiable during the life time of the database.

Critical tablespaces such as SYSTEM and SYSAUX will be created with the block size specified by the parameter DB_BLOCK_SIZE. Possible value for this parameter such as 2K, 4K, 8K, 16K and 32K, for 32 bit servers the maximum value for this parameter is 16K.

OLTP system typically benefit better by using a 4K or 8K blocks, but need to be decided after studying the data model of the database. DSS databases would benefit better with the block sizes of 16K or 32K.

SQL> show parameter db_block_size
NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_block_size			     integer	 8192
SQL>

This parameter cannot be changed after creation of the database.

SQL>
SQL> alter system set db_block_size=16384 scope=spfile;
alter system set db_block_size=16384 scope=spfile
*
ERROR at line 1:
ORA-32017: failure in updating SPFILE
ORA-32016: parameter "db_block_size" cannot be updated in SPFILE

SQL> alter system set db_block_size=16384 scope=memory;
alter system set db_block_size=16384 scope=memory
                 *
ERROR at line 1:
ORA-02095: specified initialization parameter cannot be modified

SQL>

If there is a need to create table with non-default block size, it is possible to create it in the same database. Oracle database allows upto 4 non standard block size tablespaces.

Before creating a tablespace with non standard block size be sure to allocate new buffer cache space that can accommodate blocks with this size by setting DB_nK_CACHE_SIZE.

For example if the default block size is 8K and you want to create a tablespace with 16K blocks then you need to allocate buffer cache to store 16K blocks using the parameter db_16K_cache_size.
Let’s try to create a new tablespace with non-default block size without allocating buffer cache with this block size.

SQL> create tablespace tbs_16k datafile '/oem/oradata/tbs_16k_datafile01.dbf' size 1g blocksize 16k;
create tablespace tbs_16k datafile '/oem/oradata/tbs_16k_datafile01.dbf' size 1g blocksize 16k
*
ERROR at line 1:
ORA-29339: tablespace block size 16384 does not match configured block sizes

Let’s set the 16K buffer cache as 50M and try to create the tablespace again

SQL> alter system set db_16k_cache_size=50M scope=both;
System altered.

SQL> create tablespace tbs_16k datafile '/oem/oradata/tbs_16k_datafile01.dbf' size 1g blocksize 16k;
Tablespace created.

SQL>

Tablespace has been succesfully created,

If you want to change the block size of a certain table you need to create a new tablespace with new required block size and move that table to this newly created tablespace.

Dynamic registration in Oracle

Service registration allows processes, such as an Oracle database, to identify their available services to the listener, which then acts as a port mapper for those services. The listener uses the dynamic service information about the database and instance received through service registration.

Dynamic service registration is configured in the database initialization file. It does not require any configuration in the listener.ora file. However, listener configuration must be set to listen on the ports named in the database initialization file, and must not have parameters set that prevent automatic registration, such as COST parameters.

By default, the LREG process registers service information with its local listener on the default local address of TCP/IP, port 1521. If the listener configuration is synchronized with the database configuration, then LREG can register service information with a nondefault local listener or a remote listener on another node. Synchronization occurs when the protocol address of the listener is specified in the listener.ora file and the location of the listener is specified in the initialization parameter file.

To have the LREG process register with a local listener that does not use TCP/IP, port 1521, configure the LOCAL_LISTENER parameter in the initialization parameter file to locate the local listener.

Because the LOCAL_LISTENER parameter and the LISTENER attribute enable LREG to register dispatcher information with the listener, it is not necessary to specify both the parameter and the attribute if the listener values are the same.

LOCAL_LISTENER is a comma-delimited list parameter. If a comma appears in the string, then the entire string must be enclosed in double quotation marks. Set the LOCAL_LISTENER parameter as follows:

ALTER SYSTEM SET LOCAL LISTENER=["listener_address"][,...];

If you set the parameter to null using the following statement, then the default local address of TCP/IP, port 1521 is assumed:

ALTER SYSTEM SET LOCAL_LISTENER=''

For example, if the listener address “ab,cd” is entered, then it resolves to one listener address. If the address is entered as ab,cd, then it resolves to two listener addresses, ab and cd.

The listener should be resolvable by tnsping

Suppose you have a listener named listener2 listening on port 1530

  • Ensure that you create an entry in tnsnames.ora which we will use in the parameter LOCAL_LISTENER
listener2=

(DESCRIPTION =

(ADDRESS = (PROTOCOL=tcp)(HOST=localhost)(PORT=1530)))
<ul>
  • On the host where the local listener resides, configure the listener.ora file with the protocol address of the listener.
    • On the database, set the LOCAL_LISTENER parameter in the database initialization parameter file to the alias of the local listener. For example:
    ALTER SYSTEM SET LOCAL_LISTENER=listener2;
    

    Dynamic registration is done by the database by the background process LREG.

    Listener Registration Process (LREG)

    The listener registration process (LREG) registers information about the database instance and dispatcher processes with the Oracle Net Listener (see “The Oracle Net Listener”). When an instance starts, LREG polls the listener to determine whether it is running. If the listener is running, then LREG passes it relevant parameters. If it is not running, then LREG periodically attempts to contact it.

    If the listener is not running when an instance starts, then the LREG process cannot register the service information. LREG attempts to connect to the listener periodically, but it may take up to 60 seconds before LREG registers with the listener after it has been started. To initiate service registration immediately after the listener is started, use the SQL statement ALTER SYSTEM REGISTER. This statement is especially useful in high availability configurations.

    Sourced from Oracle Documentation.

    Log file sync wait event

    By Dean Richards,

    The Oracle “log file sync” wait event is triggered when a user session issues a commit (or a rollback). The user session will signal or post the LGWR to write the log buffer to the redo log file. When the LGWR has finished writing, it will post the user session. The wait is entirely dependent on LGWR to write out the necessary redo blocks and send confirmation of its completion back to the user session. The wait time includes the writing of the log buffer and the post, and is sometimes called “commit latency”.

    The P1 parameter in <View:V$SESSION_WAIT> is defined as follows for the log file sync wait event:

    Reducing Oracle waits / wait times

    If a SQL statement is encountering a significant amount of total time for this event, the average wait time should be examined. If the average wait time is low, but the number of waits is high, then the application might be committing after every row, rather than batching COMMITs. Oracle applications can reduce this wait by committing after “n” rows so there are fewer distinct COMMIT operations. Each commit has to be confirmed to make sure the relevant REDO is on disk. Although commits can be “piggybacked” by Oracle, reducing the overall number of commits by batching transactions can be very beneficial.

    If the SQL statement is a SELECT statement, review the Oracle Auditing settings. If Auditing is enabled for SELECT statements, Oracle could be spending time writing and commit data to the AUDIT$ table.

    If the average wait time is high, then examine the other log related waits for the session, to see where the session is spending most of its time. If a session continues to wait on the same buffer# then the SEQ# column of V$SESSION_WAIT should increment every second. If not then the local session has a problem with wait event timeouts. If the SEQ# column is incrementing then the blocking process is the LGWR process. Check to see what LGWR is waiting on as it may be stuck.

    If the waits are because of slow I/O, then try the following:

    • Reduce other I/O activity on the disks containing the redo logs, or use dedicated disks.
      • Try to reduce resource contention. Check the number of transactions (commits + rollbacks) each second, from V$SYSSTAT.
    • Alternate redo logs on different disks to minimize the effect of the archiver on the log writer.
    • Move the redo logs to faster disks or a faster I/O subsystem (for example, switch from RAID 5 to RAID 1).
    • Consider using raw devices (or simulated raw devices provided by disk vendors) to speed up the writes.
    • See if any activity can safely be done with NOLOGGING / UNRECOVERABLE options in order to reduce the amount of redo being written.
    • See if any of the processing can use the COMMIT NOWAIT option (be sure to understand the semantics of this before using it).
    • Check the size of the log buffer as it may be so large that LGWR is writing too many blocks at one time.

    Log file sync wait event: other considerations

    There may be a problem with LGWR’s ability to flush redo out quickly enough if Oracle “log file sync” waits are significant for the entire system. The overall wait time for “log file sync” can be broken down into several components. If the system still shows high “log file sync” wait times after completing the general tuning tips above, break down the total Oracle wait time into the individual components. Then, tune those components that take up the largest amount of time.

    The “log file sync” wait event may be broken down into the following components:

    1. Wakeup LGWR if idle
    2. LGWR gathers the redo to be written and issues the I/O
    3. Wait time for the log write I/O to complete
    4. LGWR I/O post processing
    5. LGWR posting the foreground/user session that the write has completed
    6. Foreground/user session wakeup

    Tune the system based on the “log file sync” component with the most wait time. Steps 2 and 3 are accumulated in the “redo write time” statistic. (i.e. as found under STATISICS section of Statspack) Step 3 is the “log file parallel write” wait event. (See Metalink Note 34583.1:”log file parallel write”) Steps 5 and 6 may become very significant as the system load increases. This is because even after the foreground has been posted it may take some time for the OS to schedule it to run.

    Data Guard note

    If Data Guard with synchronous transport and commit WAIT defaults is used, the above tuning steps will still apply. However step 3 will also include the network write time and the redo write to the standby redo logs. The “log file sync” wait event and how it applies to Data Guard is explained in detail in the MAA OTN white paper – Note 387174.1:MAA – Data Guard Redo Transport and Network Best Practices.

    Final thoughts

    When a user session waits on the “log file sync” event, it is actually waiting for the LGWR process to write the log buffer to the redo log file and return confirmation/control back to it. If the total wait time is significant, review the average wait time. If the average wait time is low but the number of waits is high, reduce the number of commits by batching (or committing after “n”) rows.

    If slow I/O, investigate the following:

    • Reduce contention on existing disks.
    • Put log files on faster disks.
    • Put alternate redo logs on different disks to minimize the effect archive processes (log files switches).
    • Review application design, use NOLOGGING operations where appropriate, and avoid changing more data than required.

    If wait times are still significant, review each component of the “log file sync” and tune separately.

    Buffer busy waits

    Buffer busy wait happens when a session wants to access a database block in the buffer cache but it cannot because the buffer is busy. Another session is modifying the block and the contents of the block are in flux during the modification. To guarantee that the reader has a coherent image of the block with either all of the changes or none of the changes, the session modifying the block marks the block header with a flag letting other users know a change is taking place and to wait until the complete change is applied.

    The two main cases where this wait can occur are:

    • Another session is reading the block into the buffer
    • Another session holds the buffer in an incompatible mode to our request

    While the block is being changed, the block is marked as unreadable by others. The changes that are being made should last under a few hundredths of a second. A disk read should be under 20 milliseconds and a block modification should be under one millisecond. Therefore it will take a lot of buffer busy waits to cause a problem.

    However, in a problem situation, there is usually a hot block, such as the first block on the free list of a table, with high concurrent inserts. All users will insert into that block at the same time, until it fills up, then users start inserting into the next free block on the list, and so on.

    Another example of a problem is of multiple users running full table scans on the same large table at the same time. One user will actually read the block physically off disk, and the other users will wait on Buffer Busy Wait for the physical I/O to complete.

    The main way to reduce buffer busy waits is to reduce the total I/O on the system. This can be done by tuning the SQL to access rows with fewer block reads (i.e., by adding indexes). Even if we have a huge db_cache_size, we may still see buffer busy waits, and increasing the buffer size won’t help.

    The resolution of a “buffer busy wait”  events is one of the most confounding problems with Oracle.  In an I/O-bound Oracle system, buffer busy waits are common, as evidenced by any system with read (sequential/scattered) waits in the top-five waits.

    Reducing buffer busy waits reduces the total I/O on the system. This can be accomplished by tuning the SQL to access rows with fewer block reads by adding indexes, adjusting the database writer or adding freelists to tables and indexes.  Even if there is a huge db_cache_size , the DBA may still see buffer busy waits and, in this case, increasing the buffer size will not help.

    Increasing the db_cache_size parameter would not necessarily fix this problem.

    Point of action is give below,

    Look at v$waitstat (or the buffer busy drill down page) and determine the block type with the highest waits.

    Block Type and Action:

    • Undo Header – Use Automatic Undo Management (AUM) or add more RBS segments)
    • Undo Block – Use AUM (or increase RBS sizes)
    • Data Block – First determine if it is an I/O problem. The Buffer Busy Waits drill-down page should provide this information. Otherwise, sample from v$session_wait
      SELECT p3, count(*) 
        FROM v$session_wait 
        WHERE event='buffer busy wait'
      ;
      

      If p3 is less than 200 then it is an I/O problem. Either improve I/O performance or change application. Applications running concurrent batch jobs that do full table scans on the same large tables run into this problem.

    • Free List – Use ASSM (or freelists groups)

    Source : http://logicalread.solarwinds.com/oracle-buffer-busy-wait-event/