Lob sample Codes
Secure file Lob space
set linesize 32000
set pagesize 1000
set long 2000000000
set longchunksize 1000
set head off;
set verify off;
set termout off;
column u new_value us noprint;
column n new_value ns noprint;
select name n from v$database;
select user u from dual;
set sqlprompt &ns:&us>
set head on
set echo on
set termout on
set trimspool on
set timing on
set autotrace on
set serveroutput on size 1000000
spool &ns.lobspace.log
declare
-- parameters to update:
tabowner varchar2(30) := 'MYOWNER';
tabname varchar2(30) := 'MYTABLE';
lobcolumn varchar2(30) := 'MYLOBCOLUMN';
inlinecutoff number := 3964;
usableperblock number := 8132;
-- rest of variables
query varchar2(1000);
TYPE LenCurTyp IS REF CURSOR;
len_cursor LenCurTyp;
lob_size number;
lobsegment varchar2(30);
lobsegsize number;
unformatted_blocks NUMBER;
unformatted_bytes NUMBER;
fs1_blocks NUMBER;
fs1_bytes NUMBER;
fs2_blocks NUMBER;
fs2_bytes NUMBER;
fs3_blocks NUMBER;
fs3_bytes NUMBER;
fs4_blocks NUMBER;
fs4_bytes NUMBER;
full_blocks NUMBER;
full_bytes NUMBER;
row_count number := 0;
inline_count number := 0;
lobseg_count number := 0;
roundedupsize number;
totalinlobsegsize number := 0;
begin
-- get lob segment name
select segment_name into lobsegment
from dba_lobs
where
owner = tabowner and
table_name=tabname;
-- get size of lob segment
select bytes into lobsegsize
from dba_segments
where
owner = tabowner and
segment_name=lobsegment;
-- get number of full blocks in lob segment
DBMS_SPACE.SPACE_USAGE(tabowner, lobsegment, 'LOB',
unformatted_blocks ,
unformatted_bytes ,
fs1_blocks ,
fs1_bytes ,
fs2_blocks ,
fs2_bytes ,
fs3_blocks ,
fs3_bytes ,
fs4_blocks ,
fs4_bytes ,
full_blocks ,
full_bytes
);
-- loop through rows getting lob sizes
query := 'select dbms_lob.getlength('||lobcolumn||') len from '||tabowner||'.'||tabname;
OPEN len_cursor FOR query;
LOOP
FETCH len_cursor INTO lob_size;
EXIT WHEN len_cursor%NOTFOUND;
row_count := row_count + 1;
if lob_size is null then
lob_size := 0;
end if;
if lob_size <= inlinecutoff then
inline_count := inline_count + 1;
else
lobseg_count := lobseg_count + 1;
roundedupsize := usableperblock * ceil(lob_size/usableperblock);
totalinlobsegsize := totalinlobsegsize + roundedupsize;
end if;
END LOOP;
CLOSE len_cursor;
-- final output
dbms_output.put_line('--------------------------------------');
dbms_output.put_line('Table owner = '||tabowner);
dbms_output.put_line('Table name = '||tabname);
dbms_output.put_line('LOB column name = '||lobcolumn);
dbms_output.put_line('--------------------------------------');
dbms_output.put_line('Number of rows in table = '||to_char(row_count));
dbms_output.put_line('Number of rows with lob in table row = '||to_char(inline_count));
dbms_output.put_line('Number of rows with lob in lob segment = '||to_char(lobseg_count));
dbms_output.put_line('Total lob segment size = '||to_char(lobsegsize/(1024*1024))||' megabytes');
dbms_output.put_line('Total size of full lob segment blocks = '||to_char((full_blocks*usableperblock)/(1024*1024))||' megabytes');
dbms_output.put_line('Total lob space used in lob segment = '||to_char(totalinlobsegsize/(1024*1024))||' megabytes');
dbms_output.put_line('--------------------------------------');
dbms_output.put_line('Percentage of full blocks used = '||to_char(trunc((100*totalinlobsegsize)/(full_blocks*usableperblock)))||'%');
end;
/
spool off
CREATE TABLESPACE "LOBTEST"
LOGGING
DATAFILE 'E:\APPS\ORACLE\ORADATA\ORA92DB\LOBTEST.ORA' SIZE
10M REUSE EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT
AUTO;
create table t ( x blob );
declare
l_blob blob;
l_size number := 31191-7;
begin
insert into t values ( empty_blob() ) returning x into l_blob;
for i in 1 .. 15
loop
dbms_lob.writeappend( l_blob, l_size, utl_raw.cast_to_raw(rpad('*',l_size,'*')) );
l_size := 31191;
end loop;
commit;
end;
/
CREATE TABLE "LOB_TAB" ("THEBLOB" BLOB)
TABLESPACE "LOBTEST"
PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255
STORAGE ( INITIAL 64K NEXT 0K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0)
LOGGING LOB("THEBLOB") STORE AS
( TABLESPACE "LOBTEST" STORAGE ( INITIAL 64K NEXT 0K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0)
ENABLE STORAGE IN ROW NOCACHE CHUNK 8192 PCTVERSION 10);
declare
l_blob blob;
l_src blob;
l_bytes number;
begin
select x into l_src from t;
for i in 1 .. 15
loop
execute immediate 'truncate table lob_tab';
insert into lob_tab (theblob)
values ( empty_blob() )
returning theblob into l_blob;
dbms_lob.copy( l_blob, l_src, i * 32765 );
commit;
l_bytes := 0;
for x in
( select segment_name || ' extent id ' ||
extent_id || ' bytes ' || bytes data, bytes
from dba_extents
where tablespace_name = 'LOBTEST'
and segment_type = 'LOBSEGMENT'
order by segment_name, segment_type, extent_id )
loop
dbms_output.put_line( x.data );
l_bytes := l_bytes + x.bytes;
end loop;
dbms_output.put_line( 'l_blob = ' || dbms_lob.getlength(l_blob) ||
' bytes, allocated = ' || l_bytes ||
' pct used = ' ||
round(dbms_lob.getlength(l_blob)/l_bytes * 100,2 ) );
dbms_output.put_line( rpad('-',70,'-') );
end loop;
end;
/
begin
for i in 1 .. 7
loop
insert into lob_tab(theBlob) select x from t;
end loop;
commit;
end;
/
Test Program
-- Create table and SP
CREATE TABLE test_lob (id NUMBER, file_name VARCHAR2(45), image BLOB, timestamp DATE);
CREATE SEQUENCE test_lob_seq;
CREATE OR REPLACE DIRECTORY images_dir AS <some directory path having an image file>;
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 INTO test_lob (id, file_name, image, timestamp)
VALUES (test_lob_seq.nextval, file_name, empty_blob(), sysdate)
RETURNING image INTO dest_loc;
DBMS_LOB.OPEN(src_loc, DBMS_LOB.LOB_READONLY);
DBMS_LOB.OPEN(dest_loc, DBMS_LOB.LOB_READWRITE);
DBMS_LOB.LOADFROMFILE(
dest_lob => dest_loc
, src_lob => src_loc
, amount => DBMS_LOB.getLength(src_loc));
DBMS_LOB.CLOSE(dest_loc);
DBMS_LOB.CLOSE(src_loc);
COMMIT;
END;
-- Insert 1000 rows
BEGIN
FOR i IN 1 .. 1000
LOOP
Load_BLOB_From_File_Image();
END LOOP;
END;
-- find usage size
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';
-- Insert 1000 rows
BEGIN
FOR i IN 1 .. 1000
LOOP
Load_BLOB_From_File_Image();
END LOOP;
END;
- Explicit shrink
ALTER TABLE test_lob MODIFY LOB (image) (SHRINK SPACE);
-- find usage size
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';
Bug 26729494: LOB Segment Consuming Excessive Space Due To Expired Blocks After Applied DBBP 12.1.0.2.170418 (Doc ID 2478732.1)
References:
https://asktom.oracle.com/ords/asktom.search?tag=reclaimreuse-lob-space
https://abdul-hafeez-kalsekar-tuning.blogspot.com/2024/02/lob-space-not-released-after-delete-doc.html
Comments
Post a Comment