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