You are on page 1of 2

Oracle PL/SQL:

Hanging around in my hotel in Chicago because it is raining, I have been cruisin


g around in the OTN forums which inspired me to write something about the High W
atermark and the Oracle 10gR1 New Feature SEGMENT SHRINKING.
The High Watermark is the maximum fill-grade a table has ever reached.
Above the high watermark are only empty blocks.
These blocks can be formatted or unformatted.
First let's have a look at the question when space is allocated
- when you create a table at least one extent (contiguous blocks) is allocated t
o the table
- if you have specified MINEXTENTS the number of MINEXTENTS extents
will be allocated immedaitely to the table
- if you have not specified MINEXTENTS then exactely one extent
will be allocated (we will look at extent sizes later in another post).
Immediately after creation of the segment (table) the high watermark will be at
the first block of the first extent as long as there are no inserts made.
When you insert rows into the table the high watermark will be bumped up step by
step.
This is done by the server process which makes the inserts.
Now let us take a look at when space is released again from a segment like a tab
le or index:
Let's asume that we have filled a table with 100'0000 rows.
And let's asume that we deleted 50'000 rows afterwards.
In this case the high watermark will have reached the level of 100'000 and will
have stayed there. Which means that we have empty blocks below the high watermar
k now.
Oracle has a good reason this: it might occur that you delete rows and immediate
ly this you insert rows into the same table. In this case it is good that the sp
ace was not released with the deletes, because it had to be get reallocate again
for the following inserts, which would mean permanent changes to the data dicti
onary
(=> dba_free_space, dba_extents, dba_segements ...) .
Furthermore the physical addresses of the deleted row get recycled by new rows.
These empty blocks below the high watermark can get annoying in a number of situ
ations because they are not used by DIRECT LOADs and DIRECT PATH LOADs:
1. Seriel direct load:
INSERT /*+ APPEND */
INTO hr.employees
NOLOGGING
SELECT *
FROM oe.emps;
2. Parallel direct load:
ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+PARALLLEL(hr.employees,2)
INTO hr.employees
NOLOGGING
SELECT *
FROM oe.emps;
3. direct path loads:
sqlldr hr/hr control=lcaselutz.ctl ... direct=y (default is direct=n)
All the above actions case that the SGA is not used for the inserts but the PGA:
there wil be temporary segements filled and dumped into newly formatted blocks a
bove the high watermark.
So we might want to get high watermark down before we load data into the table i
n order to use the free empty blocks for the loading.
So how can we release unused space from a table?
There are a number of possible options which are already available before Oracle
10g:
- What we always could do is export and import the segment.
After an import the table will have only one extent.
The rows will have new physical addresses and
the high watermark will be adjusted.
- Another option would be to TRUNCATE the table.
With this we would loose all rows which are in the table.
So we cannot use this if we want to keep existing records.
With Oracle 9i another possibilty was implemented:
ALTER TABLE emp MOVE TABLESPACE users;
This statement will also cause that
- the rows will have new physical addresses and
- the high watermark will be adjusted.
But for this:
- we need a full (exclusive) table lock
- the indexes will be left with the status unusable (because they contain the ol
d rowids) and must be rebuilt.

You might also like