DBAtlas · Atlas de operaciones de bases de datos

Redefinir una tabla en línea con DBMS_REDEFINITION (flujo completo)

OracleOperaciones en línea

Comando

-- 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.

Abrir en DBAtlas →

Relacionado