Re: enq: TT contention / recyclebin

  • From: Jonathan Lewis <jlewisoracle@xxxxxxxxx>
  • To: "Oracle L." <oracle-l@xxxxxxxxxxxxx>
  • Date: Sat, 4 Jun 2022 10:45:41 +0100

Another part of the answer comes from the way that the recyclebin (at least
in some versions of Oracle - which one are you using) isn't consistent
about reporting free and used space.  ,Here's a blog note I wrote on the
topic a few years ago:
https://jonathanlewis.wordpress.com/2017/05/10/quantum-space/ ;(it may no
longer be 100% accurate).

The answer to question 2 - yes, having a lot of items in the recyclebin
could result in a lot of waits for TT enqueue because a session may have to
remove some items from the recyclebin to make space, and it may take some
time (holding the TT enqueue for that tablespace) to search for the most
appropriate thing to drop, and then update the tablespace free space map -
and any concurrent attempts to create (or drop, possibly) another object in
the same tablespace at the same time will  have to wait on the first one.
(You could try enabling SQL trace while creating a large object that needs
this to happen - or you could search for the SQL that is seeing a lot of
elapsed time for very little CPU time and looks like data dictionary SQL)
(SQL ordered by Elapsed in the AWR might help)..


Regards
Jonathan Lewis


On Sat, 4 Jun 2022 at 04:19, blair storminson <dmarc-noreply@xxxxxxxxxxxxx>
wrote:

Greetings all,

I'm trying to see if the recyclebin is linked to a bad wait performance
issue (enq: TT contention) we're having. Here's a snippet from a 1hr AWR
report (I dont think my company will let me post the whole report - waiting
on a email from boss)

Event                 Waits  TotalWaitTime(sec)   AvgWait   %DBtime
==================== ======  =================    =======   =======
enq: TT - contention    350                36K    102.99s      49.3
DB CPU                                   20.6K                 28.1
library cache lock      222              11.5K     51.98s      15.8

I know TT is about tablespace management, so I started with my usual query
to show free versus used space...which came back with *negative* usage!

SQL> select d.tablespace_name, lpad(round(tot_size/1024/1024)||'m',10)
alloc_size, lpad(round(f.tot_free/1024/1024)||'m',10) tot_free,
round(100-100*tot_free/tot_size) pct_use
  2  from
  3  ( select tablespace_name, sum(tot_free) tot_free
  4    from
  5    ( select tablespace_name, sum(bytes) tot_free
  6      from dba_free_space
  7      group by tablespace_name
  8    )
  9    group by tablespace_name
 10  ) f,
 11  ( select tablespace_name, sum(bytes) tot_size
 12    from dba_data_files
 13    group by tablespace_name
 14  ) d
 15  where f.tablespace_name(+) = d.tablespace_name
 16  order by 1;


TABLESPACE_NAME       ALLOC_SIZE       TOT_FREE           PCT_USE
--------------------- ---------------- --------------- ----------
[chopped]
TS1                   156928m          336482m               -114

I thought my script must be buggy so I cut down the components parts, and
my tablespace is *definitely* 156G in size.

SQL> select tablespace_name, sum(bytes)/1024/1024 ALLOC_MB
  2  from dba_data_files
  3  where tablespace_name = 'TS1'
  4  group by tablespace_name

TABLESPACE_NAME                     ALLOC_MB
------------------------------ -------------
TS1                                   156928


SQL> select file_id, bytes, autoextensible, maxbytes
  2  from dba_data_files
  3  where tablespace_name = 'TS1';

             FILE_ID                BYTES AUT             MAXBYTES
-------------------- -------------------- --- --------------------
                  19          33285996544 YES          33564917760
                  18          33285996544 YES          31457280000
                 194          32212254720 YES          33564917760
                 195          32212254720 YES          33564917760
                 123          33554432000 NO                     0

The tablespace is more or less empty currently....

SQL> select tablespace_name, sum(bytes)/1024/1024 mb
  2  from dba_segments
  3  where tablespace_name = 'TS1'
  4  group by tablespace_name;

TABLESPACE_NAME                                  MB
------------------------------ --------------------
TS1                                          113.25

*Here* is where it all starts to get really strange.  When I look at
*free* space, I'm getting HUNDREDS of gigabytes more than the size of the
datafiles, hence the negative usage figures.

SQL> select file_id, count(*), sum(bytes)/1024/1024 mb
  2  from dba_free_space
  3  where tablespace_name = 'TS1'
  4  group by file_id
  5  order by 1;

   FILE_ID   COUNT(*)         MB
---------- ---------- ----------
        18     748982      78530
        19    1035729      96439
       123      45426      34824
       194     532200      63956
       195     559498      65661

Compare that to below!

SQL> select file#, bytes/1024/1024 mb from v$datafile
  2  where file# in (18,19,123,194,195)
  3  order by 1;

     FILE#         MB
---------- ----------
        18      31744
        19      31744
       123      32000
       194      30720
       195      30720

In trying to see why the free space values are silly, I found thousands of
entries in DBA_FREE_SPACE which have a *multiple* rows for a file/block_id
position. That explains the over-counting, but how can this happen?

SQL> select file_id, block_id, count(*)
  2  from dba_free_space
  3  where tablespace_name = 'TS1'
  4  group by file_id, block_id
  5  having count(*) > 1
  6  order by 1,2;

3131 rows selected

My theory is leaning to one of our apps which is a port from another
platform so it is all the time creating tables, dropping them, even
creating/dropping schemas on the fly. Our recyclebin is on by default (we
are looking to changing this for this app)

On first look, the recycle bin seems small ....

SQL> select TS_NAME, count(*)
  2  from dba_recyclebin
  3  group by ts_name;

TS_NAME             COUNT(*)
---------------- ----------
TS1                     233

But!!  Looking inside the DDL for DBA_FREE_SPACE, I found all those
surplus entries came from SYS.RECYCLEBIN$.

SQL> select
  2           ts.name, fi.file#, u.ktfbuebno,
  3           u.ktfbueblks * ts.blocksize, u.ktfbueblks, u.ktfbuefno
  4    from sys.recyclebin$ rb, sys.ts$ ts, sys.x$ktfbue u, sys.file$ fi
  5    where ts.ts# = rb.ts#
  6      and rb.ts# = fi.ts#
  7      and u.ktfbuefno = fi.relfile#
  8      and u.ktfbuesegtsn = rb.ts#
  9      and u.ktfbuesegfno = rb.file#
 10      and u.ktfbuesegbno = rb.block#
 11      and ts.bitmapped <> 0 and ts.online$ in (1,4) and ts.contents$ = 0
 12      and bitand(ts.flags, 4503599627370496) <> 4503599627370496
 13  and ts.name = 'TS1';

   COUNT(*)
----------
   4422097

Still reading?

Thus my questions:

Q1) How do I have entries in SYS.RECYCLEBIN$ to never make it to
DBA_RECYCLEBIN?
Q2) Can this (what looks to me like a dictionary corruption) combined with
the terrible way our app works explain the enq:TT contention? The two
places I see it are: i) create/drop commands on table or schemma, and ii)
when EM is doing tablespace metrics collection




Other related posts: