77 7 Transaktionsverwaltung mit Undo-Tablespaces In Kapitel 6 befassten wir uns kurz mit der Verwaltung des Speicherplatzes in einem Undo-Tablespace und untersuchten Views wie V$UNDOSTAT, die den DBA beim Überwachen und Dimensionieren des Undo-Tablespace unterstützen. In diesem Kapitel untersuchen wir die Konfigurierung und das Managen des Undo-Tablespace, und wie man widersprüchlichen Anforderungen gerecht wird; beispielsweise muss eine ausreichende Anzahl von Undos für die Lesekonsistenz zur Verfügung stehen, und gleichzeitig ist dafür zu sorgen, dass DML-Anweisungen keinesfalls scheitern, nur weil der Wert für den Retention-Parameter zu hoch ist. Zur Einführung beschäftigen wir uns kurz mit den Transaktionen aus Benutzersicht. Diese Ausführungen sollen Ihnen zeigen, wie man durch korrekt dimensionierte Undo-Tablespaces die Benutzertransaktionen unterstützt. Danach geben wir eine Übersicht über das Anlegen eines Undo-Tablespace, entweder beim Einrichten der Datenbank oder zu einem späteren Zeitpunkt mit dem bekannten create tablespaceBefehl. Undo-Segmente erfüllen für Datenbankbenutzer zahlreiche Anforderungen, die wir anschließend etwas genauer unter die Lupe nehmen. Oracle verfügt über verschiedene Möglichkeiten zur Überwachung und korrekten Dimensionierung von Undo-Tablespaces. Mit dem dbms_advisor-Package lässt sich die Nutzung des Undo-Tablespace überwachen (siehe Kapitel 6). Dieses Package werden wir etwas genauer untersuchen und zeigen, wie diese Analysen von der Oracle Enterprise Manager Database Control unterstützt werden. Der letzte große Abschnitt beschäftigt sich mit den verschiedenen Flashback-Optionen, die auf adäquat dimensionierten Undo-Tablespaces aufsetzen, und dafür sorgen, dass man aus verschiedenen Fehlersituationen zurücksetzen kann. Hier stellen wir alle wichtigen Flashback-Optionen auf Abfrage-, Tabellen- oder Transaktionsebene vor: Flashback Database wird in Kapitel 15 besprochen. 272 7 Transaktionsverwaltung mit Undo-Tablespaces Die Rollback-Segmente aus älteren Oracle-Versionen ließen sich nur schwer verwalten und wurden von den meisten DBAs entweder zu groß oder zu klein dimensioniert. Oracle empfiehlt deshalb bei allen neuen Datenbanken den Einsatz des automatischen Undo Managements, und dass nach einem Upgrade unbedingt auf diese Option konvertiert werden sollte. Das manuelle Undo-Management ist nicht Gegenstand dieses Kapitels, allerdings gehen wir kurz darauf ein, wie man von Rollback-Segmenten auf automatische Undos migriert. 7.1 Transaktionen – Grundlagen Eine Transaktion ist eine Sammlung von SQL DML-Anweisungen, die als logische Einheit behandelt werden; das Scheitern einer Anweisung in der Transaktion impliziert, dass keine der übrigen Änderungen an der Datenbank permanent festgeschrieben wird. Falls die DML-Anweisungen in der Transaktion erfolgreich ausgeführt wurden, schreiben die Applikationen oder SQL*Plus-Benutzer die Änderungen mit einem commit fest. Beim Überweisen einer Summe zwischen zwei Konten ist die Transaktion nur dann erfolgreich, wenn sowohl die Soll-Seite des einen Kontos als auch die HabenSeite des anderen Kontos aktualisiert wurde. Scheitert eine oder beide Transaktionen, wird die gesamte Transaktion ungültig. Falls nur eine der Transaktionen erfolgreich ist, und die Applikation oder ein SQL*Plus-Benutzer gibt ein commit aus, hätte die Bank ein paar sehr unzufriedene Kunden! Eine Transaktion wird implizit initiiert. Nachdem das commit einer vorherigen Transaktion abgeschlossen ist und zumindest eine Zeile einer Tabelle eingefügt, aktualisiert oder gelöscht hat, wird implizit eine neue Transaktion angelegt. Auch alle DML-Befehle wie create table und alter index schreiben eine aktive Transaktion fest und beginnen eine neue. Eine Transaktion lässt sich mit dem set transaction … name 'transaction_name'-Befehl benennen; obwohl die Applikation davon keinen direkten Nutzen hat, wird der zugewiesene Name in der dynamischen Performance View V$TRANSACTION protokolliert und erlaubt dem DBA das Überwachen lang laufender Transaktionen. Der set transaction-Befehl muss, falls eingesetzt, der erste Befehl innerhalb der Transaktion sein. Innerhalb einer gegebenen Transaktion kann man einen Savepoint definieren. Ein Savepoint ermöglicht das Partitionieren der DML-Befehlssequenzen innerhalb der Transaktion. Damit kann man DML-Befehle nach dem Savepoint mit einem Rollback zurücksetzen, nachfolgend weitere DML-Befehle eingeben oder DML-Befehle festschreiben, die vor dem Savepoint ausgeführt wurden. Savepoints legt man mit dem savepoint savepoint_name-Befehl an. Um die DML-Befehle seit dem letzten Savepoint zurückzusetzen, benutzen Sie den Befehl rollback to savepoint savepoint_name. 7.2 Undos – Grundlagen 273 Eine Transaktion wird implizit festgeschrieben, sobald sich ein Benutzer normal von Oracle abmeldet; sollte der Benutzerprozess scheitern, wird die letzte Transaktion mit einem Rollback zurückgesetzt. 7.2 Undos – Grundlagen Undo-Tablespaces erleichtern das Rollback von logischen Transaktionen. Zudem unterstützen sie zahlreiche andere Funktionalitäten, wie die Lesekonsistenz, verschiedene Recovery-Operationen und Flashback-Funktionen. 7.2.1 Rollback Wie oben bereits ausgeführt, kann es notwendig sein, innerhalb einer Transaktion einen beliebigen DML-Befehl zurückzusetzen – wobei es keine Rolle spielt, ob die Transaktion einen oder hunderte DML-Befehle umfasst. Führt ein DML-Befehl eine Änderung auf eine Tabelle aus, wird der alte Wert der geänderten Daten im Undo-Tablespace in einem systemverwalteten Undo-Segment oder einem Rollback-Segment protokolliert. Wird die gesamte Transaktion zurückgesetzt (d.h. eine Transaktion ohne Savepoints), macht Oracle alle seit Transaktionsbeginn durch DML-Befehle vorgenommenen Änderungen ungeschehen. Dazu nutzt Oracle die dazugehörigen Undo-Datensätze, gibt die Sperren auf betroffene Zeilen frei (sofern vorhanden), und die Transaktion endet. Werden Teile einer Transaktion auf einen Savepoint zurückgesetzt, macht Oracle alle Änderungen durch DML-Befehle rückgängig, die seit dem Savepoint ausgeführt wurden. Alle nachfolgenden Savepoints sind verloren, alle Sperren nach dem Savepoint werden freigegeben, und die Transaktion bleibt aktiv. 7.2.2 Lesekonsistenz Undos bieten Benutzern die Lesekonsistenz für Zeilen, die gerade in die DML-Transaktion eines anderen Benutzers eingebunden sind. Anders gesagt, sehen alle anderen Benutzer in den betroffenen Zeilen keine Änderungen, bis der DML-Benutzer ein commit eingibt, und sie sich die Zeilen erneut ansehen. Mit Undo-Segmenten lassen sich die Datenblöcke auf eine lesekonsistente Version zurücksetzen, und bieten damit allen Benutzern die ursprünglichen Werte der Zeile, die vor dem Transaktionsende eine select-Anweisung eingeben. Nehmen wir beispielsweise an, der Benutzer CLOLSEN beginnt um 10:00 Uhr eine Transaktion, die schätzungsweise um 10:15 Uhr mit dem Festschreiben der Daten endet. Die Transaktion umfasst verschiedene Aktualisierungen und Einfügungen in die 274 7 Transaktionsverwaltung mit Undo-Tablespaces EMPLOYEES-Tabelle. Bei jedem insert, update und delete auf die EMPLOYEES-Tabelle werden die alten Werte im Undo-Tablespace gespeichert. Führt der Benutzer SUSANP um 10:08 Uhr eine select-Anweisung auf die EMPLOYEES-Tabelle aus, kann nur CLOLSEN die gemachten Änderungen sehen; der Undo-Tablespace bietet SUSANP und allen anderen Benutzern die ursprünglichen Werte an. Selbst wenn die Abfrage von SUSANP erst um 10:20 Uhr endet, scheint die Tabelle weiterhin unverändert zu sein. Die Änderungen werden erst sichtbar, wenn man nach dem Festschreiben der Daten eine neue Abfrage startet. Bis CLOLSEN um 10:15 Uhr seine Daten festschreibt, werden die Daten unverändert mit dem Stand von 10:00 Uhr angezeigt. Falls nicht genügend Undo-Platz vorhanden ist, um die vorherigen Werte von geänderten Zeilen aufzunehmen, erhält der Benutzer, der eine select-Anweisung ausgibt, einen „ORA-01555: Snapshot Too Old“-Fehler. Im weiteren Verlauf des Kapitels zeigen wir, wie man dieses Problem löst. 7.2.3 Datenbank-Recovery Die Undo-Tablespaces sind auch eine Schlüsselkomponente des Instanz-Recoverys. Die Online Redo Logs setzen sowohl festgeschriebene als auch nicht festgeschriebene Transaktionen auf den Zeitpunkt zurück, zu dem die Instanz scheiterte; mit Hilfe der Undo-Daten werden alle Transaktionen zurückgesetzt, die zum Zeitpunkt des Zusammenbruchs noch nicht festgeschrieben waren. 7.2.4 Flashback-Operationen Die Daten im Undo-Tablespace unterstützen verschiedene Typen von Flashback-Optionen: Flashback Table, Flashback Query und das DBMS_FLASHBACK-Package. Flashback Table stellt eine Tabelle für einen Zeitpunkt in der Vergangenheit her, mit Flashback Query sehen Sie eine Tabelle für eine SCN oder einen Zeitpunkt in der Vergangenheit, und DBMS_FLASHBACK bietet eine Programmschnittstelle für Flashback-Operationen. Sämtliche Flashback-Optionen stellen wir am Ende des Kapitels vor. 7.3 Undo-Tablespaces verwalten 7.3 275 Undo-Tablespaces verwalten Undo-Tablespaces müssen nur ein Mal parametrisiert werden, es handelt sich um eine der „Set it and forget it“-Operationen. Innerhalb des Undo-Tablespace legt Oracle automatisch Undo-Segmente an, dimensioniert sie korrekt und verwaltet sie selbstständig – ganz im Gegensatz zu früheren Versionen, bei denen der DBA die Rollback-Segmente anlegen, überwachen und verwalten musste. In den folgenden Abschnitten stellen wir Ihnen die Prozesse vor, mit denen man Undo-Tablespaces anlegt und verwaltet, inklusive der relevanten Initialisierungsparameter. Weiterhin zeigen wir einige Szenarien, in denen wir mehrere Undo-Tablespaces anlegen und demonstrieren, wie man zwischen Undo-Tablespaces umschaltet. 7.3.1 Undo-Tablespaces anlegen Zum Anlegen von Undo-Tablespaces gibt es zwei Möglichkeiten: beim Einrichten der Datenbank oder zu einem späteren Zeitpunkt mit dem create tablespace-Befehl. Genau wie die anderen Tablespaces in Oracle 10g, kann auch der Undo-Tablespace ein Bigfile-Tablespace sein, was die Verwaltung zusätzlich vereinfacht. Anlegen eines Undo-Tablespace mit CREATE DATABASE Eine Datenbank kann mehrere Undo-Tablespaces besitzen, allerdings kann zu einem gegebenen Zeitpunkt nur einer aktiv sein. Nachfolgend sehen Sie den Code zum Anlegen des Undo-Tablespace beim Einrichten der Datenbank: create database ord user sys identified by ds88dkw2 user system identified by md78s233 sysaux datafile '/u02/oradata/ord/sysaux001.dbf' size 100m default temporary tablespace temp01 tempfile '/u03/oradata/ord/temp001.dbf' size 25m undo tablespace undotbs01 datafile '/u01/oradata/ord/undo001.dbf' size 50m; Lässt sich der Tablespace im create database-Befehl nicht anlegen, scheitert die gesamte Operation. Der Fehler muss behoben werden und alle Dateien aus der Operation sind zu löschen, dann kann der Befehl erneut eingegeben werden. Die undo tablespace-Klausel im create database-Befehl ist optional, aber sollte das Automatic Undo Management aktiviert sein und die Klausel wird ausgelassen, wird trotzdem ein Undo-Tablespace mit einer selbst erweiternden Datendatei angelegt. Die Anfangsgröße der Datei beträgt 10MB und der Standardname ist SYS_UNDOTBS. 276 7 Transaktionsverwaltung mit Undo-Tablespaces Anlegen eines Undo-Tablespace mit CREATE TABLESPACE Nach jedem Anlegen der Datenbank wird ein neuer Undo-Tablespace eingerichtet. Einen Undo-Tablespace legt man wie alle anderen Tablespaces an, fügt jedoch das Schlüsselwort undo ein: create undo tablespace undotbs02 datafile '/u01/oracle/rbdb1/undo0201.dbf' size 25m reuse autoextend on; Ungeachtet der Volatilität der Datenbank oder der Erwartung, dass der Undo-Bedarf der Datenbank zukünftig dramatisch zunehmen könnte, geben wir für diesen Tablespace nur eine Größe von 25MB vor und lassen ihn wachsen. Die Extents in einem Undo-Tablespace müssen systemverwaltet sein; somit können Sie extent management nur als local autoallocate vorgeben. Anlegen eines Undo-Tablespace mit EM Database Control Das Anlegen eines Undo-Tablespace ist mit Hilfe der Enterprise Manager Database Control relativ einfach. Im Administration-Register wählen Sie Tablespaces. Es wird eine Liste der bestehenden Tablespaces angezeigt; klicken Sie auf Create. In Abbildung 7-1 legen wir einen neuen Undo-Tablespace namens UNDO_BATCH an. Im unteren Teil des Bildschirms definieren wir den Namen der Datendatei, die im Undo-Tablespace einzusetzen ist (siehe Abbildung 7-2). Abbildung 7-1: Eingeben der allgemeinen Charakteristiken für den Undo-Tablespace. 7.3 Undo-Tablespaces verwalten 277 Abbildung 7-2: Definieren der Datendatei für den Undo-Tablespace. Nach einem Klick auf Storage können wir die Extent-Reservierung vorgeben, obwohl dies ein Undo-Tablespace automatisch ausführen muss. Unterstützen wir mehrere Blockgrößen, lässt sich die Blockgröße für den Undo-Tablespace vorgeben. Abbildung 7-3 zeigt, dass wir die selbstständige Extent-Reservierung und eine Blockgröße von 8192 vorgeben; die standardmäßige und einzige Blockgröße, die für die Datenbank definiert wurde. Im dritten Register können wir die Warnungen und kritischen Prozentsätze eingeben, ab denen der DBA über potenzielle Platzprobleme im Undo-Tablespace informiert wird. Wir können die Standard-Grenzwerte verwenden – 85 Prozent für Warnungen und 97 Prozent als kritischen Wert – oder geben eigene Werte ein. In Abbildung 7-4 akzeptieren wir die Standardwerte. Wie bei den meisten Verwaltungsbildschirmen in EM Database Control können wir in einer Vorschau die SQL-Befehle sehen, die nach dem Bestätigen ausgeführt werden. In Abbildung 7-5 sehen wir die Befehle zum Anlegen des Tablespace und zum Setzen der dazugehörigen Grenzwerte für die Server-Warnungen. Nach einem Klick auf OK wird der neue Undo-Tablespace angelegt (siehe Abbildung 7-6). 278 7 Transaktionsverwaltung mit Undo-Tablespaces Abbildung 7-3: Extent-Zuweisung und Blockgröße. Abbildung 7-4: Grenzwerte für den Undo-Tablespace. 7.3 Undo-Tablespaces verwalten Abbildung 7-5: Die SQL-Vorschau. Abbildung 7-6: Die Zusammenfassung. 279 280 7 Transaktionsverwaltung mit Undo-Tablespaces Obwohl der DBA mit der EM Database Control erheblich Zeit sparen kann, deckt er nicht alle möglichen Szenarien ab und schützt den DBA auch nicht davor, dass er den Undo-Tablespace mit falschen Parametern anlegt. In Abbildung 7-3 könnten wir beispielsweise eine einheitliche Extent-Reservierung vorgeben. Versuchen wir allerdings, den Tablespace anzulegen, scheitert die Operation (siehe Abbildung 7-7). Denn wie bereits weiter oben ausgeführt, benötigen Undo-Tablespaces automatisch reservierte Extents. Abbildung 7-7: Illegale Parameter für Undo-Tablespaces. Undo-Tablespaces löschen Das Löschen eines Undo-Tablespace gleicht dem Löschen eines beliebigen Tablespace. Der Undo-Tablespace darf allerdings nicht der aktive Undo-Tablespace sein, und er darf auch keine Daten für nicht festgeschriebene Transaktionen enthalten. Falls Sie einen Undo-Tablespace mit aktiven Undo-Informationen löschen, kann das zum Scheitern von Abfragen führen. Um den oben angelegten Undo-Tablespace zu löschen, geben wir den drop tablespace-Befehl ein: SQL> drop tablespace undo_batch; Tablespace dropped. SQL> 7.3 Undo-Tablespaces verwalten 281 Die including contents-Klausel ist für das Löschen von Undo-Tablespaces gedacht. Um jedoch nach dem Entfernen des Undo-Tablespace die dazugehörigen Systemdatendateien zu löschen, ist including contents and datafiles anzugeben. Das Löschen des aktiven Undo-Tablespace ist nicht erlaubt: SQL> drop tablespace undotbs1; drop tablespace undotbs1 * ERROR at line 1: ORA-30013: undo tablespace 'UNDOTBS1' is currently in use SQL> Vor dem Löschen des aktiven Undo-Tablespace ist auf einen anderen Undo-Tablespace umzuschalten. Weitere Informationen zum Umschalten von Undo-Tablespaces erhalten Sie im weiteren Verlauf des Kapitels. Undo-Tablespaces ändern Folgende Operationen sind auf Undo-Tablespaces erlaubt: ■ Hinzufügen einer Datendatei zu Undo-Tablespaces ■ Umbenennen einer Datendatei in einem Undo-Tablespace ■ Die Datendatei eines Undo-Tablespace online oder offline setzen ■ Starten oder Beenden eines offenen Tablespace-Backups (alter tablespace undotbs begin backup) ■ Aktivieren oder Deaktivieren der Undo-Vorhaltegarantie Alles andere wird automatisch von Oracle verwaltet. OMF für Undo-Tablespaces Zusätzlich zum Einsatz eines Bigfile-Tablespace für Undo-Tablespaces lässt sich ein Undo-Tablespace auch mit OMF benennen und platzieren; der Initialisierungsparameter DB_CREATE_FILE_DEST enthält den Standort, an dem ein Undo-Tablespace angelegt wird, falls im create undo tablespace-Befehl die datafile-Klausel nicht angegeben sein sollte. Im folgenden Beispiel legen wir mit OMF einen Undo-Tablespace an: SQL> show parameter db_create_file_dest NAME TYPE VALUE ------------------------------- ----------- ------------------------db_create_file_dest string /u09/oradata/ord SQL> create undo tablespace undo_batch; Tablespace created. 282 7 Transaktionsverwaltung mit Undo-Tablespaces SQL> !ls -l /u09/oradata/ord/ORD/datafile total 102512 -rw-r----1 oracle oinstall 104865792 Apr 11 21:54 o1_mf_undo_bat_07n16plc_.dbf SQL> Da wir keine Größe angeben, ist der Tablespace standardmäßig 100MB groß. Zudem ist die Datendatei ohne Größenbeschränkung selbsterweiternd, die Grenze setzt lediglich das Dateisystem. 7.3.2 Dynamische Performance Views für UndoTablespaces Verschiedene dynamische Performance Views und Data Dictionary Views enthalten Informationen über Undo-Tablespaces, Benutzertransaktionen und Undo-Segmente. Tabelle 7-1 zeigt die View-Namen mit einer Beschreibung. Die Views in Tabelle 7-1 werden im weiteren Verlauf des Kapitels noch ausführlicher beschrieben. Tabelle 7-1: Views für Undo-Tablespaces. View Beschreibung DBA_TABLESPACES Tablespace-Namen und -Charakteristiken, inklusive der CONTENTS-Spalte, die PERMANENT, TEMPORARY oder UNDO sein kann; die Undo RETENTION-Spalte ist NOT APPLY, GUARANTEE oder NOGUARANTEE. DBA_UNDO_EXTENTS Alle Undo-Segmente in der Datenbank, mit Größe, Extents, dem Tablespace, in dem sie liegen, und dem aktuellen Status (EXPIRED oder UNEXPIRED). V$UNDOSTAT Der Umfang der Undo-Nutzung für die Datenbank in 10-MinutenIntervallen; enthält mindestens 1008 Zeilen (7Tage). V$ROLLSTAT Rollback-Segmentstatistiken, inklusive Größe und Status. V$TRANSACTION Enthält für jede aktive Transaktion der Instanz eine oder mehrere Zeilen. 7.3.3 Initialisierungsparameter für Undo-Tablespaces In den folgenden Abschnitten beschreiben wir die Initialisierungsparameter zur Definition des Undo-Tablespace für die Datenbank. Zudem steuern sie, wie lange Oracle die Undo-Informationen in der Datenbank vorhält. 7.3 Undo-Tablespaces verwalten 283 UNDO_MANAGEMENT Der Parameter UNDO_MANAGEMENT ist standardmäßig MANUAL. Das Setzen des UNDO_MANAGEMENT-Parameters auf AUTO überführt die Datenbank in den automatischen Undo Management-Modus. Damit dieser Parameter gültig ist, muss zumindest ein Undo-Tablespace vorhanden sein, ungeachtet dessen, ob UNDO_TABLESPACE angegeben ist oder nicht. UNDO_MANAGEMENT ist kein dynamischer Parameter; deshalb ist bei jeder Änderung von UNDO_MANAGEMENT die Datenbank herunterzufahren und neu zu starten. UNDO_TABLESPACE Der UNDO_TABLESPACE-Parameter definiert, welche Undo-Tablespaces für das automatische Undo-Management eingesetzt werden. Ist UNDO_MANAGEMENT entweder gar nicht oder auf MANUAL gesetzt, und UNDO_TABLESPACE angegeben, startet die Instanz nicht. Hinweis: Mit UNDO_TABLESPACE wird in RAC (Real Application Clusters)-Umgebungen der Instanz ein bestimmter UndoTablespace zugewiesen, wobei die Gesamtzahl der UndoTablespaces in der Datenbank gleich oder mehr als die Anzahl der Instanzen im Cluster ist. Falls umgekehrt UNDO_MANAGEMENT auf AUTO gesetzt und kein Undo-Tablespace in der Datenbank vorhanden ist, startet die Instanz, aber das SYSTEM-Rollback-Segment wird für alle Undo-Operationen genutzt, und eine Meldung wird in das Alert Log geschrieben. Jede Benutzer-DML, die Änderungen in Nicht-SYSTEMTablespaces ausführen möchte, erhält zusätzlich die Fehlermeldung „ORA-01552: cannot use system rollback segment for non-system tablespace 'USERS'“, und die Anweisung scheitert. UNDO_RETENTION UNDO_RETENTION definiert den minimalen Zeitraum, den Undo-Informationen für Abfragen vorgehalten werden. Im automatischen Undo-Modus ist UNDO_RETENTION standardmäßig 900 Sekunden. Dieser Wert ist nur gültig, wenn im UndoTablespace genügend Platz für die Unterstützung von lesekonsistenten Abfragen ist; falls aktive Transaktionen zusätzlichen Undo-Platz benötigen, können nicht abgelaufene Undos zur Unterstützung der aktiven Transaktionen herangezogen werden und zu „ORA-01555: Snapshot Too Old“-Fehlern führen. Die TUNED_UNDORETENTION-Spalte der dynamischen Performance View V$UNDOSTAT zeigt für jede Zeitperiode die getunete Undo-Vorhaltezeit; der Status 284 7 Transaktionsverwaltung mit Undo-Tablespaces für die Nutzung im Undo-Tablespace wird in V$UNDOSTAT alle zehn Minuten aktualisiert: SQL> show parameter undo_retention NAME TYPE VALUE ------------------------------------ ----------- --------undo_retention integer 43200 SQL> select to_char (begin_time, 'yyyy-mm-dd hh24:mi'), 2 undoblks, txncount, tuned_undoretention 3 from v$undostat where rownum = 1; TO_CHAR(BEGIN_TI UNDOBLKS TXNCOUNT TUNED_UNDORETENTION ------------------ ---------- -------- ------------------2004-04-11 22:59 206 253 43200 1 row selected. SQL> Weil die Transaktionsbelastung ist der letzten Periode nur gering war, und die Instanz erst vor kurzem gestartet wurde, ist der getunete Undo Retention-Wert der gleiche wie das definierte Minimum im Initialisierungsparameter UNDO_RETENTION: 43200 Sekunden (12 Stunden). Tipp: UNDO_RETENTION ist nur für Vorhalteangaben bei Flashbacks und LOBs anzugeben; zum Verwalten des Transaktions-Rollbacks wird der UNDO_RETENTIONParameter nicht benötigt. 7.3.4 Mehrere Undo-Tablespaces Wie bereits weiter oben erwähnt, kann eine Datenbank mehrere Undo-Tablespaces enthalten. Allerdings kann für eine Instanz immer nur ein Undo-Tablespace aktiv sein. In diesem Abschnitt zeigen wir Ihnen anhand eines Beispiels, wie man bei geöffneter Datenbank auf einen anderen Undo-Tablespace umschaltet. Hinweis: In einer Real Application Clusters (RAC)-Umgebung benötigt jede Instanz im Cluster einen Undo-Tablespace. In unserer ord-Datenbank gibt es zwei Undo-Tablespaces: SQL> select tablespace_name, status from dba_tablespaces 2 where contents = 'UNDO'; 7.3 285 Undo-Tablespaces verwalten TABLESPACE_NAME --------------------------UNDOTBS1 UNDO_BATCH STATUS ---------ONLINE ONLINE 2 rows selected. Aber nur einer der Undo-Tablespaces ist aktiv: SQL> show parameter undo_tablespace NAME TYPE VALUE -------------------------- ----------- --------undo_tablespace string UNDOTBS1 Für die Verarbeitung in der Nacht ändern wir den Undo-Tablespace von UNDOTBS1 in den UNDO_BATCH-Tablespace, der zur Unterstützung umfangreicherer DMLAktivitäten viel größer ist. Die Platte mit dem tagaktiven Undo-Tablespace ist viel schneller, bietet aber dafür weniger Speicherplatz; das Laufwerk mit dem nachtaktiven Undo-Tablespace ist größer, aber langsamer. Daher nutzen wir den kleineren UndoTablespace für das OLTP während des Tages, und den größeren Undo-Tablespace für das Laden von Data Marts und Data Warehouses und für Aggregationen, weil nachts die Antwortzeiten keine Rolle spielen. Hinweis: Im Gegensatz zu den hier beschriebenen Umständen werden Sie wahrscheinlich nur selten zwischen Undo-Tablespaces umschalten. Oracle empfiehlt, für jede Instanz nur einen Undo-Tablespace anzulegen, der alle Transaktionsbelastungen unterstützt; mit anderen Worten, „set it and forget it“. Genau zu dem Zeitpunkt, wenn zwischen den Undo-Tablespaces umgeschaltet wird, führt der Benutzer SCOTT Verwaltungsoperationen auf die HR.EMPLOYEES-Tabelle aus, und hat im aktuellen Undo-Tablespace eine aktive Transaktion: SQL> connect scott/tiger@ord; Connected. SQL> set transaction name 'Employee Maintenance'; Transaction set. SQL> update hr.employees set commission_pct = commission_pct * 1.1; 107 rows updated. SQL> Eine Abfrage auf V$TRANSACTION zeigt SCOTTs nicht festgeschriebene Transaktion: 286 7 Transaktionsverwaltung mit Undo-Tablespaces SQL> select t.status, t.start_time, t.name 2 from v$transaction t join v$session s on t.ses_addr = 3 where s.username = 'SCOTT'; s.saddr STATUS START_TIME NAME -------------- -------------------- ----------------------ACTIVE 04/12/04 21:56:53 Employee Maintenance 1 row selected. Sie ändern den Undo-Tablespace wie folgt: SQL> alter system set undo_tablespace=undo_batch; System altered. SCOTTs Transaktion ist weiterhin aktiv, und deshalb enthält der alte Undo-Tablespace weiterhin die Undo-Informationen für SCOTTs Transaktion. Damit steht das Undo-Segment mit dem folgenden Status solange zur Verfügung, bis die Transaktion festgeschrieben oder mit einem Rollback zurückgesetzt wird: SQL> select r.status 2 from v$rollstat r join v$transaction t on r.usn=t.xidusn 3 join v$session s on t.ses_addr = s.saddr 4 where s.username = 'SCOTT'; STATUS --------------PENDING OFFLINE 1 row selected. Obwohl UNDO_BATCH der aktuelle Undo-Tablespace ist, lässt sich der UNDOTBS1Tablespace erst dann offline setzen oder löschen, wenn SCOTTs Transaktion festgeschrieben oder mit einem Rollback zurückgesetzt wurde: SQL> show parameter undo_tablespace NAME TYPE VALUE -------------------------- ----------- ---------undo_tablespace string UNDO_BATCH SQL> alter tablespace undotbs1 offline; alter tablespace undotbs1 offline * ERROR at line 1: ORA-30042: Cannot offline the undo tablespace Die Fehlermeldung ORA-30042 tritt auf, falls Sie versuchen, einen aktiven Undo-Tablespace offline zu setzen – entweder handelt es sich um den aktuellen Undo-Tablespace oder er hat noch offene Transaktionen. Schalten wir auf den tagaktiven Table- 7.3 Undo-Tablespaces verwalten 287 space um, bevor SCOTT seine ursprüngliche Transaktion festgeschrieben oder mit einem Rollback zurückgesetzt hat, ändert sich der Status von SCOTTs Rollback-Segment wieder auf ONLINE: SQL> alter system set undo_tablespace=undotbs1; System altered. SQL> select r.status 2 from v$rollstat r join v$transaction t on r.usn=t.xidusn 3 join v$session s on t.ses_addr = s.saddr 4 where s.username = 'SCOTT'; STATUS --------------ONLINE 1 row selected. 7.3.5 Den Undo-Tablespace dimensionieren und überwachen In einem Undo-Tablespace gibt drei verschiedene Undo-Datentypen: aktiv, abgelaufen oder nicht abgelaufen. Aktive und nicht abgelaufene Undo-Daten werden weiterhin für die Lesekonsistenz benötigt, selbst nach dem Festschreiben einer Transaktion. Nachdem alle Abfragen beendet wurden, die aktive Undo-Daten benötigen, und gleichzeitig das Ende der Vorhaltezeit erreicht ist, werden die aktiven zu abgelaufenen Undo-Daten. Die abgelaufenen Daten lassen sich für andere Oracle-Funktionen wie Flashbacks einsetzen, werden aber nicht mehr für die Lesekonsistenz bei lang laufenden Transaktionen benötigt. Ungenutzte Undo-Daten belegen im Undo-Tablespace unnötig Platz. Damit bietet die minimale Größe für einen Undo-Tablespace genügend Platz zum Vorhalten der Before-Image-Versionen aller Daten aus sämtlichen aktiven Transaktionen, die noch nicht festgeschrieben oder mit einem Rollback zurückgesetzt wurden. Falls der für den Undo-Tablespace reservierte Speicherplatz nicht einmal ausreicht, um die Änderungen an nicht festgeschriebene Transaktionen für Rollback-Operationen zu unterstützen, erhält der Benutzer die Fehlermeldung „ORA-30036: unable to extend segment by space_qty in undo tablespace tablespace_name.“ In diesem Fall muss der DBA den Undo-Tablespace vergrößern. Alternativ kann der Benutzer unter Einhaltung der Geschäftsregeln größere in kleinere Transaktionen aufteilen. Manuelle Methoden Die Größe eines Undo-Tablespaces kann ein DBA auch manuell korrigieren. Wie in Kapitel 6 gezeigt, sehen wir in der dynamischen Performance View V$UNDOSTAT die Nutzung der Undo-Segmente in 10-Minuten-Intervallen. Zusätzlich zeigt die 288 7 Transaktionsverwaltung mit Undo-Tablespaces SSOLDERRCNT-Spalte, wie viele Abfragen mit einem „Snapshot too old“-Fehler scheiterten: SQL> select to_char (end_time,'yyyy-mm-dd hh24:mi') end_time, 2> undoblks, ssolderrcnt from v$undostat; END_TIME UNDOBLKS SSOLDERRCNT ------------------ -------- ----------2004-04-13 08:12 2114 0 2004-04-13 08:09 4569 0 2004-04-13 07:59 7403 0 2004-04-13 07:49 2341 0 2004-04-13 07:39 8338 0 2004-04-13 07:29 1483 0 2004-04-13 07:19 1548 0 2004-04-13 07:09 61950 2 2004-04-13 06:59 4433 0 2004-04-13 06:49 5658 0 2004-04-13 06:39 757 0 Zwischen 6:59 Uhr und 7:09 Uhr haben wir eine Spitzenbelastung der Undos, was zu gescheiterten Transaktionen führte. Die folgende Kalkulation ist eine gute Faustregel: undo_tablespace_size = UV * UPS + Overhead In dieser Formel ist UR die Undo-Vorhaltezeit in Sekunden (vom Initialisierungsparameter UNDO_RETENTION), UPS sind die genutzten Undo-Blöcke pro Sekunde, und Overhead sind die Undo-Metadaten – im Vergleich zur Gesamtgröße relativ wenige. Unsere ord-Datenbank hat eine Blockgröße von 8K und UNDO_RETENTION ist 43200 (12 Stunden). Wenn wir pro Sekunde 500 Blöcke generieren, die stets 12 Stunden vorzuhalten sind, muss der gesamte Undo-Platz wie folgt sein: undo_tablespace_size = 43200 * 500 * 8192 = 176947200000 = 177GB Fügt man zu diesem Wert nochmals 10 bis 20 Prozent hinzu, ist man für alle denkbaren Situationen gerüstet. Alternativ können Sie die Datendateien im Tablespace als selbsterweiternd definieren. Obgleich diese Kalkulation ein guter Ausgangspunkt ist, können die Oracle-Ratgeber mit Hilfe von Trendanalysen eine besseres Gesamtbild zeichnen. Undo Advisor Der Undo Advisor von Oracle 10g automatisiert viele Jobs zum Feintuning des Speicherplatzes für Undo-Tablespaces. In Kapitel 6 stellten wir zwei Beispiele mit dem Undo Advisor vor: über die Schnittstelle von EM Database Control und den PL/SQL DBMS_ADVISOR-Packages im Automatic Workload Repository (AWR). Die Seite für den Undo Advisor sehen Sie in Abbildung 7-8. 7.3 Undo-Tablespaces verwalten 289 Abbildung 7-8: EM Database Control: der Undo Advisor. Obwohl wir UNDO_RETENTION auf 43200 (720 Minuten) setzen, ist es im Undo Advisor anscheinend so, dass die auto-getunete Undo-Vorhalteperiode zur Unterstützung einer lesekonsistenten Ansicht von geänderten Tabellen für die aktuelle Undo-Segmentnutzung nicht höher oder niedriger als 720 sein muss. Beim Anlegen unseres Undo-Tablespace (siehe Abbildung 7-4) setzen wir einige Grenzwerte. Anhand dieser automatischen Warnungen können wir den Undo-Tablespace in den Fällen proaktiv neu dimensionieren, falls einer der Schwellenwerte überschritten wird – und zwar bevor irgendwelche DMLs oder Abfragen scheitern. Steuern der Undo-Nutzung Seit Oracle 9i unterstützt uns der Database Resource Manager beim Verwalten der Speicherplatzbelegung, entweder nach Benutzer oder nach Benutzergruppen in einer Ressourcen-Verbrauchergruppe, mit Hilfe der UNDO_POOL-Direktive. Jede Verbrauchergruppe kann einen eigenen Undo-Pool besitzen; überschreitet die Gesamtzahl der generierten Undos nach Gruppen den zugewiesenen Wert, wird die aktuelle Transaktion, die Undos generiert, beendet, und die Fehlermeldung „ORA30027: Undo quota violation—failed to get number (bytes).“ ausgegeben. Die Sitzung muss warten, bis der DBA den Undo-Pool vergrößert, oder bis sich Transaktionen von anderen Benutzern in der gleichen Verbrauchergruppe beenden. 290 7 Transaktionsverwaltung mit Undo-Tablespaces Im folgenden Beispiel ändern wir für die Benutzer in der Verbrauchergruppe LOW_ GROUP den Standardwert von UNDO_POOL von NULL (unbeschränkt) auf 100KB: begin dbms_resource_manager.create_pending_area(); dbms_resource_manager.update_plan_directive( plan => 'system_plan', group_or_subplan => 'low_group', new_comment => 'Limit undo space for low priority groups', new_undo_pool => 10 00); dbms_resource_manager.validate_pending_area(); dbms_resource_manager.submit_pending_area(); end; Der Oracle Resource Manager und andere Ressourcendirektiven werden in Kapitel 5 besprochen. 7.3.6 Lesekonsistenz und erfolgreiche DMLs Bei OLTP-Datenbanken möchten wir üblicherweise, dass die DML-Befehle erfolgreich sind – gegebenenfalls auf Kosten der Lesekonsistenz. In einer DSS-Umgebung hingegen sollen sich lang laufende Abfragen möglichst ohne „Snapshot too old“-Fehler beenden. Obwohl ein Vergrößern des UNDO_RETENTION-Parameters oder ein Anpassen des Undo-Tablespace sicherstellen kann, dass für lesekonsistente Abfragen Undo-Blöcke zur Verfügung stehen, besitzen Undo-Tablespaces eine weitere Charakteristik, die das erfolgreiche Ausführen von Abfragen sicherstellt: die RETENTION GUARANTEE-Einstellung. RETENTION GUARANTEE wird auf Tablespace-Ebene gesetzt und lässt sich jederzeit ändern. Das Setzen einer Vorhaltegarantie für einen Undo-Tablespace stellt sicher, dass ein aktives Undo innerhalb des Tabelle auch dann vorgehalten wird, wenn es so aussieht, als ob für das erfolgreiche Ausführen von DML-Transaktionen nicht genügend Undo-Platz zur Verfügung steht. Ein Tablespace wird standardmäßig mit NOGUARANTEE angelegt, außer Sie definieren das Schlüsselwort GARANTEE gleich beim Anlegen des Tablespace oder zu einem späteren Zeitpunkt mit ALTER TABLESPACE: SQL> alter tablespace undotbs1 retention guarantee; Tablespace altered. SQL> select tablespace_name, retention 2 from dba_tablespaces 3 where tablespace_name = 'UNDOTBS1'; 7.4 Flashback-Optionen 291 TABLESPACE_NAME RETENTION ------------------------------ ----------UNDOTBS1 GUARANTEE 1 row selected. Für Nicht-Undo-Tablespaces ist der Wert von RETENTION stets NOT APPLY. 7.4 Flashback-Optionen In diesem Abschnitt besprechen wir die Flashback-Optionen, die von Undo-Tablespaces unterstützt werden: Flashback Query, Flashback Table, Flashback Version Query und Flashback Transaction Query. Zudem stellen wir das DBMS_FLASHBACK-Package vor. Flashback Database und Flashback Drop werden in Kapitel 15 besprochen. Flashback Database nutzt für die Flashback-Funktionalität die Flashback Logs in der Flash Recovery Area, und keine Undos in einem Undo-Tablespace. Flashback Drop platziert Tabellen in einer virtuellen Recycle bin innerhalb des Tablespace. Die Tabellen bleiben dort solange, bis sie der Benutzer mit flashback table … to before drop abholt, die Recycle bin leert, oder der Platz für permanente Objekte im Tablespace benötigt wird. Weiterhin kann der DBA in Oracle 10g System- und Objektberechtigungen zuweisen, die es Benutzern erlauben, bestimmte Probleme selbstständig zu lösen. Im folgenden Beispiel sorgen wir dafür, dass der Benutzer SCOTT Flashback-Operationen auf bestimmte Tabellen ausführen und innerhalb der Datenbank auf transaktionsbezogene Metadaten zugreifen kann: SQL> grant insert, update, delete, select on hr.employees to scott; Grant succeeded. SQL> grant insert, update, delete, select on hr.departments to scott; Grant succeeded. SQL> grant flashback on hr.employees to scott; Grant succeeded. SQL> grant flashback on hr.departments to scott; Grant succeeded. SQL> grant select any transaction to scott; Grant succeeded. 7.4.1 Flashback Query Seit Oracle 9i2 kann man mit der as of-Klausel in einer select-Anweisung mit Hilfe eines gegebenen Zeitstempels oder einer SCN den Status einer Tabelle abholen. Damit lässt sich beispielsweise herausfinden, welche Zeilen in einer Tabelle seit Mitternacht 292 7 Transaktionsverwaltung mit Undo-Tablespaces gelöscht wurden. Oder Sie vergleichen den aktuellen Stand von Zeilen in einer Tabelle mit den gestrigen Inhalten. Im folgenden Beispiel räumt SCOTT in der HR.EMPLOYEES-Tabelle auf und löscht zwei Angestellte, die nicht mehr im Unternehmen arbeiten: SQL> delete from hr.employees 2 where employee_id in (195,196); 2 rows deleted. SQL> commit; Commit complete. SQL> Normalerweise würde SCOTT diese Zeilen zuerst an die Tabelle HR.EMPLOYEES_ ARCHIVE kopieren, aber das vergaß er diesmal; er muss die Zeilen zwar nicht mehr in die HR.EMPLOYEES-Tabelle zurückkopieren, aber er braucht sie für die Archivtabelle. Da SCOTT weiß, dass er die Zeilen vor weniger als einer Stunde gelöscht hat, lassen sich die Zeilen mit Flashback Query und einem relativen Zeitstempel zurückholen: SQL> 2 3 4 5 insert into select * as of where hr.employees_archive from hr.employees timestamp systimestamp - interval '60' minute hr.employees.employee_id not in (select employee_id from hr.employees); 2 rows created. SQL> commit; Commit complete. Da EMPLOYEE_ID der Primärschlüssel der Tabelle ist, können wir mit seiner Hilfe die Angestelltendatensätze zurückholen, die vor einer Stunde vorhanden waren. Beachten Sie auch, dass wir nicht wissen müssen, welche Zeilen gelöscht wurden: Wir verglichen die Tabelle mit dem Stand vor einer Stunde und fügten die nicht mehr vorhandenen Datensätze in die Archivtabelle ein. Tipp: Bei Flashbacks sollten Sie vorzugsweise SCNs und keine Zeitstempel einsetzen: SCNs sind präzise, während die Zeitstempelwerte für Flashback-Operationen nur alle 5 Minuten gespeichert werden. Deshalb können bei zeitstempelbasierten Flashbacks Lücken von 150 Sekunden entstehen. 7.4 293 Flashback-Optionen Obgleich wir zum Zurückholen der gesamten Tabelle auch Flashback Table einsetzen, die Tabelle archivieren und die betroffenen löschen könnten, ist es in unserem Fall einfacher, die gelöschten Zeilen abzuholen und in die Archivtabelle einzufügen. Ein andere Variante von Flashback Table ist der Einsatz von Create Table As Select (CTAS) mit einer Flashback Query als Unterabfrage: SQL> create table hr.employees_deleted as 2 select * from hr.employees 3 as of timestamp systimestamp - interval '60' minute 4 where hr.employees.employee_id not in 5 (select employee_id from hr.employees); Table created. SQL> select employee_id, last_name from hr.employees_deleted; EMPLOYEE_ID ----------195 196 LAST_NAME --------------------------Jones Walsh 2 rows selected. Diese Variante bezeichnet man als Out-of-Place-Restore (mit andern Worten, das Wiederherstellen der Tabelle oder eines Tabellensubsets an einem anderen Standort). Das hat den Vorteil, dass man die fehlenden Zeilen manipulieren kann, bevor man sie wieder in die Tabelle platziert; beispielsweise kann ein referenzieller Integritäts-Constraint verlangen, dass man die Zeile zuerst in eine Parent-Tabelle einfügt, bevor die wiederhergestellte Zeile wieder in der Child-Tabelle hinterlegt werden darf. Ein Nachteil des Out-of-Place-Restore mit CTAS ist, dass weder Constraints noch Indizes wiederhergestellt werden. 7.4.2 DBMS_FLASHBACK Eine Alternative zu Flashback Query ist das DBMS_FLASHBACK-Package. Einer der wichtigsten Unterschiede zwischen DBMS_FLASHBACK und Flashback Query ist, dass DBMS_FLASHBACK auf Sitzungsebene und Flashback Query auf Objektebene operiert. DBMS_FLASHBACK lässt sich innerhalb einer PL/SQL-Prozedur oder Benutzersitzung aktivieren, und alle nachfolgenden Operationen, inklusive der existierenden Applikationen, lassen sich ausführen, ohne in select-Anweisungen die as of-Klausel anzugeben. Nach dem Aktivieren von DBMS_FLASHBACK für einen bestimmten Zeitstempel oder eine SCN erscheint die Datenbank so, als ob die Uhr auf den Zeitstempel oder eine SCN zurückgestellt worden sei. Dieser Zustand hält bis zum Deak- 294 7 Transaktionsverwaltung mit Undo-Tablespaces tivieren von DBMS_FLASHBACK an. Obwohl bei aktiviertem DBMS_FLASHBACK keine DMLs erlaubt sind, lässt sich vor dem Aktivieren von DBMS_FLASHBACK in einer PL/SQL-Prozedur einen Cursor öffnen, damit man Daten von einem früheren Zeitpunkt übernehmen und im aktuellen Zeitpunkt einfügen oder aktualisieren kann. Tabelle 7-2 enthält die verfügbaren Prozeduren in DBMS_FLASHBACK. Tabelle 7-2: DBMS_FLASHBACK-Prozeduren. Prozedur Beschreibung DISABLE Deaktiviert den Flashback-Modus für die Sitzung. ENABLE_AT_SYSTEM_CHANGE_NUMBER Aktiviert den Flashback-Modus unter Angabe einer SCN für die Sitzung. ENABLE_AT_TIME Aktiviert den Flashback-Modus für die Sitzung, wobei die SCN verwendet wird, die dem angegebenen Zeitstempel am nächsten liegt. GET_SYSTEM_CHANGE_NUMBER Liefert die aktuelle SCN. SCN_TO_TIMESTAMP Konvertiert einen Oracle-TIMESTAMP und liefert die SCN, die dem TIMESTAMP-Wert am nächsten liegt. TIMESTAMP_TO_SCN Die Prozeduren zum Aktivieren und Deaktivieren des Flashback-Modus sind einfach zu bedienen. Die Komplexität liegt üblicherweise in der PL/SQL-Prozedur, die beispielsweise zur Unterstützung von DML-Befehlen einen Cursor anlegt. Im folgenden Beispiel widmen wir uns noch einmal dem Benutzer SCOTT und den gelöschten Zeilen in der HR.EMPLOYEES-Tabelle, und zeigen, wie man die Tabelle mit Hilfe des DBMS_FLASHBACK-Package wiederherstellt. In diesem Szenario bindet SCOTT die gelöschten Zeilen wieder in die Tabelle ein: SQL> delete from hr.employees where employee_id in (195,196); 2 rows deleted. SQL> commit; Commit complete. Nach einer halben Stunde entscheidet SCOTT, dass er die beiden Zeilen mit dem DBMS_FLASHBACK-Package zurückholt, und aktiviert Flashback für die Sitzung. SQL> execute dbms_flashback.enable_at_time( 2 to_timestamp(sysdate - interval '45' minute)); PL/SQL procedure successfully completed. 7.4 295 Flashback-Optionen Danach prüft er, ob die beiden gelöschten Zeilen genauso wie vor einer dreiviertel Stunde vorliegen: SQL> select employee_id, last name from hr.employees 2 where employee_id in (195,196); EMPLOYEE_ID ----------195 196 LAST_NAME -----------------------Jones Walsh SQL> Um die beiden Zeilen wieder in die HR.EMPLOYEES-Tabelle zurückzubringen, schreibt SCOTT eine anonyme PL/SQL-Prozedur, in der er einen Cursor zur Aufnahme der gelöschten Zeilen anlegt, Flashback Query deaktiviert, und danach die Zeilen wieder einfügt: declare -- cursor to hold deleted rows before closing cursor del_emp is select * from hr.employees where employee_id in (195,196); del_emp_rec del_emp%rowtype; -- all columns of the employee row begin -- open the cursor while still in Flashback mode open del_emp; -- turn off Flashback so we can use DML to put the rows -- back into the HR.EMPLOYEES table dbms_flashback.disable; loop fetch del_emp into del_emp_rec; exit when del_emp%notfound; insert into hr.employees values del_emp_rec; end loop; commit; close del_emp; end; -- anonymous PL/SQL procedure Beachten Sie, dass SCOTT das Flashback auch innerhalb der Prozedur aktivieren könnte. Im konkreten Fall aktivierte er es zum Ausführen von Ad-hoc-Abfragen außerhalb der Prozedur. Danach nutzte der die Prozedur zum Anlegen des Cursors, zum Ausschalten von Flashback und zum Wiedereinfügen der Zeilen. 7.4.3 Flashback Table Die Flashback Table-Funktion in Oracle 10g stellt nicht nur den Status von Tabellenzeilen für einen Zeitpunkt in der Vergangenheit wieder her, sondern auch die dazugehörigen Indizes, Trigger und Constraints. Und das während die Datenbank online ist, 296 7 Transaktionsverwaltung mit Undo-Tablespaces was die Verfügbarkeit der Datenbank wesentlich verbessert. Die Tabelle lässt sich für einen Zeitstempel oder eine SCN zurücksetzen. Flashback Table bewährt sich gegenüber anderen Flashback-Methoden, wenn die Auswirkungen von Benutzerfehlern nur gering sind und sich auf wenige Tabellen beschränken. Zur Wiederherstellung des Status von mehreren Tabellen ist Flashback Database die bessere Wahl. Flashback Table lässt sich nicht auf eine Standby-Datenbank oder zum Rekonstruieren von DML-Operationen einsetzen, wie das Hinzufügen oder Entfernen von Spalten. Um Flashback Table auf Tabellen einzusetzen, ist vor dem Ausführen der FlashbackOperation die Zeilenverschiebung zu aktivieren, die allerdings zu dem Zeitpunkt, wenn der Benutzerfehler auftritt, nicht aktiv sein muss. Die Zeilenverschiebung benötigt man auch zur Unterstützung der Segmentverkleinerung: Da die Zeilenverschiebung allerdings die ROWID auf eine Tabellenzeile ändert, sollten Sie diese Option nicht aktivieren, falls Ihre Applikation davon abhängt, dass die ROWID bis zum Löschen einer Zeile gleich sein muss. Da keine Ihrer Applikationen die Tabellen via ROWID referenziert, aktivieren Sie für Ihre Tabellen die Zeilenverschiebung: SQL> alter table hr.employees enable row movement; Table altered. SQL> alter table hr.departments enable row movement; Table altered. Am nächsten Tag löscht SCOTT auf Grund eines Fehlers beim Ausschneiden/Einfügen aus einem bestehenden Skript versehentlich alle Zeilen in der HR.EMPLOYEESTabelle: SQL> delete from hr.employees 2 / 107 rows deleted. SQL> commit 2 ; Commit complete. SQL> where employee_id = 195 SP2-0734: unknown command beginning "where empl..." - rest of line ignored. Da der Undo-Tablespace groß genug ist und die Vorhalteperiode 12 Stunden beträgt, kann SCOTT, auch ohne DBA, die gesamte Tabelle schnell wiederherstellen: SQL> flashback table hr.employees 2 to timestamp systimestamp - interval '15' minute; Flashback complete. 7.4 Flashback-Optionen 297 SQL> select count(*) from hr.employees; COUNT(*) ---------107 Sollten Tabellen eine Parent/Child-Beziehung mit Primärschlüssel-Constraints besitzen, und aus beiden Zeilen wurden unbeabsichtigt Zeilen gelöscht, lassen sie sich im gleichen Flashback-Befehl zurücksetzen: SQL> flashback table hr.employees, hr.departments 2 to timestamp systimestamp - interval '15' minute; Flashback complete. Abbildung 7-9: EM Database Control Backup/Recovery. SCOTT kann Tabellen auch mit der EM Database Control zurückblenden. In Abbildung 7-9 selektierte er im Maintenance-Register unter der Überschrift Backup/Recovery den Perform Recovery-Link. Wählt SCOTT als Objekttyp Tables, hat er die Option, vorhandene oder gelöschte Tabellen zurückzusetzen. Im vorliegenden Fall wird er eine bestehende Tabelle zurückblenden (siehe Abbildung 7-10). Nach einem Klick auf Next kennt er den genauen Zeitpunkt, wann die Tabelle gültig war, und gibt es in Bildschirm 7-11 ein. 298 7 Transaktionsverwaltung mit Undo-Tablespaces Abbildung 7-10: Bestehende Tabellen zurückblenden. Abbildung 7-11: Auswahl von Datum und Zeit für Flashback Table. 7.4 Flashback-Optionen 299 In Abbildung 7-12 entscheidet sich SCOTT für das Flashback einer Tabelle (in diesem Fall HR.EMPLOYEES). Dieser Bildschirm zeigt den gewählten Bildschirm und die äquivalente SCN. Abbildung 7-12: Auswahl von Flashback Table. EM Database Control identifiziert alle Abhängigkeiten, wie Fremdschlüssel-Constraints, und alarmiert SCOTT in Abbildung 7-13. Falls es nicht gute Gründe zum Aufbrechen von Parent/Child-Beziehungen zwischen Tabellen gibt, lassen Sie die Standardoption Cascade selektiert. Ein Klick auf Show Dependencies macht genau das: Es zeigt die Abhängigkeiten zwischen den Fremdschlüsseln in der zurückzusetzenden Tabelle und den Parent-Tabellen. Die gesamte Hierarchie von Abhängigkeiten ist in Abbildung 7-14 zu sehen. In Abbildung 7-15 kann SCOTT nochmals die selektierten Optionen sehen. Und wie bei den meisten EM Database Control-Anzeigen kann man sich die generierten SQL-Befehle ansehen: FLASHBACK TABLE HR.EMPLOYEES, HR.JOBS, HR.DEPARTMENTS TO TIMESTAMP to_timestamp('2004-04-15 06:15:12 PM', 'YYYY-MM-DD HH:MI:SS AM') Ein Klick auf Submit führt den Befehl aus. 300 7 Transaktionsverwaltung mit Undo-Tablespaces Abbildung 7-13: Abhängigkeitsoptionen bei Flashback. Abbildung 7-14: Die Abhängigkeitshierarchie bei Flashback. 7.4 Flashback-Optionen 301 Abbildung 7-15: Flashback Table: Optionsübersicht. Beachten Sie, dass Sie in SCOTTs Beispiel Ihr Ziel über die Befehlszeile weit schneller erreicht hätten. Liegen allerdings unbekannte Abhängigkeiten vor, oder sollten Sie die Syntax nicht kennen, ist der OEM die bessere Option. 7.4.4 Flashback Version Query Die Flashback Version Query ist eine weitere Flashback-Option, die auf Undo-Daten aufsetzt. Sie bietet eine feinere Detailebene als eine as of-Abfrage. Während die bisher vorgestellten Flashback-Methoden für einen bestimmten Zeitpunkt entweder Zeilen oder ganze Tabellen zurückbringen, liefert Flashback Version Query anhand von zwei SCNs oder Zeitstempeln die gesamte Historie einer gegebenen Zeile zurück. In diesem und dem folgenden Beispiel führt der Benutzer SCOTT an den Tabellen HR.EMPLOYEES und HR.DEPARTMENTS zahlreiche Änderungen aus: SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER -----------------------1673333 SQL> update hr.employees set salary = salary*1.2 where employee_id=195; 1 row updated. SQL> select dbms_flashback.get_system_change_number from dual; 302 7 Transaktionsverwaltung mit Undo-Tablespaces GET_SYSTEM_CHANGE_NUMBER -----------------------1673349 SQL> delete from hr.employees where employee_id = 196; 1 row deleted. SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER -----------------------1673406 SQL> insert into hr.departments values (660,'Security', 100, 1700); 1 row created. SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER -----------------------1673433 SQL> update hr.employees set manager_id = 100 where employee_id = 195; 1 row updated. SQL> commit; Commit complete. SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER -----------------------1673455 SQL> update hr.employees set department_id = 660 where employee_id = 195; 1 row updated. SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER -----------------------1673602 SQL> update hr.employees set salary = salary*1.2 where employee_id=195; 1 row updated. SQL> commit; Commit complete. SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER -----------------------1674188 SQL> 7.4 303 Flashback-Optionen Am folgenden Tag ist SCOTT nicht im Büro und die HR-Abteilung möchte wissen, welche Zeilen und Tabellen geändert wurden. Mit der Flashback Version Query kann der Benutzer HR nicht nur die Werte einer Spalte für einen bestimmten Zeitpunkt sehen; er sieht die gesamte Änderungshistorie zwischen den angegebenen Zeitstempeln oder SCNs. Mit der versions between-Klausel geben Sie einer Flashback Version Query den SCNBereich oder die Zeitstempel zum Analysieren einer Tabelle vor (in unserem Fall die HR.EMPLOYEES-Tabelle). Setzt man diese Klausel ein, lassen sich über verschiedene Pseudospalten diverse Informationen ableiten: die SCNs und Zeitstempel für Änderungen, die Transaktions-ID und der ausgeführte Operationstyp. Tabelle 7-3 zeigt die verfügbaren Pseudospalten für Flashback Version Queries: Der Benutzer HR führt eine Flashback Version Query aus, und möchte alle Änderungen auf die Schlüsselspalten in HR.EMPLOYEES für die beiden Angestellten mit den IDs 195 und 196 sehen: SQL> select versions_startscn startscn, versions_endscn endscn, 2 versions_xid xid, versions_operation oper, 3 employee_id empid, last_name name, manager_id mgrid, salary sal 4 from hr.employees 5 versions between scn 1673333 and 1674188 6 where employee_id in (195,196); STARTSCN ENDSCN XID OPER EMPID NAME MGRID SAL --------- --------- ---------------- ---- ----- -------- ------------ --1674182 0400240098030000 U 195 Jones 100 4032 1673453 1674182 0400160098030000 U 195 Jones 100 3360 1673368 1673453 04000F0098030000 U 195 Jones 123 3360 1673368 195 Jones 123 2800 1673368 04000F0098030000 D 196 Walsh 124 3100 1673368 196 Walsh 124 3100 6 rows selected. Tabelle 7-3: Pseudospalten für Flashback Version Query. Pseudospalte Beschreibung VERSIONS_START{SCN|TIME} Die Start-ID oder den Zeitstempel für den Zeitpunkt, als die Änderung an der Zeile ausgeführt wurde. VERSION_END{SCN|TIME} Die End-ID oder den Endezeitstempel, als die Änderung für die Zeile nicht mehr gültig war. Ist der Wert NULL, ist die Zeilenversion entweder noch gültig oder die Zeile wurde gelöscht. 304 7 Transaktionsverwaltung mit Undo-Tablespaces Tabelle 7-3: Pseudospalten für Flashback Version Query. (Fortsetzung) Pseudospalte Beschreibung VERSIONS_XID Die Transaktions-ID der Transaktion, die die Zeilenversion anlegte. VERSIONS_OPERATION Die auf die Zeile ausgeführte Operation (I=Insert, D=Delete, U=Update). Die Zeilen mit den letzten Änderungen werden zuerst angezeigt. Alternativ könnte HR die Abfrage nach TIMESTAMP ausführen oder sich die TIMESTAMP-Werte anzeigen lassen; aber beide Varianten lassen sich zu einem späteren Zeitpunkt in einer Flashback Query oder Flashback Table-Operation einsetzen. In dieser Ausgabe sehen wir, dass ein Angestellter gelöscht wurde und ein anderer Angestellter gleich zwei Gehälter erhielt. Zudem können wir festhalten, dass manche Operationen nur ein, andere hingegen zwei DML-Befehle enthielten. Im folgenden Abschnitt versuchen wir, diese Probleme zu beheben. 7.4.5 Flashback Transaction Query Nach dem Aufdecken von fehlerhaften oder falschen Änderungen in einer Tabelle lassen sich mit einer Flashback Transaction Query alle anderen Modifikationen ermitteln, die von der Transaktion mit den unpassenden Änderungen ausgeführt wurden. Danach kann man sämtliche Änderungen als Gruppe rückgängig machen. Damit werden typischerweise die referenzielle Integrität oder die Geschäftsregeln gewahrt. Eine Flashback Transaction Query referenziert im Unterschied zu einer Flashback Version Query nicht die Tabelle, die in DML-Transaktionen eingebunden war; stattdessen fragen Sie die Data Dictionary View FLASHBACK_TRANSACTION_QUERY ab. Die Spalten von FLASHBACK_TRANSACTION_QUERY sind in Tabelle 7-4 zusammengefasst. Tabelle 7-4: Die Spalten in FLASHBACK_TRANSACTION_QUERY. Spaltenname Beschreibung XID Nummer der Transaktions-ID START_SCN SCN für die erste DML in der Transaktion START_TIMESTAMP Zeitstempel für die erste DML in der Transaktion COMMIT_SCN SCN, als die Transaktion festgeschrieben wurde COMMIT_TIMESTAMP Zeitstempel, als die Transaktion festgeschrieben wurde. 7.4 305 Flashback-Optionen Tabelle 7-4: Die Spalten in FLASHBACK_TRANSACTION_QUERY. (Fortsetzung) Spaltenname Beschreibung LOGON_USER Benutzer, dem die Transaktion gehört UNDO_CHANGE# Undo-SCN OPERATION Ausgeführte DML-Operation: DELETE, INSERT, UPDATE, BEGIN oder UNKNOWN TABLE_NAME Tabelle, die von der DML geändert wurde TABLE_OWNER Eigentümer der Tabelle, die von der DML geändert wurde ROW_ID ROWID der Zeile, die von der DML geändert wurde UNDO_SQL SQL-Anweisung, zum Zurücksetzen der DML-Operation Um die Änderungen auf die HR.EMPLOYEES-Tabelle eingehender zu untersuchen, fragen wir die View FLASHBACK_TRANSACTION_QUERY mit der ältesten Transaktion aus der Abfrage im letzten Abschnitt ab: SQL> select start_scn, commit_scn, logon_user, 2 operation, table_name, undo_sql 3 from flashback_transaction_query 4 where xid = hextoraw('04000F0098030000'); START_SCN COMMIT_SCN LOGON_USER OPERATION TABLE_NAME --------- ---------- ----------- ------------ ---------UNDO_SQL -------------------------------------------------------1673366 1673368 SCOTT DELETE EMPLOYEES insert into "HR"."EMPLOYEES"("EMPLOYEE_ID","FIRST_NAME","LAS T_NAME","EMAIL","PHONE_NUMBER","HIRE_DATE","JOB_ID","SALARY" , "COMMISSION_PCT" , "MANAGER_ID" , "DEPARTMENT_ID" ) values ( ' 196 1,'Alana','Walsh','AWALSH','650.507.9811',TO_DATE('24-APR-98 ', 'DD-MON-RR'),'SH_CLERK','3100',NULL,'124','50'); 1673366 1673368 SCOTT UPDATE update "HR"."EMPLOYEES" set "SALARY" = 'AAAMAeAAFAAAABYABc ' ; 1673366 3 1673368 SCOTT '2800' EMPLOYEES where ROWID = BEGIN rows selected. Das Ergebnis bestätigt, was wir erwarteten – die Löschoperation und die Aktualisierung des Gehalts wurden von SCOTT ausgeführt. Die UNDO_SQL-Spalte enthält den Code, mit dem sich der Effekt der Transaktion rückgängig machen lässt. In unserem 306 7 Transaktionsverwaltung mit Undo-Tablespaces Beispiel geht es um die erste Transaktion zwischen den gewählten SCNs. Wurden zu einem früheren Zeitpunkt auf dieselbe Spalte irgendwelche Änderungen ausgeführt, sollte man vor dem Ausführen dieses SQL-Codes die anderen Aktualisierungen ansehen. Wenn wir uns in der Serie die letzte Transaktion ansehen, erkennen wir, dass es für die SALARY-Spalte des Angestellten eine neuere Aktualisierung gibt: SQL> select start_scn, commit_scn, logon_user, 2 operation, table_name, undo_sql 3 from flashback_transaction_query 4 where xid = hextoraw('04000F0098030000'); START_SCN COMMIT_SCN LOGON_USER OPERATION TABLE_NAME --------- ---------- ----------- ------------ ---------UNDO_SQL -------------------------------------------------------1673386 1674182 SCOTT UPDATE EMPLOYEES update "HR"."EMPLOYEES" set "SALARY" = '3360' where ROWID = 'AAAMAeAAFAAAABYABc ' ; 1673386 1674182 SCOTT INSERT JOB_HISTORY delete from "HR"."JOB_HISTORY" where ROWID = 'AAAMAiAAFAAAAB tAAB ' ; 1673386 1674182 SCOTT UPDATE EMPLOYEES update "HR"."EMPLOYEES" set "DEPARTMENT_ID" = '50' where ROW ID = 'AAAMAeAAFAAAABYABc'; 1673386 4 1674182 SCOTT BEGIN rows selected. Die erste Gehaltsaktualisierung war gültig, während die zweite (aktuellere) dupliziert wurde, und daher ungültig ist. Innerhalb der gleichen Transaktion änderte SCOTT auch die DEPARTMENT_ID des Angestellten und führte ein insert auf die HR.JOB_ HISTORY aus. Das insert war nicht das Ergebnis eines impliziten Befehls, sondern geht auf das Konto eines Triggers auf die HR.JOB_HISTORY-Tabelle, der alle Änderungen von JOB_ID oder DEPARTMENT_ID in HR.EMPLOYEES an HR.JOB_HISTORY protokolliert. Damit ist lediglich die letzte Gehaltänderung rückgängig zu machen: SQL> update "HR"."EMPLOYEES" 2 set "SALARY" = '3360' where ROWID ='AAAMAeAAFAAAABYABc'; 1 row updated. SQL> commit; Commit complete. In der vorletzten Transaktion sieht man das insert in die HR.DEPARTMENTS-Tabelle plus die erneute Zuordnung des Angestellten zur neuen Abteilung: 7.5 307 Migration zum automatischen Undo-Management SQL> select start_scn, commit_scn, logon_user, 2 operation, table_name, undo_sql 3 from flashback_transaction_query 4 where xid = hextoraw(' 0400160098030000'); START_SCN COMMIT_SCN LOGON_USER OPERATION TABLE_NAME --------- ---------- ----------- ------------ ---------UNDO_SQL -------------------------------------------------------1673449 1673453 SCOTT UPDATE EMPLOYEES update "HR"."EMPLOYEES" set "MANAGER_ID" = '123' where ROWID = ' AAAMAeAAFAAAABYABc ' ; 1673449 1673453 SCOTT INSERT DEPARTMENTS delete from "HR"."DEPARTMENTS" where ROWID = 'AAAMAZAAFAAAAA 1AAB' ; 1673449 1673453 SCOTT BEGIN 3 rows selected. Da wir in der Flashback Version Query auf die DEPARTMENT_ID-Spalte verzichteten, war nicht sofort ersichtlich, dass auf die Spalten in der HR.EMPLOYEES-Tabelle weitere Änderungen ausgeführt wurden und zusätzlich eine neue Zeile in HR.DEPARTMENTS eingefügt wurde. 7.5 Migration zum automatischen Undo-Management Um Ihre Umgebung von manuell verwalteten Rollback-Segmenten auf das automatische Undo Management zu migrieren, müssen Sie eine Sache kennen; die Größe des Undo-Tablespace, basierend auf der Nutzung der Rollback-Segmente im manuellen Undo-Modus. Sind alle manuellen Rollback-Segmente online gesetzt, führen Sie die Prozedur DBMS_UNDO_ADV.RBU_MIGRATION aus: Sie liefert die aktuelle Belegung für die Rollback-Segmente in Megabytes zurück: SQL> variable undo_size number SQL> begin 2 :undo_size := dbms_undo_adv.rbu_migration; 3 end; 4 / PL/SQL procedure successfully completed. 308 7 Transaktionsverwaltung mit Undo-Tablespaces SQL> print :undo_size UNDO_SIZE 2840 SQL> In unserem Beispiel sollte ein Undo-Tablespace, der die Rollback-Segmente ersetzen soll, mindestens 2840MB oder 2,84GB groß sein. Nur so kann er alle Undo-Anforderungen aufnehmen, die derzeit von Rollback-Segmenten unterstützt werden.