DBA Tips Archive for Oracle |
|
Reclaiming Unused LOB Space
by Jeff Hunter, Sr. Database Administrator
Contents
DROP SEQUENCE test_lob_seq / Sequence dropped. CREATE SEQUENCE test_lob_seq / Sequence created. |
CREATE OR REPLACE DIRECTORY images_dir AS '/u03/oradir/images' / Directory created. |
| load_blob_from_file_image.sql |
CREATE OR REPLACE PROCEDURE Load_BLOB_From_File_Image
AS
dest_loc BLOB;
file_name TEST_LOB.FILE_NAME%TYPE := 'iDevelopment_info_logo_2.tif';
src_loc BFILE := BFILENAME('IMAGES_DIR', file_name);
BEGIN
-- +-------------------------------------------------------------+
-- | INSERT INITIAL BLOB VALUE (an image file) INTO THE TABLE |
-- +-------------------------------------------------------------+
INSERT INTO test_lob (id, file_name, image, timestamp)
VALUES (test_lob_seq.nextval, file_name, empty_blob(), sysdate)
RETURNING image INTO dest_loc;
-- +-------------------------------------------------------------+
-- | OPENING THE SOURCE BFILE IS MANDATORY |
-- +-------------------------------------------------------------+
DBMS_LOB.OPEN(src_loc, DBMS_LOB.LOB_READONLY);
-- +-------------------------------------------------------------+
-- | OPENING THE LOB IS OPTIONAL |
-- +-------------------------------------------------------------+
DBMS_LOB.OPEN(dest_loc, DBMS_LOB.LOB_READWRITE);
-- +-------------------------------------------------------------+
-- | SIMPLY CALL "loadfromfile" TO LOAD FILES INTO A LOB COLUMN |
-- +-------------------------------------------------------------+
DBMS_LOB.LOADFROMFILE(
dest_lob => dest_loc
, src_lob => src_loc
, amount => DBMS_LOB.getLength(src_loc));
-- +-------------------------------------------------------------+
-- | CLOSING ANY LOB IS MANDATORY IF YOU HAVE OPENED IT |
-- +-------------------------------------------------------------+
DBMS_LOB.CLOSE(dest_loc);
DBMS_LOB.CLOSE(src_loc);
COMMIT;
END;
/ |
|
BEGIN
FOR i IN 1 .. 1000
LOOP
Load_BLOB_From_File_Image();
END LOOP;
END;
/
PL/SQL procedure successfully completed.
SELECT count(1) FROM test_lob;
COUNT(1)
----------
1000 |
SELECT table_name, column_name, segment_name, a.bytes
FROM dba_segments a JOIN dba_lobs b
USING (owner, segment_name)
WHERE b.table_name = 'TEST_LOB';
TABLE_NAME COLUMN_NAME SEGMENT_NAME BYTES
------------ -------------- ---------------------------- ----------
TEST_LOB IMAGE SYS_LOB0000054349C00003$$ 25,165,824
SELECT NVL((SUM(DBMS_LOB.GETLENGTH(image))),0) AS BYTES
FROM test_lob;
BYTES
----------
16,706,000 |
DELETE FROM test_lob;
1000 rows deleted.
COMMIT;
Commit complete.
SELECT table_name, column_name, segment_name, a.bytes
FROM dba_segments a JOIN dba_lobs b
USING (owner, segment_name)
WHERE b.table_name = 'TEST_LOB';
TABLE_NAME COLUMN_NAME SEGMENT_NAME BYTES
------------ -------------- ---------------------------- ----------
TEST_LOB IMAGE SYS_LOB0000054349C00003$$ 25,165,824
SELECT NVL((SUM(DBMS_LOB.GETLENGTH(image))),0) AS BYTES
FROM test_lob;
BYTES
----------
0 |
BEGIN
FOR i IN 1 .. 1000
LOOP
Load_BLOB_From_File_Image();
END LOOP;
END;
/
PL/SQL procedure successfully completed.
SELECT count(1) FROM test_lob;
COUNT(1)
----------
1000
SELECT table_name, column_name, segment_name, a.bytes
FROM dba_segments a JOIN dba_lobs b
USING (owner, segment_name)
WHERE b.table_name = 'TEST_LOB';
TABLE_NAME COLUMN_NAME SEGMENT_NAME BYTES
------------ -------------- ---------------------------- ----------
TEST_LOB IMAGE SYS_LOB0000054349C00003$$ 50,331,648
SELECT NVL((SUM(DBMS_LOB.GETLENGTH(image))),0) AS BYTES
FROM test_lob;
BYTES
----------
16,706,000 |
DELETE FROM test_lob;
1000 rows deleted.
COMMIT;
Commit complete.
ALTER TABLE test_lob MODIFY LOB (image) (SHRINK SPACE);
Table altered.
SELECT table_name, column_name, segment_name, a.bytes
FROM dba_segments a JOIN dba_lobs b
USING (owner, segment_name)
WHERE b.table_name = 'TEST_LOB';
TABLE_NAME COLUMN_NAME SEGMENT_NAME BYTES
------------ -------------- ---------------------------- ----------
TEST_LOB IMAGE SYS_LOB0000054349C00003$$ 65,536
SELECT NVL((SUM(DBMS_LOB.GETLENGTH(image))),0) AS BYTES
FROM test_lob;
BYTES
----------
0 |
Troubleshooting
The alter table <table_name> shrink space statement
was introduced in Oracle 10g R1.
The ability to extend the SHRINK SPACE command to LOBs was introduced
in Oracle 10g R2 - the focus of this article.
This new feature allows users to remove the deleted and free space
altogether from a LOB segment and LOB index.
The LOB segment must reside in an ASSM tablespace.
Row movement on a table is only required if you are
moving rows from the table itself. It is not required
if all you are doing is shrinking its LOB segment(s).
With Oracle 10g R1, when shrinking a table, the CASCADE option
DOES NOT shrink LOB segments for that table.
With Oracle 10g R2 and higher, when shrinking a table, the CASCADE option
DOES shrink all LOB segments (and indexes) for that table.
Copyright (c) 1998-2012 Jeffrey M. Hunter. All rights reserved.
All articles, scripts and material located at the Internet address of http://www.idevelopment.info is the copyright of Jeffrey M. Hunter
and is protected under copyright laws of the United States. This document may not be hosted on any other site without my express,
prior, written permission. Application to host any of the material elsewhere can be made by contacting me at jhunter@idevelopment.info.
I have made every effort and taken great care in making sure that the material included on my web site is technically accurate,
but I disclaim any and all responsibility for any loss, damage or destruction of data or any other property which may arise from
relying on it. I will in no case be liable for any monetary damages arising from such loss, damage or destruction.
Shrinking a LOB segment does generate redo. For example, shrinking
a 36GB LOB will generate approximately 36GB of redo! Make certain
you have an adequate amount of disk space for any archived redo log
files before manually shrinking a LOB segment.
The alter table <table_name> shrink space statement
has an optional CASCADE clause that shrinks all dependent objects
(including LOBS) along with the table data itself. For example:
ALTER TABLE test_lob ENABLE ROW MOVEMENT;
Table altered.
ALTER TABLE test_lob SHRINK SPACE CASCADE;
Table altered.
Saturday, 18-Sep-2010 17:38:20 EDT
Page Count: 19094