|
![]() |
|
![]() |
|
|
szukaj w serwisie
![]() |
![]() |
|
![]() |
|
||||||||||
|
||||||||||||||
|
![]() |
Podróż w czasie, czyli Oracle FlashbackPaweł Barut Baza danych Oracle od wersji 9i udostępnia niezwykły mechanizm do podróży w czasie. Mechanizm ten, nazwany Flashback, umożliwia odczyt danych w wersji, jaka była w przeszłości. Czy nie zdarzyło się wam uruchomić proces modyfikacji danych, zatwierdzić zmiany i zastanawiać się co tak naprawdę zostało zmienione? Jakie dane były przed wykonaniem modyfikacji? W odpowiedzi na te pytanie pomoże właśnie mechanizm Flashback Query. Zaczynamy, czyli konfiguracja bazy danychMechanizm Oracle Flashback działa prawidłowo przy włączonym mechanizmie automatycznego zarządzania segmentem UNDO (Automatic Undo Management, parametr UNDO_MANAGEMENT=AUTO). Przy tradycyjnych segmentach wycofania użycie Flashback też jest możliwe, ale w praktyce ogranicza się do cofnięcia się do danych sprzed kilku minut. Następnie należy zadbać, aby dane z segmentów wycofania były przechowywane przez odpowiednio długi czas. W tym celu ustawiamy parametr bazy danych UNDO_RETENTION na odpowiednio dużą wartość, np. 43200 sekund, czyli 12 godzin. Należy pamiętać, że ustawienie dużej wartości może wymagać odpowiednio większej przestrzeni wycofań (UNDO TABLESPACE). Wielkość potrzebnej przestrzeni jest zależna od intensywności zmian w bazie danych, i należy ją określić na podstawie empirycznie zmierzonego współczynnika:
gdzie za p_start i p_stop należy podstawić okres największej intensywności pracy bazy danych. Wtedy minimalną wielkość przestrzeni UNDO można wyliczyć ze wzoru:
Margines błędu musi być na tyle duży, aby w przypadku niespodziewanego wzrostu intensywności generacji informacji wycofań, nie nastąpiło przepełnienie przestrzeni UNDO. Potrzebne uprawnieniaJeśli nie jesteś właścicielem tabeli, na której wykonywana będzie operacja odczytu danych historycznych, to musisz otrzymać od administratora bazy przywilej FLASHBACK dla danej tabeli. Możliwe jest również otrzymanie prawa do wykonania operacji Flashback na wszystkich tabelach bazy, czyli przywilej FLASHBACK ANY TABLE. Jeśli dodatkowo zamierzasz korzystać z pakietu DBMS_FLASHBACK,
to musisz uzyskać prawo do wykonania funkcji z tego pakietu. Pakiet ten
znajduje się DBMS_FLASHBACKPodstawowym sposobem korzystania z mechanizmu Flashback Query jest przełączenie sesji w tryb Flashback. Przełączenia trybu sesji dokonuje się korzystając z procedur zawartych w pakiecie DBMS_FLASHBACK:
Procedura enable_at_time w rzeczywistości dokonuje przemapowania podanego czasu na numer zmiany SCN i wykonanie enable_at_system_change_number. Mapowanie czasu na SCN można odczytać z tabeli systemowej SMON_SCN_TIME:
Mapowanie jest wykonywane z dokładnością do 5 minut, więc podanie czasu 23:23 i 23:26 powoduje mapowanie do tego samego numeru SCN. Jeżeli wiemy, że zmiana nastąpiła o 23:24, a następnie o 23:26 dane zostały ponownie zmienione, to używając procedury enable_at_time, nie będziemy w stanie cofnąć się do godziny 23:25. W takim przypadku należy poeksperymentować z różnymi numerami SCN z przedziału 8114349 - 8115568. Dlatego, o ile to możliwe, należy korzystać bezpośrednio z numeru SCN i procedury enable_at_system_change_number, a mapowania czasu na numer SCN wykonać samemu na podstawie zawartości tabeli SMON_SCN_TIME. Procedura enable_at_time jest za to przydatna do oszacowania, kiedy nastąpiła zmiana, która jest dla nas interesująca. Włączenie trybu Flashback przy użyciu pakietu DBMS_FLASHBACK powoduje, że niemożliwe jest wykonanie jakiejkolwiek operacji modyfikującej zawartość danych w bazie. Niemożliwe jest także wykonanie jakiejkolwiek operacji DDL. Zobaczmy jak to działa w praktyce. Na początek zapiszmy aktualny czas i SCN:
Utwórzmy tabelę testową:
i wyzwalacz zapisujący czas utworzenia i ostatniej zmiany:
Wstawmy kilka wierszy to tej tabeli:
Zapiszmy teraz aktualną wartość SCN (oznaczmy ją jako SCN01):
Zmieniamy kilka wierszy, np.:
Po wykonaniu tej operacji zupełnie nie wiemy, co było początkowo wstawione do tabeli. Sprawdzamy, co zawiera tabela:
Odtwórzmy stan tabeli przed operacją update. Włączamy tryb Flashback podając SCN przed operacją wstawienia danych:
Sprawdzamy, co zawiera tabela:
Jak widać, mamy zawartość tabeli sprzed wykonania operacji Update. Spróbujmy zatem wykonać kopię odtworzonych danych:
Niestety operacje zmieniające dane, jak i operacje DDL nie są możliwe, gdy baza pracuje w trybie Flashback. Wyłączamy zatem tryb Flashback:
I tabela powraca do aktualnego stanu:
Powstaje zatem pytanie: Jak skorzystać z trybu Flashback do odzyskania danych, skoro nie można ich nigdzie skopiować? Przecież nie sposób przepisać wszystkich danych na kartce papieru i potem "wklepać" z powrotem do bazy danych! Jest na to sposób: kursor, który jest otwarty podczas aktywnego trybu Flashback, pozostanie w trybie Flashback nawet po wyłączeniu trybu Flashback dla sesji. Tak więc teraz już będzie prosto - utworzymy najpierw tabelę, do której skopiujemy dane:
i wykonamy kopiowanie:
Teraz możemy już w jednym zapytaniu porównać dane:
Wygląda to skomplikowanie? Można taki sam efekt osiągnąć prościej. SELECT AS OF TIMESTAMP/SCNW poprzednim przykładzie operacja wykonania kopii utraconych danych i porównania z danymi aktualnymi wymagała wykonania kilku operacji. Ten sam efekt można uzyskać wykonując jedno zapytanie. Składnia instrukcji SELECT w Oracle9i została rozszerzona o klauzulę AS OF [TIMESTAMP|SCN]. Podając w klauzuli FROM tabelę, można dla niej określić moment czasu (lub numer zmiany SCN) wg. którego będą wybierane dane. Tak więc porównanie danych aktualnych z danymi sprzed zmiany można zrealizować jednym zapytaniem:
Jeśli natomiast chcielibyśmy wykonać kopię tabeli z poprzednimi danymi, to wykonujemy:
Przypuśćmy, że ktoś usunął wszystkie dane z tabeli i chcemy je odtworzyć. W tym celu należy najpierw odnaleźć dokładny SCN lub czas, dla którego dane jeszcze występują. Spróbujmy to zasymulować:
Usuńmy wszystkie dane:
Usuwanie musimy wykonać poprzez operację DELETE, gdyż TRUNCATE TABLE powoduje, że nie jest generowana informacja o sposobie wycofania instrukcji (UNDO). Jeśli odszukamy właściwy SCN, to operacja jest niezwykle prosta:
Tego nie da się wykonać jedną instrukcją przy użyciu pakietu dbms_flashback! Eksport też potrafiWyobraźmy sobie wyjątkowo niekorzystny zbieg okoliczności. Z bazy usunięte zostały pomyłkowo istotne dane, jednocześnie bieżące terminowe prace nie pozwalają ci na przeprowadzenie "standardowej" procedury odzyskiwania danych z backupu. Na dodatek parametr UNDO_RETENTION ma małą wartość, i za chwilę wszelkie ślady po nieszczęśliwie skasowanych danych bezpowrotnie znikną. Nie mamy także miejsca na dysku, aby szybko zwiększyć rozmiar przestrzeni UNDO, co umożliwiłoby zwiększenie UNDO_RETENTION i dało nam nieco więcej czasu na rozwiązanie problemu! Czy jest to sytuacja bez wyjścia? Nie. Skuteczną metodą odzyskania skasowanych danych w takim przypadku jest skorzystanie z zaawansowanych opcji eksportu dostępnych w bazie 9i. Eksport danych w tej wersji bazy poprzez rozbudowę o nowe parametry FLASHBACK_SCN oraz FLASHBACK_TIME ma możliwość użycia mechanizmu Oracle Flashback. Wykorzystując te parametry określić możemy numer zmiany, lub czas według którego będą eksportowane dane. Pamiętajmy, że czas podawany w parametrze FLASHBACK_TIME musi mieć format YYYY-MM-DD HH24:MI:SS. Aby operacja eksportu danych "archiwalnych" zakończyła się sukcesem, dodatkowo muszą być spełnione następujące warunki:
Czy SYS naprawdę nie może?Sporym zaskoczeniem dla wszystkich, którzy próbowaliby powyższe przykłady wykonać jako użytkownik SYS, będzie pojawienie się błędu podczas wykonywania procedury dbms_flashback.enable_at_system_change_number:
Tak samo dotyczy procedury dbms_flashback.enable_at_time. To żałosne! Wszak SYS powinien potrafić wszystko. Na przykład podejrzeć, jakie obiekty usunął praktykant, któremu ktoś nieroztropnie zdradził ważne hasła. A tu taka niespodzianka! Niestety, jest to jedno z poważnych ograniczeń opisywanej funkcjonalności. Jedynym wyjściem z zaistniałej sytuacji jest znalezienie rozwiązania alternatywnego. Użytkownik SYS co prawda nie może włączyć trybu Flashback przy użyciu pakietu dbms_flashback, ale zawsze pozostaje możliwość użycia zapytania SELECT AS OF SCN|TIMESTAMP. Tak więc teraz zadanie jest już banalne:
Zastosowanie odczytu z tabeli obj$ zamiast widoku np. DBA_OBJECTS jest związane z wydajnością. Ponieważ działanie mechanizmu Flashback jest oparte na odtwarzaniu stanu tabeli na podstawie segmentów wycofania, to operacja ta jest dość czasochłonna. Szczególnie negatywnie objawia się to we wszelkich złączeniach większej liczby tabel, lub przy odczycie ze skomplikowanych widoków. Cierpliwym polecam wypróbowanie wersji korzystającej z widoku DBA_OBJECTS:
Naprawdę, powyższe zapytanie może trwać wiele minut, nawet w przypadku, gdy nie było żadnych zmian w liście obiektów. Do czego jest to przydatne?
Często zdarza się, że mamy do przetestowania skomplikowany proces, operujący na tablicach sporych rozmiarów, który modyfikuje małą część danych. Jednakże w wyniku zaistnienia złych warunków w klauzuli WHERE dla operacji UPDATE, może dojść do modyfikacji nie tych danych co trzeba. Dzięki Oracle Flashback możemy łatwo sprawdzić, jakie zmiany zaszły w interesujących nas tabelach. Zapytanie typu:
zwraca uporządkowaną listę zmian, pomiędzy czasem aktualnym, a określonym czasem z przeszłości:
Dzięki temu możemy tak konstruować przypadki testowe, aby bez względu na stan początkowy bazy danych, dokonać wstawienia wierszy, na których ma zostać przeprowadzony test. Następnie wykonać test, i zapytaniem o konstrukcji przedstawionej powyżej zweryfikować, czy proces operował na właściwych danych, a także czy nie zostało zmienione nic ponadto. Całość można zawrzeć w skrypcie, którego wynikiem będzie zapisanie wyniku zapytania do pliku (spool). Mechaniczne porównanie zawartości pliku z przygotowanym wcześniej wzorcem zapewni automatyzację testów regresyjnych. OgraniczeniaPodstawowe ograniczenie w stosowaniu mechanizmu Flashback, to czas - informacja UNDO nie jest przechowywana w nieskończoność. Administrator systemu musi zadeklarować oczekiwany czas przechowywania danych w segmentach UNDO. Drugim niezwykle ważnym ograniczeniem jest fakt, że Oracle Flashback wykorzystuje aktualny stan słownika danych. Dlatego zmiana struktury tabeli, np. dodanie kolumny powoduje generowanie błędu "ORA-01466: nie można odczytać danych - definicja tabeli jest zmieniona." Dlatego nie można tego mechanizmu zastosować, jeśli próbujemy cofnąć się do stanu tabeli sprzed usunięcia/dodania kolumny. Podsumowanie
Co dalej?W Oracle10g mechanizm Flashback został znacząco rozbudowany. Zostały dodane nowe instrukcje, np. FLASHBACK TABLE, które ułatwiają wykonanie pewnych standardowych operacji, takich jak przywrócenie tabeli do stanu z określonego czasu. Została także wprowadzona możliwość przywrócenia tabeli, usuniętej za pomocą drop table, poprzez zastosowanie mechanizmu podobnego do kosza w systemach okienkowych. Wprowadzona została także możliwość cofnięcia całej bazy przy użyciu jednej instrukcji. W celu zapoznania się ze szczegółami, zachęcam do zapoznania się z dokumentacją Oracle 10g.
|
|||||||||||||||||||||||||||||||
|
![]() |
Copyright © 2004-2010 by PLOUG | |||||||||||||||||||||||||||||||