Redefinir una tabla en línea con DBMS_REDEFINITION (flujo completo)
OracleOperaciones en líneaComando
-- 1) Is it eligible? (use CONS_USE_ROWID if there is no PK)
EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('CUSTOMER_APP', 'CUSTOMER', DBMS_REDEFINITION.CONS_USE_PK);
-- 2) Interim table with the target structure: hash partitioned in this example
CREATE TABLE customer_app.customer_int (
id NUMBER, name VARCHAR2(100), city VARCHAR2(30))
PARTITION BY HASH (id) PARTITIONS 8;
-- 3) Start: initial copy + change tracking through an MV log
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(
uname => 'CUSTOMER_APP',
orig_table => 'CUSTOMER',
int_table => 'CUSTOMER_INT',
col_mapping => NULL,
options_flag => DBMS_REDEFINITION.CONS_USE_PK);
END;
/
-- 4) Copy indexes, constraints, triggers, grants and statistics:
SET SERVEROUTPUT ON
DECLARE
l_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(
uname => 'CUSTOMER_APP',
orig_table => 'CUSTOMER',
int_table => 'CUSTOMER_INT',
copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS,
copy_triggers => TRUE,
copy_constraints => TRUE,
copy_privileges => TRUE,
ignore_errors => FALSE,
num_errors => l_errors,
copy_statistics => TRUE);
DBMS_OUTPUT.PUT_LINE('Error count: ' || l_errors);
END;
/
SELECT object_name, base_table_name, ddl_txt FROM dba_redefinition_errors;
-- 5) Close the gap before finishing (shortens finish; can be run several times):
EXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE('CUSTOMER_APP', 'CUSTOMER', 'CUSTOMER_INT');
-- 6) Swap under a short lock:
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('CUSTOMER_APP', 'CUSTOMER', 'CUSTOMER_INT', dml_lock_timeout => 60);
-- 7) Drop the interim table, which now holds the old structure:
DROP TABLE customer_app.customer_int PURGE;
-- On problems: EXEC DBMS_REDEFINITION.ABORT_REDEF_TABLE('CUSTOMER_APP', 'CUSTOMER', 'CUSTOMER_INT');
-- Status: SELECT * FROM dba_redefinition_status WHERE base_table_owner = 'CUSTOMER_APP';Qué hace
Cambia la estructura de una tabla (particionamiento, tipos/orden de columnas, tablespace, compresión, configuración de LOB) mientras la aplicación sigue funcionando: los datos se copian a una tabla intermedia, los cambios se sincronizan mediante un MV log y al final se intercambian los nombres bajo un bloqueo muy breve.
Cuándo usarlo
Para cambios que ALTER TABLE no puede hacer en línea, como particionar una tabla grande no particionada sin tiempo de inactividad, cambiar el tipo de una columna o convertir LOB BasicFile a SecureFiles.
Precaución
Requiere Enterprise Edition (más la opción Partitioning si el destino está particionado). El proceso necesita el doble del espacio de la tabla y añade sobrecarga de redo y de MV log. FINISH toma un breve bloqueo exclusivo; las transacciones largas lo hacen esperar (dml_lock_timeout). Revise siempre los errores de COPY_TABLE_DEPENDENTS en DBA_REDEFINITION_ERRORS; las FK pueden copiarse como NOVALIDATE. Ensáyelo primero en un entorno de pruebas.