This note will demonstrate how to convert BasicFiles to SecureFiles and SecureFiles to BasicFiles
SOLUTION
The following reference discusses conversion TO Securefiles FROM BasicFIles ...
Oracle Database SecureFiles and Large Objects Developer's Guide 11g Release 1 (11.1) Part Number B28393-03
4 Using Oracle SecureFiles
Example 4-1 Example of Online Redefinition
The reverese of the method may be used to convert from SecureFiles
The following example is a modified version of the example from the above reference
Convert to SecureFiles from Basicfiles
connect / as sysdba
create user pm identified by pm;
GRANT EXECUTE ON DBMS_REDEFINITION TO pm;
GRANT ALTER ANY TABLE TO pm;
GRANT DROP ANY TABLE TO pm;
GRANT LOCK ANY TABLE TO pm;
GRANT CREATE ANY TABLE TO pm;
GRANT SELECT ANY TABLE TO pm;
GRANT CREATE SESSION TO pm;
ALTER USER pm QUOTA UNLIMITED ON <default tablespace>;
--Privileges required to perform cloning of dependent objects.
GRANT CREATE ANY TRIGGER TO pm;
GRANT CREATE ANY INDEX TO pm;
CONNECT pm/pm
-- CREATE OUR TABLE TO BE CONVERTED TO SECUREFILE
CREATE TABLE cust (
c_id NUMBER PRIMARY KEY,
c_zip NUMBER,
c_name VARCHAR(30) DEFAULT NULL,
c_lob CLOB
);
-- INSERT A ROW INTO THIS TABLE
INSERT INTO cust VALUES (1, 94065, 'hhh', 'ttt');
COMMIT;
-- CREATE OUR 'INTERIM' TABLE
CREATE TABLE cust_int (
c_id NUMBER NOT NULL,
c_zip NUMBER,
c_name VARCHAR(30) DEFAULT NULL,
c_lob CLOB
) LOB(c_LOB) STORE AS SECUREFILE (NOCACHE FILESYSTEM_LIKE_LOGGING);
-- START THE REDEFINITION
DECLARE
col_mapping VARCHAR2(1000);
BEGIN
-- map all the columns in the interim table to the original table
col_mapping := 'c_id c_id , '|| 'c_zip c_zip , '|| 'c_name c_name, '|| 'c_lob c_lob';
DBMS_REDEFINITION.START_REDEF_TABLE('pm', 'cust', 'cust_int', col_mapping);
END;
/
-- COPY THE CONSTRAINTS FROM OUR ORIGINAL TABLE ... TO THE INTERIM TABLE
DECLARE
error_count pls_integer := 0;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('pm', 'cust', 'cust_int', dbms_redefinition.cons_orig_params, TRUE,TRUE,TRUE,FALSE, error_count);
DBMS_OUTPUT.PUT_LINE('errors := ' || TO_CHAR(error_count));
END;
/
-- KEEPS THE INTERIM TABLE SYNCHRONIZED WITH THE ORIGINAL TABLE.
BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE('pm', 'cust', 'cust_int');
END;
/
-- FINISH OUR REDEFINITION WHICH WILL SWAP THE ORIGINAL TABLE AND THE INTERIM TABLE
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('pm', 'cust', 'cust_int');
-- DROP THE INTERIM TABLE (THE FORMER ORIGINAL TABLE)
DROP TABLE cust_int;
-- TRY TO INSERT A ROW INTO OUR NEW SECUREFILE TABLE TO PROVE THAT THE PRIMARY KEY WAS PROPERLY MOVED
INSERT INTO cust VALUES(1, 94065, 'hhh', 'ttt');
-- VERIFY THAT OUR NEW TABLE IS NOW USING SecureFiles
SELECT SECUREFILE FROM USER_LOBS WHERE TABLE_NAME = 'CUST';
Convert to Basicfiles from SecureFiles
-- CREATE OUR 'INTERIM' TABLE
-- NOTE: no SecureFile option and no primary key
CREATE TABLE cust_int (
c_id NUMBER,
c_zip NUMBER,
c_name VARCHAR(30) DEFAULT NULL,
c_lob CLOB
);
-- START THE REDEFINITION
DECLARE
col_mapping VARCHAR2(1000);
BEGIN
-- map all the columns in the interim table to the original table
col_mapping := 'c_id c_id , '|| 'c_zip c_zip , '|| 'c_name c_name, '|| 'c_lob c_lob';
DBMS_REDEFINITION.START_REDEF_TABLE('pm', 'cust', 'cust_int', col_mapping);
END;
/
-- COPY THE CONSTRAINTS FROM OUR ORIGINAL TABLE ... TO THE INTERIM TABLE
DECLARE
error_count pls_integer := 0;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('pm', 'cust', 'cust_int', dbms_redefinition.cons_orig_params, TRUE,TRUE,TRUE,FALSE, error_count);
DBMS_OUTPUT.PUT_LINE('errors := ' || TO_CHAR(error_count));
END;
/
-- KEEPS THE INTERIM TABLE SYNCHRONIZED WITH THE ORIGINAL TABLE.
BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE('pm', 'cust', 'cust_int');
END;
/
-- FINISH OUR REDEFINITION WHICH WILL SWAP THE ORIGINAL TABLE AND THE INTERIM TABLE
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('pm', 'cust', 'cust_int');
-- DROP THE INTERIM TABLE (THE FORMER ORIGINAL TABLE)
DROP TABLE cust_int;
-- TRY TO INSERT A ROW INTO OUR NEW SECUREFILE TABLE TO PROVE THAT THE PRIMARY KEY WAS PROPERLY MOVED
INSERT INTO cust VALUES(1, 94065, 'hhh', 'ttt');
-- VERIFY THAT OUR NEW TABLE IS NOW USING BasicFIles
SELECT SECUREFILE FROM USER_LOBS WHERE TABLE_NAME = 'CUST';
=======================================================
Testing internally made clear that a huge decrease in time could be achieved by transform of BasicFiles into SecureFiles even if the parallel option is still not usable.
The export of big table with clob (as SecureFile) doesn't still work in parallel. The confirmation is received from DEV in Bug 19345593 - EXPORT OF CLOB AD SECUREFILE NOT DONE IN PARALLEL, closed as not a bug due to: exporting a table with LOBs is still something that Data Pump does not allow to use parallel DML (PDML). It is being worked at and looking to fix it in 12.2 release. The unpublished documentation Bug 21256503 : DATAPUMP CAN'T USE PARALLEL DML FOR SECUREFILE LOBS, was created in order to correct 11gR2 Utilities documentation with this information.
SOLUTION
In our internal testing, the time for the export was reduced from 30 minutes to 6 minutes for 20 GB of data.
Basicfiles: 20.53 GB 8752 rows => 10:38:17 - 11:09:32 around 30 minutes
Securefiles: 20.53 GB 8752 rows => 14:30:51 - 14:36:41 around 6 minutes
The solution is transform the table to SecureFiles and then redo the export process
Here is the output of the DDL using SecureFiles: (example)
CREATE TABLE <TABLE_NAME>
( "<COLUMN1>" CHAR(36 BYTE) DEFAULT (' ') NOT NULL ENABLE,
"<COLUMN2>" BLOB,
"<COLUMN3>" DATE,
"<COLUMN4>" VARCHAR2(254 BYTE)
) SEGMENT CREATION IMMEDIATE
PCTFREE 30 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 114688 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "<TABLESPACE_NAME>"
LOB ("<COLUMN2>") STORE AS securefile (tablespace "<TABLESPACE_NAME>" cache STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645));
The idea is do an export, recreate the table using SecureFiles and then do an import.
Note: Online redefinition can be used to change a lob from BasicFile to SecureFiles as decribed in Note 728758.1 - HOW TO ONLINE CONVERT TO/FROM SECUREFILES FROM/TO BASICFILES.