Exceptionfault
Erfahrenes Mitglied
Hallo,
seit langem komme ich nun endlich wieder dazu ein kleines Tutorial fürs Forum zu verfassen. Wer schonmal einen Beitrag von mir gelesen hat kann sich auch denken was diesmal das Thema sein wird, ;-) Oracle !
Thema soll ein neues, und in meinen Augen geniales Feature, der neuen Oracle Releases 10g sein, das Flashback. Ganz grob zur Einführung könnte man es mit dem Recyclebin oder Papierkorb unter Windows vergleichen. Flashback ermöglicht es tatsächlich mit geringem Aufwand gelöschte Daten wieder herzustellen. Zwar nicht unbegrenzt in die Vergangenheit (es ist eine Frage desSpeicherplatzes...) aber dafür kann es noch viele viele tolle andere Sachen.
Es folgen ein paar kleine Anwendungsbeispiele für Flashback, doch zunächst die technischen Vorbereitungen der Datenbank:
Voraussetzung ist, dass die Datenbank in Archivelog Modus läuft, was bei Produktiven Datenbanken sowieso die Regel sein sollte!
Zweitens muss eine sog. flash_recovery_area definiert werden (INIT.ORA Parameter). Wo die liegt und wieviel Platz dafür reserviert wird kann man durch folgenden Befehl herausfinden:
Meine liegt also unter "/u01/flash_recovery_area" (Linux) und darf 2GB groß werden.
Dann müssen wir das Flashback natürlich auch anschalten. Das geht leider nur durch einen Neustart der Datenbank:
Hats funktioniert ?
Wunderbar. Nun die Vorbereitungen für meine Beispiele... ich brauche eine Benutzer und eine kleine Tabelle:
Beim einfügen der Datensätze lasse ich mir etwas Zeit und Committe auch zwischendurch. Nehmen wir an es wären Benutzer die mit dem System gearbeitet haben und Schritt für Schritt Daten erfasst haben.
So, nun wird aber im System auch weiter gearbeitet, vielleicht ein paar Daten korrigiert:
Und natürlich arbeiten auf unserer Applikation auch Azubis ;-)
Oha! Was nun Ein Backup wieder einspielen dauert viel zu lange. Die Daten wieder eingeben? Die Archive Logs nach den Statements durchsuchen?
Nein, natürlich nicht, sondern Flashback!
Unsere Datenbank hat sich während der ganzen Arbeitszeit unmerklich ein paar Informationen in die Flashback Area geschrieben und die holen iwr uns jetzt wieder zurück. Oracle hat das SELECT Statement um Flashback Optionen erweitert. Schauen wir doch also mal, wie die Tabelle vor wenigen Minuten noch aussah:
Wie man sieht kann ich sowohl den Stand vor dem DELETE als auch vor dem Update ermitteln. Unsere Tabelle ist dabei immernoch leer! Ich mache quasi ein Select in die Vergangenheit. Das geht sogar noch weiter zurück als noch Daten erfasst wurden:
Gut, jetzt wollen wir aber auch den Schade wieder reparieren. Hierfür müssen wir eine Option der Tabelle ändern, das sog. "row movement". Es dürfte dem normalen User kein Unterschied auffallen ob der Parameter gesetzt ist oder nicht, er entscheidet lediglich über das interne Speicherverhalten der Datensätze.
Und nun stellen wir die Tabelle wieder her!
Cool, oder ?
Aber das geht noch weiter! Setzen wir mal alle Sätze auf das gleiche Datum, das machts etwas leichter zu sehen.
Jetzt fügen wir einen neuen Satz hinzu und löschen einen anderen raus.
Wie wärs denn jetzt mit einer Liste der Änderungen ? ;-)
Nunja, das war wie immer nur ein kleiner Teil der Möglichkeiten. Oracle hat das ganze Spiel natürlich wieder "übertrieben" und ermöglicht nicht nur ein Flashback Table sondern gleich ein Flashback Database *g*.
Das wirklich einzige Problem an der Sache ist: Man darf sich nie drauf verlassen wie lange etwas vorgehalten wird. Wie gesagt liegt das an der Größe der Area und an der auftretenden Last. Je mehr gearbeitet wird, dest mehr Daten fallen an und desto schneller sind die 2GB ( bei mir) voll und alte Sachen fliegen raus.
seit langem komme ich nun endlich wieder dazu ein kleines Tutorial fürs Forum zu verfassen. Wer schonmal einen Beitrag von mir gelesen hat kann sich auch denken was diesmal das Thema sein wird, ;-) Oracle !
Thema soll ein neues, und in meinen Augen geniales Feature, der neuen Oracle Releases 10g sein, das Flashback. Ganz grob zur Einführung könnte man es mit dem Recyclebin oder Papierkorb unter Windows vergleichen. Flashback ermöglicht es tatsächlich mit geringem Aufwand gelöschte Daten wieder herzustellen. Zwar nicht unbegrenzt in die Vergangenheit (es ist eine Frage desSpeicherplatzes...) aber dafür kann es noch viele viele tolle andere Sachen.
Es folgen ein paar kleine Anwendungsbeispiele für Flashback, doch zunächst die technischen Vorbereitungen der Datenbank:
Voraussetzung ist, dass die Datenbank in Archivelog Modus läuft, was bei Produktiven Datenbanken sowieso die Regel sein sollte!
Zweitens muss eine sog. flash_recovery_area definiert werden (INIT.ORA Parameter). Wo die liegt und wieviel Platz dafür reserviert wird kann man durch folgenden Befehl herausfinden:
Code:
SQL> sho parameter db_recovery
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string /u01/flash_recovery_area
db_recovery_file_dest_size big integer 2G
Dann müssen wir das Flashback natürlich auch anschalten. Das geht leider nur durch einen Neustart der Datenbank:
Code:
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 201326592 bytes
Fixed Size 1218508 bytes
Variable Size 67110964 bytes
Database Buffers 130023424 bytes
Redo Buffers 2973696 bytes
Database mounted.
SQL> alter database archivelog;
Database altered.
SQL> alter database flashback on;
Database altered.
SQL> alter database open;
Database altered.
Hats funktioniert ?
Code:
SQL> select FLASHBACK_ON from v$database;
FLASHBACK_ON
------------------
YES
Wunderbar. Nun die Vorbereitungen für meine Beispiele... ich brauche eine Benutzer und eine kleine Tabelle:
Code:
SQL> create user flash identified by back;
User created.
SQL> grant dba to flash;
Grant succeeded.
SQL> conn flash/back
Connected.
SQL> alter session set nls_date_format = 'DD.MM.YYYY HH24:MI:SS';
Session altered.
SQL> create table test (
2 field1 NUMBER(5) NOT NULL,
3 field2 VARCHAR2(10) NOT NULL,
4 field3 DATE NOT NULL
5 );
Table created.
Beim einfügen der Datensätze lasse ich mir etwas Zeit und Committe auch zwischendurch. Nehmen wir an es wären Benutzer die mit dem System gearbeitet haben und Schritt für Schritt Daten erfasst haben.
Code:
SQL> insert into test values ( 1, 'Hello ', SYSDATE );
1 row created.
SQL> commit;
Commit complete.
SQL> insert into test values ( 2,'World', SYSDATE );
1 row created.
SQL> commit;
Commit complete.
SQL> insert into test values(3,' ',SYSDATE );
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test;
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
1 Hello 15.02.2006 22:55:21
2 World 15.02.2006 22:56:12
3 15.02.2006 22:56:29
Code:
SQL> update test set field2 = 'User', field3 = SYSDATE where field1 = 2;
SQL> select * from test;
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
1 Hello 15.02.2006 22:55:21
2 User 15.02.2006 22:58:32
3 15.02.2006 22:56:29
Code:
SQL> DELETE FROM TEST;
3 rows deleted.
SQL> commit;
Commit complete.
SQL> select * from test;
no rows selected
Nein, natürlich nicht, sondern Flashback!
Unsere Datenbank hat sich während der ganzen Arbeitszeit unmerklich ein paar Informationen in die Flashback Area geschrieben und die holen iwr uns jetzt wieder zurück. Oracle hat das SELECT Statement um Flashback Optionen erweitert. Schauen wir doch also mal, wie die Tabelle vor wenigen Minuten noch aussah:
Code:
SQL> select * from test as of timestamp to_date('15.02.2006 22:59:00', 'dd.mm.yyyy hh24:mi:ss');
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
1 Hello 15.02.2006 22:55:21
2 User 15.02.2006 22:58:32
3 15.02.2006 22:56:29
SQL> select * from test as of timestamp to_date('15.02.2006 22:58:00', 'dd.mm.yyyy hh24:mi:ss');
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
1 Hello 15.02.2006 22:55:21
2 World 15.02.2006 22:56:12
3 15.02.2006 22:56:29
Code:
SQL> select * from test as of timestamp to_date('15.02.2006 22:55:40', 'dd.mm.yyyy hh24:mi:ss');
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
1 Hello 15.02.2006 22:55:21
Code:
SQL> alter table test enable row movement;
Table altered.
Code:
SQL> flashback table test to timestamp to_date('15.02.2006 22:58:00', 'dd.mm.yyyy hh24:mi:ss');
Flashback complete.
SQL> select * from test;
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
1 Hello 15.02.2006 22:55:21
2 World 15.02.2006 22:56:12
3 15.02.2006 22:56:29
Cool, oder ?
Aber das geht noch weiter! Setzen wir mal alle Sätze auf das gleiche Datum, das machts etwas leichter zu sehen.
Code:
SQL> update test set field3 = sysdate;
3 rows updated.
SQL> commit;
Commit complete.
SQL> select * from test;
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
1 Hello 15.02.2006 23:29:00
2 World 15.02.2006 23:29:00
3 15.02.2006 23:29:00
Code:
SQL> delete from test where field1 = 2;
1 row deleted.
SQL> commit;
Commit complete.
SQL> insert into test values (4, 'Hinzu', SYSDATE);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test;
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
1 Hello 15.02.2006 23:29:00
3 15.02.2006 23:29:00
4 Hinzu 15.02.2006 23:30:44
Wie wärs denn jetzt mit einer Liste der Änderungen ? ;-)
Code:
SELECT *
FROM (
( SELECT * FROM TEST
UNION
SELECT * FROM TEST AS OF TIMESTAMP TO_DATE('15.02.2006 23:30:00', 'DD.MM.YYYY HH24:MI:SS')
)
MINUS
(
SELECT * FROM TEST
INTERSECT
SELECT * FROM TEST AS OF TIMESTAMP TO_DATE('15.02.2006 23:30:00', 'DD.MM.YYYY HH24:MI:SS')
)
);
FIELD1 FIELD2 FIELD3
---------- ---------- -------------------
2 World 15.02.2006 23:29:00
4 Hinzu 15.02.2006 23:30:44
Nunja, das war wie immer nur ein kleiner Teil der Möglichkeiten. Oracle hat das ganze Spiel natürlich wieder "übertrieben" und ermöglicht nicht nur ein Flashback Table sondern gleich ein Flashback Database *g*.
Das wirklich einzige Problem an der Sache ist: Man darf sich nie drauf verlassen wie lange etwas vorgehalten wird. Wie gesagt liegt das an der Größe der Area und an der auftretenden Last. Je mehr gearbeitet wird, dest mehr Daten fallen an und desto schneller sind die 2GB ( bei mir) voll und alte Sachen fliegen raus.