On a recent post about reducing the high water mark in a table by shrinking it someone asked if you could tell how much “space” there was in a table that could be recovered by compressing it.
Yes. As pseudo-code:
select number_of_rows*average_row_length. That is how much data there is.
Divided by the block size, to give how many blocks-worth of data you have.
Divided this by a “overhead” fudge factor to allow for wasted space (see later) of about 20%
Compare to the number of blocks used by the table.
Here is some code to do it, showing some extra data and how we calculate the effective percentage of space used (pct_spc_used). It runs against an example table ‘HWM’
My last post was on slow dictionary queries caused by having many, many thousands of extents in your database. This post is about a special case of this problem, which I encountered recently. It was on an Exadata box – Exadata is not particularly relevant to the issue, but I’m curious to see if mentioning Exadata will make this post more popular
I was querying the used and free space on a very small database on the client’s X2-2 1/4 rack Exadata machine. The query was really slow, taking about 30 seconds. This is a FAST box, what is going on?
I quickly realised that the problem was specific to one tablespace:
Are you finding queries to identify free space, the size of segments or details of extents in your database are very slow? You could have a database with a very, very large number of extents. If you are on version 9 or up, I would suggest you check the extent management settings for any tablespace holding large segments (see later).
{Caveat – I’m writing this posting based on what I remember of some issues I had on two V10.2 databases 2 and 3 years ago respectively, and those systems are no longer available to me. So please treat everything I say here with some caution – I’ve not checked and verified it to the level I normally would. But I wanted to move this information from another posting I am writing on a recent experience I will verify…}
Something I’ve just reminded myself of is that under Oracle you cannot add a comment on an index or a constraint. You can only add comments on tables, views, materialized views, columns of those object types and a couple of esoteric things like Operators, Editions and Indextypes.
Here is an example of adding comments to tables and columns:
One of my most popular postings is about why your SYSTEM tablespace could be rather large. Recently I’ve had issues with a SYSAUX tablespace being considerably larger than I expected, so I thought I would do a sister posting on the reason.
The client I was working with at the time was about to go live with a new application and database. For various reasons I was a little anxious about how the Java application (the User Interface) would actually call the stored PL/SQL code I had helped develop. Initial workloads would be low and so I asked that the STATISTICS_LEVEL be set to ALL, so that bind variables (amongst other things) would be gathered. This is on version 10.2.0.4, btw, enterprise edition and 4-node RAC.
We went live, issues were encountered and resolved, the usual way these things work. Then, a few weeks in and when everything was still very “exciting” from a problem resolution perspective, I got an odd email from the DBA team. Would they like us to add another datafile to the SYSAUX tablespace. Huh? I checked. I’d been watching the size of our application’s tablespaces but not the others {well, I was not supposed to be a DBA and I was watching an awful lot of other things}. Our SYSAUX tablespace was around 160GB in size, having pretty much filled it’s 5th datafile. Why? I checked to see what was taking up the space in the tablespace:
select * from
(select owner,segment_name||'~'||partition_name segment_name,bytes/(1024*1024) size_m
from dba_segments
where tablespace_name = 'SYSAUX'
ORDER BY BLOCKS desc)
where rownum < 40
OWNER SEGMENT_NAME SIZE_M
------------------ -------------------------------------------------- ------------
SYS WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_3911 27,648
SYS WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_3911 26,491
SYS WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_3537 23,798
SYS WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_3537 22,122
SYS WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_4296 17,378
SYS WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_4296 16,818
SYS WRH$_ACTIVE_SESSION_HISTORY~WRH$_ACTIVE_14459270_3 136
911
SYS WRH$_SQLSTAT~WRH$_SQLSTA_14459270_3911 96
SYS WRH$_SQLSTAT~WRH$_SQLSTA_14459270_3537 72
SYS WRH$_SQLSTAT~WRH$_SQLSTA_14459270_4296 47
SYS WRH$_LATCH_MISSES_SUMMARY_PK~WRH$_LATCH__14459270_ 45
3537
SYS I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST~ 41
SYS WRH$_SYSMETRIC_SUMMARY~ 40
SYS WRH$_LATCH_MISSES_SUMMARY_PK~WRH$_LATCH__14459270_ 37As you can see, almost all the space is being taken up by WRH$_LATCH_CHILDREN and WRH$_LATCH_CHILDREN_PK partitions. They are massive compared to other objects. A quick goggle did not come up with much other than many hits just listing what is in SYSAUX and the odd person also seeing SYSAUX being filled up with these objects and suggested ways to clear down space, nothing about the cause.
I had a chat with the DBAs and we quickly decided that this was going to be something to do with AWR given the name of objects – “WRH$_” objects are the things underlying AWR. The DBA suggested my settings of 15 minute intervals and 35 day retention was too aggressive. I knew this was not the case, I’ve had more aggressive snapshot intervals and longer retention periods on far busier systems than this. I did not have access to Metalink at that point so I asked the DBAs to raise a ticket, which they duly did.
Oracle support cogitated for a couple of days and came back with the advice to reduce the retention period. Hmmmm. Via the DBA I asked Oracle support to explain why those objects were so large when I had not seen this issue on several other systems. Was it a bug? I had by now corroborated with a friend from a previous site with 5 minute snapshot intervals and two months retention period and their SYSAUX tablespace was about 10GB all in. I did not want to go changing things if we did not know it would fix the issue as we really wanted to stop the growth of SYSAUX as soon as possible, not just try a hunch.
As you probably realise from the title of this blog, the issue was not the snapshot interval or retention period but the STATISTICS_LEVEL=ALL. The one and only hit you get in metalink if you search on WRH$_LATCH_CHILDREN is note 874518.1. From V10.1.0.2 to V11.1.0.7 setting this parameter to ALL is known to create a lot of data about Latch children and not clear it down when the AWR data is purged (Bug 8289729). The advice was to change STATISTICS_LEVEL and make the snapshot interval larger. I’d suggest you just need to alter the STATISTICS_LEVEL, unless you really, really need that extra information gathered. It seemed to take Oracle Support an extra day or two to find that note for us. {I’ve since checked out Metalink directly to confirm all this}.
So with a known issue we felt confident that altering the initialisation parameter would solve the issue. It took a while for us to change the STATISTICS_LEVEL on the production system – Change Control for that site is rather robust. This allowed us to see some other impacts of this issue.
The mmon process which looks after AWR data was becoming a top session in our OEM performance screens. In particular, a statement with SQL id 2prbzh4qfms7u that inserted into the WRH$_LATCH_CHILDREN table was taking several seconds to run each time and was running quite often {I include the SQL ID as it may be the same on many oracle V10 systems as it is internal code}:
This was doing a lot of IO, by far the majority of the IO on our system at the time – it was a new system and we had been able to tune out a lot of the physical IO.

The physical IO requirements and 15-20 second elapsed time made this out most demanding statement on the system
We also now started to have issues with mmon running out of undo space when it ran at the same time as our daily load. This was particularly unfortunate as it coincided in a period of “intense management interest” in the daily load…
What was happening to the size of the SYSAUX tablespace?
Enter the tablespace (or leave null)> sys
TS_NAME ORD SUM_BLKS SUM_K MAX_CHNK_K NUM_CHNK
-------------------- ----- ----------- ------------ ----------- --------
SYSAUX alloc 58,187,904 465,503,232 33,553,408 14
free 10,728 85,824 21,504 20
SYSTEM alloc 128,000 1,024,000 1,024,000 1
free 68,360 546,880 546,752 3
4 rows selected.
select * from
(select owner,segment_name||'~'||partition_name segment_name,bytes/(1024*1024) size_m
from dba_segments
where tablespace_name = 'SYSAUX'
ORDER BY BLOCKS desc)
where rownum < 40
OWNER SEGMENT_NAME SIZE_M
-------- ------------------------------------------------------------ ----------
SYS WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_6201 30262
WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_5817 29948
WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_5435 28597
WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_4675 28198
WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_3911 27648
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_5817 27144
WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_6585 26965
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_6201 26832
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_4675 26741
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_3911 26491
WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_4296 26307
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_5435 26248
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_4296 25430
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_6585 25064
WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_5058 24611
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_5058 23161
WRH$_LATCH_CHILDREN~WRH$_LATCH__14459270_6966 9209
WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__14459270_6966 8462
WRH$_SYSMETRIC_SUMMARY~ 152
WRH$_ACTIVE_SESSION_HISTORY~WRH$_ACTIVE_14459270_3911 136
WRH$_SQLSTAT~WRH$_SQLSTA_14459270_3911 96
@sysaux_conts
OWNER OBJ_PART_NAME SIZE_M
------------------------------ ---------------------------------------- ----------
SYS WRH$_LATCH_CHILDREN-WRH 231745.063
SYS WRH$_LATCH_CHILDREN_PK-WRH 215573.063
SYS WRH$_SQLSTAT-WRH 711.0625
SYS WRH$_LATCH_MISSES_SUMMARY_PK-WRH 439.0625
SYS WRH$_ACTIVE_SESSION_HISTORY-WRH 437.0625
SYS WRH$_LATCH_PARENT-WRH 292.0625
SYS WRH$_LATCH-WRH 276.0625
SYS WRH$_LATCH_MISSES_SUMMARY-WRH 273.0625
SYS WRH$_SEG_STAT-WRH 268.0625
SYS WRH$_LATCH_PARENT_PK-WRH 239.0625
SYS WRH$_SYSSTAT_PK-WRH 237.0625
Yes, that is close to half a terabyte of SYSAUX and it is all used, more partitions have appeared and the total size of the largest segments in SYSAUX show how WRH$_LATCH_CHILDREN and WRH$_LATCH_CHILDREN_PK make up the vast majority of the space used.
Shortly after, we finally got permission to change the live system. The impact was immediate, mmon dropped from being the most demanding session, that SQL code dropped down the rankings and the issues with running out of undo ceased.
I was anxious to see if the old data got purged, as the Metalink note had suggested the data would not be purged. Thankfully, that was not the case. The space was slowly released as normal purging of data outside the retention period took place and after just over a month, the SYSAUX tablespace contained a lot less information and was mostly free space:
OWNER OBJ_PART_NAME SIZE_M
---------- ---------------------------------------- ----------
SYS WRH$_LATCH_MISSES_SUMMARY_PK-WRH 512.0625
SYS WRH$_LATCH_MISSES_SUMMARY-WRH 350.0625
SYS WRH$_LATCH-WRH 304.0625
SYS WRH$_SQLSTAT-WRH 280.0625
SYS WRH$_LATCH_PK-WRH 259.0625
SYS WRH$_SYSSTAT_PK-WRH 247.0625
SYS WRH$_SERVICE_STAT_PK-WRH 228.0625
SYS WRH$_PARAMETER_PK-WRH 201.0625
SYS WRH$_PARAMETER-WRH 169.0625
SYS WRH$_SYSSTAT-WRH 169.0625
SYS WRH$_SEG_STAT-WRH 161.0625
SYS WRH$_SYSTEM_EVENT_PK-WRH 156.0625
SYS WRH$_SYSMETRIC_SUMMARY- 152
SYS WRH$_SYSTEM_EVENT-WRH 133.0625
SYS WRH$_SERVICE_STAT-WRH 123.0625
SYS WRH$_ACTIVE_SESSION_HISTORY-WRH 115.0625
TS_NAME ORD SUM_BLKS SUM_K MAX_CHNK_K NUM_CHNK
-------------------- ----- ----------- ------------ ----------- --------
SYSAUX alloc 58,251,904 466,015,232 33,553,408 15
free 57,479,400 459,835,200 4,063,232 1,208
SYSTEM alloc 128,000 1,024,000 1,024,000 1
free 68,048 544,384 544,320 2Now, how do we get that space back? I left that with the DBA team to resolve.
Oh, one last thing. I mentioned the above to a couple of the Oaktable lot in the pub a few weeks back. Their instant response was to say “You set STATISTICS_LEVEL to ALL on a live system?!? You are mad!”
{Update, I’ve just spotted this posting by Colbran which is related. Last time I googled this I just got a stub with no information}
How much Disk do I need for my new Oracle database? Answer:-
{Disclaimer. This is of course just my opinion, based on some experience. If you use the above figures for a real project and get the total disc space you need wrong, don’t blame me. If you do and it is right, then of course you now owe me a beer.}
Many of us have probably had to calculate the expected size a database before, but the actual database is only one component of all the things you need to run the Oracle component of your system. You need to size the other components too – Archived redo logs, backup staging area, dataload staging area, external files, the operating system, swap space, the oracle binaries {which generally gets bigger every year but shrink in comparison to the average size of an Oracle DB} etc…
In a similar way to my thoughts on how much database space you need for a person, I also used to check out the total disk space every database I created and those that I came across took up. {A friend emailed me after my earlier posting to ask if I had an obsession about size. I think the answer must be “yes”}.
First of all, you need to know how much “raw data” you have. By this I mean what will become the table data. Back in the early 90’s this could be the total size of the flat files the old system was using, even the size of the data as it was in spreadsheets. An Oracle export file of the system gives a pretty good idea of the raw data volume too. Lacking all these then you need to roughly size your raw data. Do a calculation of “number_of_rows*sum_of_columns” for your biggest 10 tables (I might blog more on this later). Don’t be tempted to overestimate, my multipliers allow for the padding.
Let us say you have done this and it is 60GB of raw data for an OLTP system. Let the storage guys know you will probably want about 500GB of space. They will then mentally put it down as “of no consequence” as if you have dedicated storage guys you probably have many terabytes of storage. {Oh, I should mention that I am not considering redundancy at all but space that is provided. The amount of actual spinning disk is down to the level and type of RAID you storage guys make you use. That is a whole other discussion}.
If you come up with 5TB of raw data for a DW system then you need around 12-15TB of disk storage.
If you come up with more than a Terabyte or so of raw data for an OLTP system or 10 to 20 Terabytes for a DW, when you give you figures to the storage guys/procurement people then they may well go pale and say something like “you have got to be kidding!”. This is part of why the multiplication factor for Data Warehouses and larger systems in general is less, as you are forced to be more careful about the space you allocate and how you use it.
The overhead of total disk space over Raw data reduces as the database gets bigger for a number of reasons:
My best ever ratio of database size to raw data was around 1.6 and it took an awful lot of effort and planning to get there. And an IT manager who made me very, very aware of how much the storage was costing him (it is not the disks, it’s all the other stuff).
I should also just mention that the amount of disk you need is only one consideration. If you want your database to perform well you need to consider the number of spindles. After all, you can create a very large database indeed using a single 2TB disc – but any actual IO will perform terribly.
Recent comments
17 weeks 4 days ago
27 weeks 2 days ago
29 weeks 19 hours ago
32 weeks 2 days ago
34 weeks 4 days ago
44 weeks 20 hours ago
45 weeks 4 days ago
46 weeks 4 days ago
46 weeks 5 days ago
49 weeks 3 days ago