Migration of LOBs to SecureFiles (online redefinition)

1) Создаем таблицы с BasicFile LOB и загружаем туда файлы из ОС (FBILE).


create table t1
(
  id   NUMBER constraint pk_t1 primary key,
  vlob BLOB
) tablespace FRX pctfree 1;

2) Загружаем BLOB в таблицу t1.

declare
   Dest_loc       BLOB    := NULL;
   Src_loc        BFILE   := NULL;
   Amount         INTEGER := DBMS_LOB.getlength(Src_loc);
BEGIN
  delete from t1;
  commit;
   DBMS_LOB.CREATETEMPORARY(Dest_loc, TRUE);

   for ds in (select rownum as fn from dual connect by rownum<=17) loop
    Src_loc := BFILENAME('DATA_PUMP_DIR', ds.fn||'.JPG');
     DBMS_LOB.OPEN(Src_loc,  DBMS_LOB.LOB_READONLY);
     DBMS_LOB.OPEN(Dest_loc, DBMS_LOB.lob_readwrite);
     Amount := dbms_lob.getlength(Src_loc);
     dbms_output.put_line('Size ['||ds.fn||'.JPG'||'] = '||to_char(Amount)||' bytes.');
     
     DBMS_LOB.LOADFROMFILE(Dest_loc, Src_loc, Amount);
     insert into t1(id,vlob) values(ds.fn,Dest_loc);
     commit;

   DBMS_LOB.CLOSE(Dest_loc);
   DBMS_LOB.CLOSE(Src_loc);
   commit;
   end loop;
END;

Size [1.JPG] = 960761 bytes.
Size [2.JPG] = 893478 bytes.
Size [3.JPG] = 1038031 bytes.
Size [4.JPG] = 1005522 bytes.
Size [5.JPG] = 1023496 bytes.
Size [6.JPG] = 938197 bytes.
Size [7.JPG] = 943824 bytes.
Size [8.JPG] = 922090 bytes.
Size [9.JPG] = 907578 bytes.
Size [10.JPG] = 916900 bytes.
Size [11.JPG] = 1005522 bytes.
Size [12.JPG] = 1023496 bytes.
Size [13.JPG] = 938197 bytes.
Size [14.JPG] = 943824 bytes.
Size [15.JPG] = 922090 bytes.
Size [16.JPG] = 907578 bytes.
Size [17.JPG] = 916900 bytes.

3) Смотрим на сегмент с LOB.

clear;
column TABLE_NAME format a12
column SEGMENT_NAME format a27
select l.TABLE_NAME,s.segment_name,s.BYTES,s.segment_type,s.segment_subtype,
       l.COMPRESSION
  from dba_segments s, user_lobs     l
 where l.table_name='T1' and
       l.SEGMENT_NAME = s.segment_name;

TABLE_NAME   SEGMENT_NAME                     BYTES SEGMENT_TYPE       SEGMENT_SUBTYPE COMPRESSION
------------ --------------------------- ---------- ------------------ --------------- -----------
T1           SYS_LOB0000127906C00002$$     18874368 LOBSEGMENT         ASSM            NONE

3) Создаем таблицу такой же структуры, без ПК, для redefinition.

create table t2
(
  id   NUMBER,
  vlob BLOB
) tablespace FRX pctfree 1
   lob(vlob) store as securefile(compress HIGH deduplicate cache);

4) Делаем процедуру redefinition

declare
  l_col_mapping varchar2(1000);
begin
  l_col_mapping :=
     'id id , '||
     'vlob vlob';
     dbms_redefinition.start_redef_table('EXAM', 'T1', 'T2', l_col_mapping);
end;

declare
   l_error_count pls_integer := 0;
begin
   dbms_redefinition.copy_table_dependents
   ('EXAM', 'T1', 'T2',1, TRUE, TRUE, TRUE, FALSE, l_error_count);
   dbms_output.put_line('Errors Occurred := ' || to_char(l_error_count));
end;

begin  
 dbms_redefinition.finish_redef_table('EXAM', 'T1', 'T2');
end;

drop materialized view exam.t2

5) Смотрим результат

TABLE_NAME   SEGMENT_NAME                     BYTES SEGMENT_TYPE       SEGMENT_SUBTYPE COMPRESSION
------------ --------------------------- ---------- ------------------ --------------- -----------
T1           SYS_LOB0000127917C00002$$     13828096 LOBSEGMENT         SECUREFILE      HIGH