Pre-Ramble

My local council collects plastic, glass, paper, etc separately from the rubbish so that it can be put to good use for another purpose rather than these resources being wasted in a landfill somewhere.

Oracle databases (from 10g) collect dropped segments in a recycle bin, until the resource (tablespace capacity) needs to be used for something else.

My local council is having trouble finding a use (or buyer) for the collected materials, and so those materials are stockpiled and over time take up more and more space.  Some databases are in a similar situation.

Recent Case

A monitoring tool had been activated for an Oracle 10g database for the first time.  The monitoring tool’s database session was running for a long time and using a lot of CPU.  In fact, the next check was starting before the previous one had finished.

I could see that these sessions were doing a lot of consistent reads from memory (not much physical I/O) so high CPU usage was understandable because a lot of processing was occurring.

The SQL was referencing v$datafile, v$log, v$tempfile and dba_free_space.  It was a common enough piece of code that returned immediately on most 10g databases.  What was different about this database?  The first thing I thought to check was the number and size of the free and used chunks of space in the database.  When ordering the segments by total size or number of extents, I noticed a lot of segments beginning with “BIN$%”.  This made me think that the recycle bin had something to do with this issue.

SQL> select sum(bytes)/1048576 from dba_segments where segment_name like 'BIN$%';

SUM(BYTES)/1048576
------------------
        147092.125

1 row selected.

SQL> select min(droptime) from dba_recyclebin;

MIN(DROPTIME)
-------------------
2008-11-13:08:24:45

SQL> select count(1) from dba_recyclebin;

  COUNT(1)
----------
      9525

There are 9,525 items in the recycle bin that take up 150GB out of a total database size of 250GB!  Just think of the wasted space on disk, tape, etc.

Further reports on DBA_RECYCLEBIN showed that the application regularly drops some segments (partitions mostly).  I surmised at this point that the dropped objects are never purged, and that the datafiles are manually extended whenever the recycle bin contents fill up the tablespace enough to make the used capacity reach a certain threshold.  Note that if auto-extension had been left to handle growth, then the dropped objects would be purged as needed before the datafile was extended.  It was human intervention that was circumventing Oracle’s recycling process.

I suggested that this database should have the recycle bin purged and disabled so that the DBAs could continue to manage the capacity with their standard procedures.

A Little More for Anyone Still Interested

A “My Oracle Support” search showed that there were some bugs and problems in previous versions /patch sets regarding performance of DBA_FREE_SPACE when objects had been dropped.  Although there were no exact bug/note matches for this database’s version, I suspect that the underlying SQL was still not being executed efficiently.  Gathering statistics on the X$ views (via DBMS_STATS.GATHER_FIXED_OBJECTS_STATS) didn’t help, because one of the referenced v$ views (V$DATAFILES I think it was) had a RULE hint in it.  However, if the same SQL was forced to use CBO  then it ran much quicker.

This is the logical block accesses they’ve done so far:

SID BLOCK_GETS CONSISTENT_GETS PHYSICAL_READS BLOCK_CHANGES CONSISTENT_CHANGES

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

43        142        73903895 14224             0                  2

68        142        75150676 14573             0                  2

189        143        23221325 9066             1                  2

267        142        22997804 9059             0                  2

This is the SQL statement they are all running:

PARSING PARSING

SQL_TEXT

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

select  total_mb as met212_1, total_mb-free_mb as met212_2

from(select a.m + b.m + decode(c.m,null,0,c.m) total_mb, d.m fr

ee_mb    from(select sum(bytes)/1048576 m from v$datafile) a,

(select sum(bytes)/1048576 m from v$log) b,     (select sum(by

tes)/1048576 m from v$tempfile) c,     (select sum(bytes)/104867

6 m from dba_free_space) d)

CHLD      SHARE      PERST        RUN LOADED KEPT OPEN            PARSE                                            USER  SCHEMA

NUM        MEM        MEM        MEM   VERS VERS VERS LOADS INVL CALLS FIRST_LOAD_TIME     LAST_LOAD_TIME           ID      ID

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

0     153076      68608      67336      1    0    1     1    0     8 2009-07-30/11:51:10 2009-07-30/11:51:10      66      66

CHLD                 DISK     BUFFER                             ROWS

NUM     EXECS      READS       GETS      SORTS    FETCHES  PROCESSED      COST

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

0         8 120258  549877971 64          4          4         1

CHLD    CPU_TIME     ELAPSED

NUM         SEC         SEC MODULE                                             ACTION

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

0    18916.85 20740.22 SQL*Plus

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s