DBAtlas · Atlas für Datenbankbetrieb

Tabelle online mit DBMS_REDEFINITION umdefinieren (vollständiger Ablauf)

OracleOnline-Operationen

Befehl

-- 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';

Was es tut

Ändert die Struktur einer Tabelle (Partitionierung, Spaltentypen/-reihenfolge, Tablespace, Kompression, LOB-Einstellungen), während die Anwendung weiterläuft: Die Daten werden in eine Interimstabelle kopiert, Änderungen über ein MV-Log synchronisiert, und am Ende werden die Namen unter einer sehr kurzen Sperre getauscht.

Wann einsetzen

Für Änderungen, die ALTER TABLE nicht online ausführen kann, etwa eine große nicht partitionierte Tabelle ohne Ausfallzeit partitionieren, einen Spaltentyp ändern oder BasicFile-LOBs in SecureFiles umwandeln.

Vorsicht

Erfordert die Enterprise Edition (plus Partitioning-Option, wenn das Ziel partitioniert ist). Der Vorgang braucht den doppelten Platz der Tabelle und erzeugt zusätzlichen Redo- und MV-Log-Overhead. FINISH nimmt kurz eine exklusive Sperre; lang laufende Transaktionen lassen es warten (dml_lock_timeout). Prüfe immer die COPY_TABLE_DEPENDENTS-Fehler in DBA_REDEFINITION_ERRORS; FKs werden eventuell als NOVALIDATE kopiert. Probe es zuerst in einer Testumgebung.

In DBAtlas öffnen →

Verwandte Einträge