Logo Oracle Deutschland August 2016
Edition Based Redefinition (EBR): Editionen in der Datenbank?
Ulrike Schwinn

Was steckt hinter dem Feature Edition Based Redefinition (auch kurz EBR)? Kann man damit die Datenbank versionieren? Was muss man tun, um das Feature zu verwenden? Solche und ähnliche Fragen erhalte ich in den letzten Monaten häufiger. Gleich vorweg: Möchte man sich allumfassend in das Thema einarbeiten, empfehle ich die Lektüre der Handbücher oder/und das White Paper von Bryn Llewellyn, Product Manager für PL/SQL und EBR (siehe Informationen unten). Obwohl das White Paper selbst noch auf dem Stand von 11g Release 2 ist, gibt es einen ausgezeichneten und ausführlichen Überblick über das Thema.

Worum handelt es sich nun bei Edition Based Redefinition? Edition Based Redefinition ist ein Feature der Datenbank 11g Release 2, um ein Online Application Upgrade zu unterstützen. Die Technik steht sofort nach der Installation ohne weiteres Setup für alle Editionen der Datenbank zur Verfügung. Bei EBR geht es in erster Linie um die Verfügbarkeit der Datenbank, bei der Überführung einer "alten" Version (Pre Upgrade) in eine "neue" Version (Post Upgrade). Trotz Veränderungen an der Datenbank sollen Anwender ununterbrochen mit ihren Applikationen weiterarbeiten können.

Wenn man über Veränderungen in der Datenbank spricht, unterscheidet man bei EBR folgende drei Fälle:

  1. Veränderungen an PL/SQL Objekten, Views oder Synonymen - auch "editioned objects"
  2. Veränderungen an der Tabellenstruktur (auch Redefinition), aber nicht an den zugehörigen Daten
  3. Veränderungen an der Tabellenstruktur und Änderungen an den zughörigen Daten
Drei neue Strukturen sind notwendig um allen Anforderungen (Fall 1 bis Fall 3) zu genügen: Editionen, Editioning Views und Cross Edition Trigger.

Eine Edition stellt eine private Umgebung dar, in der Datenbankobjekte geändert werden können. Datenbankobjekte wie zum Beispiel PL/SQL Prozeduren, die von einem "editionable" Typ sind, können dabei versioniert ("editioned") werden. Das bedeutet, es können unterschiedliche Versionen eines Objekts in verschiedenen Editionen existieren und im Zugriff sein. In der aktuellen Datenbankversion sind folgende Objekttypen "editionable": Die Verwendung von Editionen ist also vollkommen ausreichend, wenn es sich nur um Änderungen an sogenannten "editioned objects" handelt.

Andere Objekte wie Tabellen, die von einen "non editionable" Typ sind (also "non editioned" objects), sind nicht änderbar und identisch in allen Editionen. Letztere benötigen daher ein zusätzliches Konstrukt bei Änderungen (auch Redefinitionen) - die sogenannten Editioning Views (siehe Fall 2). Eine Editioning View - im Gegensatz zu einer "normalen " View - hat dabei nur die Aufgabe eine Untermenge (der zu ändernden Basistabelle) zur Verfügung zu stellen. Daher gibt es auch einige Einschränkungen, die bei der Verwendung zu beachten sind.

Werden noch wie in Fall 3 Datenänderungen an den redefinierten Tabellenstrukturen vorgenommen, sind sogenannte Crossedition Trigger erforderlich. Spezielle "Forward" bzw. "Reverse" Crossedition Trigger stellen dabei sicher, dass User ohne Unterbrechung weiterhin in der "alten" und "neuen" Edition arbeiten können.

Um den Blogeintrag nicht zu sprengen, werden wir uns auf den einfachsten Fall - Fall 1 - konzentrieren und mit einem simplen Beispiel starten. Meine Ausführungen sind dabei in 11g Release 2 und 12c Umgebungen verwendbar.

Ein einfaches Beispiel

Im folgenden Beispiel, das exemplarisch für Fall 1 stehen soll, wird eine simple PL/SQL Prozedur in zwei verschiedenen Ausführungen unter dem gleichen Namen verfügbar gemacht. PL/SQL Stored Procedures sind, wie oben schon erwähnt, von einem "editionable object type", somit reicht die Verwendung von Editionen aus.

Zuerst wird die PL/SQL Prozedur TEST1 in der aktuellen Umgebung, der Default Edition, erzeugt. Mit der Funktion SYS_CONTEXT lässt sich dabei leicht die Umgebung überprüfen.

SQL> connect scott/tiger
Connected.
SQL> select sys_context('userenv','current_edition_name') edition from dual;

EDITION
---------------
ORA$BASE

SQL> create or replace procedure test1
     as
     begin dbms_output.put_line('dies ist version1');
     end;
/
Procedure created.

SQL> set serveroutput on

SQL> execute test1
dies ist version1

PL/SQL procedure successfully completed.                 

Nun wird eine weitere Edition zur Verfügung gestellt, dazu ist das CREATE ANY EDITION System Privileg erforderlich. Damit der User SCOTT mit der neuen Edition arbeiten kann, muss die Edition für den User verfügbar sein (siehe USE ON EDITION Privileg). Zusätzlich muss der User die Eigenschaft "Editioned Enabled" über ein CREATE oder ALTER USER Kommando erhalten.

SQL> connect / as sysdba
Connected.

SQL> create edition version1 as child of ora$base;
Edition created.

SQL> alter user scott ENABLE EDITIONS;
User altered.

SQL> select username from dba_users where editions_enabled='Y';

USERNAME
--------------------
HR
SCOTT

SQL> grant USE ON EDITION version1 to scott;
Grant succeeded.
Nun verbindet sich User SCOTT mit der Edition VERSION1 über das ALTER SESSION Kommando und stellt eine veränderte Stored Procedure unter dem gleichen Namen zur Verfügung.
SQL> connect scott/tiger
Connected.

SQL> alter session SET EDITION = version1;
Session altered.

SQL> select sys_context('userenv', 'current_edition_name') edition from dual;
EDITION
---------------
VERSION1

SQL> create or replace procedure test1
     as
     begin dbms_output.put_line('dies ist version2');
     end;
/

SQL> set serveroutput on
SQL> execute test1
dies ist version2

PL/SQL procedure successfully completed.
Je nachdem mit welcher Edition der User SCOTT verbunden ist, kann er mit der Stored Procedure TEST1 in der Edition VERSION1 oder in der Default Edition ORA$BASE arbeiten. Es ist keine spezielle Syntax erforderlich.

Editionen

Jede Datenbank ab 11g Release 2 besitzt mindestens eine Edition mt Namen ORA$BASE - die sogenannte Default Edition. Ein Grund mehr sich dieses Konzept genauer anzuschauen. Editionen sind keine Schemaobjekte und sind eindeutig durch ihren Namen definiert. Eine Edition kann dabei genau ein "Child" haben, somit dient ORA$BASE immer als "Parent" der ersten Edition. Einen Überblick über alle verfügbaren Editionen erhält man folgendermaßen:

SQL> select EDITION_NAME, PARENT_EDITION_NAME, usable from all_editions;

EDITION_NAME         PARENT_EDITION_NAME  USA
-------------------- -------------------- ---
ORA$BASE                                  YES
VERSION1             ORA$BASE             YES                    

Editionen gelten datenbankweit. Man verbindet sich normalerweise automatisch mit einer Default Edition. Die Einstellung der Default Editionen lässt sich dabei über ein ALTER DATABASE Kommando ändern. In DATABASE_PROPERTIES wird die aktuelle Default Edition angezeigt.

SQL> select * from database_properties where PROPERTY_NAME like '%EDITION%';

PROPERTY_NAME     PROPERTY_V DESCRIPTION
----------------- ---------- ----------------------------------------
DEFAULT_EDITION   ORA$BASE   Name of the database default edition

SQL> alter database default edition = version1;
Database altered.

SQL> select * from database_properties where PROPERTY_NAME like '%EDITION%';

PROPERTY_NAME     PROPERTY_V DESCRIPTION
----------------- ---------- ----------------------------------------
DEFAULT_EDITION   VERSION1   Name of the database default edition

SQL> alter database default edition = ora$base;
Database altered.
Möchte man sich mit einer anderen als der Default Edition verbinden, kann man ein ALTER SESSION Kommando oder einen speziellen Net Servicenamen nutzen. Net Servicenamen können beispielsweise über das Package DBMS_SERVICE (im Single Instance Fall) oder über SRVCTL mit einer Edition (in allen anderen Fällen) verbunden werden. Im folgenden wird der Service EDITION_V1 mit der Edition VERSION1 in Verbindung gebracht.
srvctl modify service -s edition_v1 -d orcl -edition version1
Oder aber mit DBMS_SERVICE, wie folgt ...
SQL> execute dbms_service.modify_service(service_name   => 'edition_v1', edition => 'VERSION1', modify_edition => TRUE);
PL/SQL procedure successfully completed.

SQL> select name, network_name, edition from dba_services;

NAME                 NETWORK_NAME         EDITION
-------------------- -------------------- --------------------
SYS$BACKGROUND
SYS$USERS
orclXDB              orclXDB
orcl.de.oracle.com   orcl.de.oracle.com
edition_v1           edition_v1           VERSION1
edition_v2           edition_v2           VERSION2

SQL> connect scott@edition_v1
Enter password:
Connected.

SQL> select sys_context('userenv', 'current_edition_name') edition from dual;

EDITION
--------------------------------------------------------------------------------
VERSION1
Objekte werden nun eindeutig über Owner, Objektname, Objekttyp und den Editionsnamen definiert. In der Edition VERSION1 gibt es beispielsweise zwei Prozeduren - TEST1 und TEST2_V1. Datenbanktabellen und alle Objekte von "non editionable type" gehören keiner Edition an. Die Eigenschaft "editionable" der aktuellen Objekte lässt sich im Data Dictionary über USER_OBJECTS anzeigen.
SQL> select object_name, object_type, edition_name, editionable, status from user_objects;

OBJECT_NAME     OBJECT_TYPE             EDITION_NAME    E
--------------- ----------------------- --------------- -
...
T               PROCEDURE               ORA$BASE        Y
TEST            PROCEDURE               ORA$BASE        Y
TEST1           PROCEDURE               VERSION1        Y
TESTLOAD        TABLE
TEST_ADD        TABLE
TEST_EMP        TABLE
TEST_LOB        TABLE
TEST_TAB        TABLE
TEST_TAB_PK     INDEX
TEST2_V1        PROCEDURE               VERSION1        Y
U               TABLE
WAIT_TEST       PROCEDURE               ORA$BASE        Y
...
Im Vergleich dazu führen wir nun ein Abfrage auf die View USER_OBJECTS_AE (AE für All Editions) aus. Hier wird die Prozedur TEST1 aus unserem Beispiel oben zweimal aufgeführt - einmal in der Edition ORA$BASE und einmal in der Edition VERSION1.
SQL> select object_name, object_type, edition_name, editionable, status from user_objects_ae;

OBJECT_NAME     OBJECT_TYPE             EDITION_NAME    E
--------------- ----------------------- --------------- -
...
T               PROCEDURE               ORA$BASE        Y
TEST            PROCEDURE               ORA$BASE        Y
TEST1           PROCEDURE               ORA$BASE        Y
TEST1           PROCEDURE               VERSION1        Y
TESTLOAD        TABLE
TEST_ADD        TABLE
TEST_EMP        TABLE
TEST_LOB        TABLE
TEST_TAB        TABLE
TEST_TAB_PK     INDEX
TEST2_V1        PROCEDURE               VERSION1        Y
U               TABLE
WAIT_TEST       PROCEDURE               ORA$BASE        Y
...
Views mit Suffix "_AE" enthalten die gleichen Spalten wie ihre Counterparts, beinhalten aber alle Vorkommen der "Editioned" Objekte. Somit gibt es zwei Versionen von TEST1; TEST2_V1 hingegen existiert nur in Edition VERSION1. Wollen wir genauere Informationen über den Source Code erhalten, bietet sich die View USER_SOURCE_AE an. Sie listet den Sourcecode der Prozedur TEST1 in Edition ORA$BASE und VERSION1.
col edition_name format a10 
col text format a60
break on edition_name 
select edition_name, text from user_source_ae where name='TEST1';

EDITION_NA TEXT
---------- ------------------------------------------------------------
ORA$BASE   procedure test1
                as
                begin dbms_output.put_line('dies ist version1');
                end;
VERSION1   procedure test1
                as
                begin dbms_output.put_line('dies ist version2');
                end;

8 rows selected.
Views mit Suffix "_AE" gibt es übrigens für alle Objekt relevanten Data Dictionary Views.

Berücksichtigen Sie bitte beim Arbeiten in mehreren Editionen immer die Abhängigkeiten der "Editioned" Objekte voneinander und ihr Auftreten in den verschiedenen Editionen. Ein Beispiel: Nehmen wir an, es existiert eine View in der Edition VERSION1, dann kann diese View nur in VERSION1 und folgenden "Child" Editionen genutzt werden, allerdings nicht in ORA$BASE, weil sie dort nicht vorkommt. Folgende Ausführung demonstriert das Verhalten.
SQL> connect scott/tiger
Connected.

SQL> alter session set edition=version1;
Session altered.

SQL> create view view_version1_emp as select * from emp;
View created.

SQL> select object_name, object_type, edition_name, editionable, status 
     from user_objects_ae where object_name like '%VERSION1%';

OBJECT_NAME               OBJECT_TYPE             EDITION_NAME    E STATUS
------------------------- ----------------------- --------------- - -------
VIEW_VERSION1_EMP         VIEW                    VERSION1        Y VALID
TEST_VERSION1             PROCEDURE               VERSION1        Y VALID

SQL> connect scott/tiger
Connected.
SQL> create view view_from_version1 as select * from VIEW_VERSION1_EMP;
create view view_from_version1 as select * from VIEW_VERSION1_EMP
                                                *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> alter session set edition= version2;
Session altered.

SQL> create view view_from_version1 as select * from VIEW_VERSION1_EMP;
View created.
Am Schluss noch die Frage: Wie kann man eine Edition löschen? Um eine Edition zu löschen, entfernt man zuerst das USE Privileg aller User von dieser Edition, so dass kein User mehr damit arbeiten kann. Dies nennt man auch Stillegen (Retire) der Edition. Falls Sie eine Default Edition stillegen wollen, müssen Sie zuerst die Default Edition verlagern bzw. ändern. Danach kann man die Edition mit DROP EDITION name [CASCADE] löschen. Bitte beachten Sie dabei die existierenden Implikationen und Einschränkungen aus dem Handbuch (DROP EDITION) und berücksichtigen Sie die Abhängigkeiten der Objekte der Editionen untereinander.

Folgendes Bild (Quelle White Paper) zeigt eine Situation, wie sie sich nach einigen Edition Based Redefinition Vorgängen ergeben kann.

Gestartet wurde mit Edition e1, die Änderungen wurden in e2 bis Edition e4 fortgeführt. Nachdem die Objekte in e1 und e2 nicht mehr verwendet wurden, wurde Edition e1 und e2 stillgelegt. Am Ende sehen Sessions, die mit e4 verbunden sind, die aktuelle Version von der View v2 und die vererbten Versionen der Prozeduren p1 und p2. Da die View v1 gelöscht wurde, ist sie für die Sessions nicht mehr sichtbar. Die Tabelle t1 bleibt natürlich für alle Sessions gleichermaßen bestehen und im Zugriff.

Schlußbemerkungen

Auch wenn es nirgendwo explizit erwähnt wurde: das EBR Konzept ist gleichermaßen in allen Oracle Architekturen wie Multitenant oder Non-CDB usw. verfügbar. Das bedeutet in einer Multitenant Container Datenbank (CDB), ist der Gültigkeitsbereich für die Konzepte wie Editionen, Editioning View oder Crossedition Trigger die Pluggable Database (PDB), in welcher sie erzeugt wurden. In einer Non-CDB bezieht sich der Gültigkeitsbereich auf die gesamte Datenbank. Aktuell wird EBR übrigens zum Online Patching der E-Business Suite Release 12.2 verwendet.

Die einfachste Verwendung von Edition Based Redefinition ist dabei die gezeigte - über versionierbare (editioned) Objekte. Sobald eine Redefinition von Tabellen und laufenden Transaktionen mitberücksichtigt werden müssen, steigt der Komplexitätsgrad (siehe Fall 2 und Fall 3). Weitere Vorbereitungen wie Editioning Views und Crossedition Trigger werden erforderlich. Obwohl das Thema hauptsächlich im Database Development Guide dokumentiert wird, erfordert ein erfolgreiches Projekt in jedem Fall eine enge Abstimmung von Datenbankadministratoren und Datenbankentwicklern. Mein Tipp: Starten Sie am Besten mit dem Anlegen und der Verwendung von Editionen, um sich in das Thema einzuarbeiten.

Hinweis zur Lizenzierung

EBR ist in allen Editionen (Standard und Enterprise) und Cloudangeboten der Datenbank ab Oracle Database 11g Release 2 verfügbar. Keine zusätzliche Lizenzierung ist erforderlich.

Weitere Informationen

 

Zurück zum Anfang des Artikels

Zurück zur Community-Seite