Blog 
Flashback Query

2001 war die Oracle Open World in Deutschland und ein sehr bekannter Redner (Herr L. E.) kündigte Oracle 9i mit seinen fantastischen Features an. Eine der Funktionen hatte den Namen „Flashback Query“ und in seiner Rede sagte er so etwa „mit unserer neuen Flashback Technologie sind Sie in der Lage alte Daten zu lesen, die vor Tagen, Wochen oder Monaten gültig waren“. Das hörte sich zunächst einmal super an und man konnte im Saal förmlich sehen, wie die ersten Anwendungen Gestalt annahmen. Unglücklicherweise war die Realität doch wieder etwas anders als die Ankündigung: Flashback Query basiert auf den Informationen, die in den Undo Segmenten gespeichert wurden. Wenn man also zu dieser Zeit Daten hätte lesen wollen, die vor einem Monat gültig waren, hätte man eine Undo Retention von 2678400 (Sekunden) gebraucht und hoffentlich gute Preise mit seinem Storage Hersteller ausgehandelt, denn bei einer einigermaßen frequentierten Datenbank wären da schnell etliche Terabyte zusammen gekommen. In der Realität wird dadurch die Möglichkeit des Flashback Query auf einige wenige Stunden beschränkt.

Mit Oracle 11g wurde das Statement von 2001 dann allerdings doch wahr: Oracle gab die Verfügbarkeit der „Total Recall“ Option für die Enterprise Edition bekannt. Dieses Feature erlaubt es jetzt, für dedizierte Tabellen eine fest definierte Flashback Zeit anzugeben, die dazu führt, dass „alte“ Daten in einem separaten Bereich, dem Flashback Data Archive gespeichert werden. Zwar gab es in den ersten Versionen einige Einschränkungen (z.B. dass die Daten nicht gesichert werden konnten) aber prinzipiell funktionierte dieses Feature wie erwartet. Jetzt ist Flashback Query nicht mehr durch die Größe des Undo-Tablespaces beschränkt sondern alte Transaktionen können überwacht oder auch wieder rückgängig gemacht werden, selbst wenn sie mehrere Wochen oder Monate alt sind (je nachdem, wie der Parameter für die Flashback Data Archive gesetzt wurde). Allerdings war diese Option der Enterprise Edition vorbehalten und, da es sich um eine Option handelte, auch noch kostenpflichtig – bis Oracle 12c freigegeben wurde.

Nicht nur, dass es mit Oracle 12c zu dieser Option einige interessante Erweiterungen gibt und die Funktion nicht länger „Total Recall“ sondern „Flashback Data Archive“ heißt, das Feature ist kostenfrei für die Enterprise Edition und – was mich besonders freut – auch in der Standard bzw. Standard One Edition verfügbar. Und dies gilt sowohl für die neue Oracle 12c als auch für Oracle 11.2.0.4.

Jetzt ist es wirklich sinnvoll sich mit der Funktionalität näher auseinander zu setzen.

Flashback Data Archive

Zunächst einmal ist Flashback Data Archive (oder Flashback Archive, kurz FBA) einfach ein Platzhalter in einem existierenden Tablespace. Für die Definition wird nur ein Tablespace angegeben und die Retention Zeit also die Dauer der Aufbewahrung „alter“ Daten.

CREATE FLASHBACK ARCHIVE fda1
TABLESPACE fda_tablespace
RETENTION 2 YEAR;

Man kann beliebig viele FBAs anlegen, da sie zunächst keinen weiteren Platz benutzen. Das ist sicherlich auch sinnvoll, da es für unterschiedliche Tabellen unterschiedliche Aufbewahrungsfristen gibt. Und so sieht die Abfrage auf die FBA aus:

SELECT owner_name AS owner, flashback_archive_name, retention_in_days
FROM dba_flashback_archive;

OWNER   FLASHBACK_ARCHIVE_NAME RETENTION_IN_DAYS
------- ---------------------- -----------------
SYSTEM  FDA1                                 730

Im nächsten Schritt wird jetzt definiert, für welche Tabellen die Daten in der FBA aufbewahrt werden. Dabei ist es wichtig zu wissen, dass der Schemaowner entsprechende Quota auf dem Tablespace haben muss, in dem die FBA liegt (in diesem Fall also im Tablespace fba_tablespace).

ALTER TABLE demo.personen FLASHBACK ARCHIVE fda1;
ALTER TABLE demo.auftraege FLASHBACK ARCHIVE fda1;
ALTER TABLE demo.positionen FLASHBACK ARCHIVE fda1;
ALTER TABLE demo.adressen FLASHBACK ARCHIVE fda1;
ALTER TABLE demo.telefone FLASHBACK ARCHIVE fda1;

Das war alles.

Für jede Tabelle gibt es jetzt ein Pendant in der FBA. Das kann man sich mit folgender Query ansehen:

SELECT * FROM dba_flashback_archive_tables;

TABLE_NAME   OWNER_NAME   FLASHBAC    ARCHIVE_TABLE_NAME   STATUS
------------ ------------ ----------  -------------------- --------
PERSONEN     DEMO         FDA1        SYS_FBA_HIST_92011   ENABLED
AUFTRAEGE    DEMO         FDA1        SYS_FBA_HIST_92007   ENABLED
POSITIONEN   DEMO         FDA1        SYS_FBA_HIST_92015   ENABLED
ADRESSEN     DEMO         FDA1        SYS_FBA_HIST_92005   ENABLED
TELEFONE     DEMO         FDA1        SYS_FBA_HIST_92023   ENABLED

Wenn man ins Detail geht, stellt man fest, dass alle diese Tabellen partitioniert sind. Das gilt auch, wenn es sich um die Standard Edition handelt.

Wenn jetzt eine Flashback Query ausgeführt wird, wird diese, wenn sich die „alten“ Daten nicht mehr in den Undo-Segmenten befinden automatisch auf die FBA umgeleitet.

SELECT * FROM personen
AS OF TIMESTAMP to_date('2013-12-19 15:00:00','YYYY-MM-DD HH24:MI:SS');

Natürlich ist es auch möglich, die „alten“ Daten direkt aus den FBA Tabellen zu selektieren.

Transaction Context

Manchmal möchte man allerdings nicht nur die Daten haben sondern auch wissen, welche Anwendung oder welcher Benutzer diese geändert hat. Seit Version 12c kann diese Information ebenfalls mit in der FBA abgespeichert werden. Mit der Prozedur dbms_flashback.set_context_level ist es möglich, zusätzliche Informationen zu speichern:

dbms_flashback_archive.set_context_level ('ALL' | 'TYPICAL' | 'NONE');

Derzeit sieht es allerdings so aus, als ob diese Funktion nur datenbankweit gesetzt werden kann, es scheint nicht möglich, für bestimmte Tabellen oder bestimmte FBAs den Parameter zu setzen. Wenn dieser Kontext gesetzt ist, wird in der FBA der Tabelle für jede Transaktion eine ID (XID) gespeichert und diese verweist dann auf den Kontext, der sich in der Tabelle SYS_FBA_CONTEXT_AUD befindet. Abgefragt werden kann dieser Kontext mit der Funktion GET_SYS_CONTEXT wie im folgenden Beispiel zu sehen:

SELECT xid, persid, strasse, plz, ort
FROM demo.sys_fba_hist_92005;

XID                  PERSID STRASSE         PLZ ORT
---------------- ---------- ---------- -------- ----------
0500080028070000     100101 Behnitz       10115 Berlin

SELECT dbms_flashback_archive.get_sys_context('0500080028070000','USERENV','MODULE') AS CONTEXT
FROM DUAL;

CONTEXT
----------------
SQL*Plus

SELECT xid, authenticated_identity, host, module, os_user, session_user, terminal
FROM sys.sys_fba_context_aud;

XID              AUTHENTIC HOST                      MODULE          OS_USER           SESSION_US TERMINAL
---------------- --------- ------------------------- --------------- ----------------- ---------- ----------
0500080028070000 demo      albinoni.carajandb.intra  SQL*Plus oracle DEMO              pts/1
090016003F080000 SYSTEM    CARAJANDB                 TOAD 12.1.0.22  Johannes Ahrends  SYSTEM     xxx

Zusammenfassung

Durch die Möglichkeit Flashback Data Archive jetzt kostenlos in allen Oracle Editionen nutzen zu können ergeben sich sicherlich eine ganze Reihe von neuen Möglichkeiten. Der Aufbau ist einfach und FBA wartet geradezu darauf, genutzt zu werden.

Für Fragen und Anregungen sowie gerne auch kontroverse Diskussion stehe ich selbstverständlich zur Verfügung.

Viel Spaß

2 Kommentare zu “Flashback Query

Zwei Fragen:

1.) Haben Sie auch bemerkt, dass das Statement set_context_level(‚ALL‘) dazu führt, dass sehr schnell die flashback queries die die Funktion get_context_leven beinhalten unakzeptabel langsam werden ?

2.) Die dahinter liegende Tabelle läßt sich nicht aus dem SYSTEM Tablespace verschieben und wächst enorm an.

Danke für die Info. Das war mir in der Tat noch nicht aufgefallen (allerdings habe ich mit set_context_level(‚ALL‘) auch nur experimentiert und das nicht produktiv laufen. Es war mir allerdings schon klar, dass das große Datenmengen produziert.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Was kann CarajanDB für Sie tun?