czwartek, 26 kwietnia 2012

RMAN - Duplikacja bazy danych

Używanie duplikacji

Duplikacja jest kopią bazy z jednoczesną zmianą unikalnego identyfikatora bazy DBID. Możesz odtworzyć bazę danych na podstawie pliku backupu oraz archivelogów. Możliwa jest również duplikacja do punktu w czasie, dzięki czemu istnieje możliwość porównania aktualnego stanu obiektów (z bazy produkcyjnej) z ich stanem nawet w odległej przeszłości, gdy nie można już wykorzystać danych UNDO.  Taka duplikacja do punktu w czasie działa podobnie jak odtwarzanie do punktu w czasie, z tym że na innej bazie docelowej. Duplikację możesz zastosować jako prostą metodę kopiowania bazy w celach testowych. Na takiej kopii możesz np. sprawdzić upgrady, patche, modyfikacje przed wdrożeniem zmian na bazie produkcyjnej.     Bazę możesz zduplikować na tym samym hoście, lub po skopiowaniu niezbędnych plików na innym. Przedstawiony tutaj rodzaj duplikacji to w rzeczywistości odtworzenie bazy w innym miejscu na podstawie backupu.


Duplikacja 1-1

Metod na skopiowanie bazy jest kilka, tutaj prezentuję moim zdaniem najwygodniejszą tj. z wykorzystaniem katalogu. Potrzebujemy trzech połączeń. Do bazy źródłowej, do katalogu (który spełnia rolę repozytorium danych o backupach), oraz oczywiście do bazy docelowej. Ponadto z poziomu bazy docelowej musi być dostęp do plików backupów , oraz archivelogów bazy źródłowej. Jeśli duplifikujemy bazę na inny host, zapewnienie dostępu do backupów i archivelogów sprowadza się do ich skopiowania z serwera źródłowego do FRA na serwerze docelowym.
Całą operację przeprowadzamy z poziomu hosta docelowego, ponieważ baza docelowa przed duplikacją musi zostać uruchomiona do trybu NOMOUNT, nie będzie do niej dostepu poprzez Listener. Sama duplikacja po uprzednim przygotowaniu odpowiednich informacji i podłączeniu sprowadza się do wydania komendy „duplicate target database to nazwa_bazy_docelowej”. Ta komenda mimo że sprowadza się do paru słów, wywołuje w rzeczywistości skomplikowany mechanizm. Informacje które trzeba podać RMANowi przed duplikacją to nowa nazwa plików danych , oraz ewentualnie moment do którego odtwarzamy  jeśli wykonujemy duplikację do punktu w czasie. Podać nowe nazwy plików można na dwa sposoby – albo pojedynczo dla każdego pliku danych, albo podając schemat zamiany nazw. W pierwszej kolejności wykorzystamy ten pierwszy sposób, mimo że jest bardziej czasochłonny, ale też łatwiejszy w zrozumieniu. Następnie powtórzymy operację z wykorzystaniem schematu zamiany nazw i ścieżek.

Przygotowania

Przede wszystkim potrzebujemy bazy , do której zostanie zduplifikowana nasza baza źródłowa. Uruchamiamy więc narzędzie DBCA i tworzymy bazę danych. Tworzenie bazy danych tym narzędziem jest na tyle proste, że nie będziemy się tym szczegółowo zajmować. Generalnie jest to „next, next, next, next , finish” :) Samo tworzenie bazy może chwilę potrwać.



Logujemy się do nowe bazy jako sys. Jest nam to potrzebne, bo przy duplikacji będzie trzeba podać nowe nazwy plików. Stosujemy najpierw tą pierwszą metodę. Gdybyśmy w ogóle nie zadbali o zmianę nazw plików danych, w czasie duplikacji dostalibyśmy komunikat o tym że istnieją już pliki o takiej nazwie , a sama duplikacja zostałaby przerwana. Określamy więc gdzie leżą nasze pliki danych i pliki tymczasowe.




Źródłowa baza danych musi pracować w trybie ARCHIVELOG, poza tym potrzebujemy przynajmniej jednego pełnego backupu który będzie podstawą do duplikacji. Na tym etapie powinieneś już wiedzieć jak włączyć tryb archivelog, jednak gdybyś zapomniał to przypominam :).
W pierwszej kolejności należy bazę położyć ( shutdown immediate ), następnie włączyć do trybu mount (startup mount), włączyć tryb archivelog (alter database archivelog ) i otworzyć (alter database open).
Po stworzeniu nowej bazy możesz natknąć się na niespodziewaną przeszkodę. DBCA po stworzeniu bazy ustawia nam w zmiennej systemowej ORACLE_SID sid nowej bazy danych. Konsekwencją tego jest fakt, że jeśli logujesz się do bazy sqlplusem bez podania sid'a (a tak się logujemy do wyłączonej ) to połączysz się do tej której SID jest ustawiony w zmiennej ORACLE_SID. Analogicznie przy podłączeniu za pomocą RMANa. Jeśli chcesz zmienić wartość tej zmiennej, w linuksie robisz to wydając komendę:

export ORACLE_SID=xxx

a w Windowsie :

set ORACLE_SID=xxx

gdzie xxx to sid bazy. Wielkość liter ma znaczenie.




Po ustawieniu ORACLE_SID na SID bazy źródłowej, wykonujemy jej pełną kopię zapasową (jeśli nie zrobiliśmy jej wcześniej). W przypadku gdybyś chciał zrobić duplikację pomiędzy różnymi hostami a wykonywałeś już jakieś backupy , to i tak warto wykonać ten jeden pełen backup. Dzięki temu będzie mniej niezbędnych plików do skopiowania, zwłaszcza archivelogów.





Jeśli nie masz jeszcze ustawionej opcji CATALOG RMANa, to wykonaj następujące czynności:

- Stwórz użytkownika i nadaj mu role: connect,resource, recovery_catalog_owner. Użytkownika stwórz na dowolnej bazie, byleby nie na tej bazie która będzie bazą docelową. Ważne byś do tej bazy mógł się później podłączyć z poziomu hosta na którym znajdzie się baza docelowa.




- Z poziomu RMANa podłącz się do bazy źródłowej oraz do schematu przed chwilą stworzonego użytkownika. Wydaj polecenia: „create catalog” oraz „register database”.
(więcej na ten temat znajdziesz w artykule „RMAN – opcja CATALOG” )




- Doprowadź teraz do tego by otwarte były bazy źródłowa oraz ta w której znajduje się katalog (u mnie to ta sama baza), natomiast baza docelowa była uruchomiona w trybie NOMOUNT. Musi być akurat NOMOUNT ponieważ podczas duplikacji będą zachodziły zmiany na jej pliku kontrolnym.




- Dalszą część czynności wykonujemy z poziomu hosta na którym znajduje się baza docelowa. Zadbaj teraz o to , by w zmiennej systemowej ORACLE_SID znalazł się sid bazy docelowej. Podłącz się teraz do bazy źródłowej , katalogu i bazy docelowej z poziomu rmana w taki sposób by:
Po connect target  znajdowała się linijka połączenia do bazy źródłowej.
Po connect catalog znalazła się linijka połączenia do schematu w którym założyłeś katalog.
Po connect auxilary  był slash (/) który spowoduje podłączenie do tej bazy której sid mamy w zmiennej systemowej ORACLE_SID.





Duplikacja

Przechodzimy do właściwej duplikacji. Wszystkie polecenia „set newname...” oraz ewentualnie
„set until time...” muszą znaleźć się w tym samym bloku run co polecenie „duplicate target database to ….”. Te polecenia obowiązują tylko w bloku RUN , więc nie możesz ich wykonywać niezależnie. Przy użyciu polecenia „set newname” nadajemy nazwy plikom danych które mają zostać utworzone w docelowej bazie danych wraz ze ścieżkami. Te numerki to numery plików danych w bazie źródłowej które wyświetlaliśmy na samym początku.







Komenda „duplicate target database to nowa” powoduje odtworzenie bazy źródłowej w bazie docelowej której sid podajemy (tutaj jest to „nowa”). Pamiętamy by ta komenda znalazła się w tym samym bloku run co wszystkie „set newname”. Do docelowej bazy danych zostanie odtworzony ostatni pełen backup bazy źródłowej, oraz wszystkie archivelogi jakie są dostępne.
Musimy teraz poczekać , proces duplikacji trwa przynajmniej tyle czasu ile pełne odtworzenie bazy źródłowej. Baza źródłowa po zakończeniu duplikacji zostanie otwarta.



Jeśli zechcemy odświeżyć naszą kopię bazy danych, wystarczy ponownie wykonać duplikację, tym razem jednak nie tworzymy nowej bazy :).

Troubleshot podczas duplikacji

Jeśli dopiero co włączyliśmy tryb archivelog w bazie źródłowej , może pojawić nam się taki bład:



Wynika on z tego, że nie zostały jeszcze utworzone żadne archivelogi. Wystarczy więc przełączyć pliki dziennika powtórzeń (w bazie źródłowej). Komunikat jest trochę mylący, chodzi o bazę źródłową – czyli tą którą kopiujemy a nie docelową – czyli tą do której kopiujemy. W nomenklaturze RMANa „baza docelowa” to ta do której jesteśmy podłączeni z użyciem klauzuli „target”. Przełączamy więc pliki dziennika powtórzeń:


a następnie powtarzamy próbe duplikacji.


Duplikacja do punktu w czasie

Podobnie jak możemy odtworzyć bazę do punktu w czasie , tak możemy również duplikować bazę do punktu w czasie. Ostatecznie duplikacja do punktu w czasie jest odtwarzaniem do punktu w czasie , tyle że innym miejscu. Wszystkie dotychczasowe kroki wykonujemy analogicznie, natomiast w samym bloku w którym wywołujemy duplikację dodajemy jeszcze komendę „set until time” korzystając ze znanej z SQLa funkcji to_date. 




Schemat zmiany nazw plików danych i ścieżek do nich

Teraz czas na obiecaną krótszą wersję zmiany nazw plików przy duplikacji. Zamiast podawać nowe nazwy dla wszystkich plików danych osobno , możemy RMANowi wskazać schemat według którego ma je pozmieniać za nas. Zasady i procedury opisane wcześniej pozostają zasadniczo bez zmian, modyfikacja dotyczy tylko poleceń „set newname” już przy samej duplikacji. Zamiast set newname for datafile / tempfile piszemy tym razem set newname for database. Podajemy ścieżkę do katalogu w którym mają się znaleźć pliki danych oraz znacznik „%b” który oznacza starą nazwę pliku. Poniższa sekwencja spowoduje że powstaną pliki danych w katalogu którego ścieżkę podajemy, jednak będą nazywały się tak samo jak pliki danych w bazie źródłowej.



Możliwa jest też duplikacja do punktu w czasie z użyciem tej wygodniejszej formy zmiany nazw:







środa, 25 kwietnia 2012

RMAN - opcja CATALOG




Co to jest CATALOG i jakie korzyści przynosi?

Opcja catalog w skrócie, polega na tym że repozytorium backupów poza plikiem kontrolnym znajduje się również w specjalnym schemacie innej bazy danych. Co nam to daje?

  • Dane o backupach są przechowywane również poza plikiem kontrolnym , więc w przypadku jego utraty jesteśmy w stanie odtwarzać kopie zapasowe.
  • Jesteśmy w stanie odtwarzać kopie zapasowe już w trybie NOMOUNT, co normalnie nie byłoby możliwe.
  • Możemy posiadać gotowe użytkowe skrypty i współdzielić je między bazami danych.


W teorii jak stworzyć CATALOG?
  • Musimy w innej bazie danych stworzyć użytkownika i nadać mu poza zwykle przyznawanymi rolami CONNECT, RESOURCE również rolę RECOVERY_CATALOG_OWNER.
  • Stworzyć w schemacie tego użytkownika specjalną strukturę tabel do przechowywania danych o backupach i skryptach
  • Zarejestrować bazę, tj dodać odpowiednie wpisy w stworzonym wyżej schemacie.
  • Zsynchronizować repozytorium pliku kontrolnego i CATALOG (co dzieje się automatycznie przy rejestracji bazy).

W jednym raz stworzonym CATALOGu możemy zarejestrować wiele baz.
A w praktyce?

Tworzenie użytkownika i nadawanie mu odpowiednich uprawnień

W pierwszej kolejności , w bazie w której ma się znaleźć CATALOG tworzymy użytkownika. Nadajemy mu trzy role :

  • connect
  • resource
  • recovery_catalog_owner




Tutaj sworzyłem użytkownika o nazwie rman z hasłem rman. Oczywiście Twój użytkownik może nazywać się inaczej.
Będziemy potrzebowali podłączyć się do bazy w której znajduje się nasz CATALOG z poziomu RMANa więc wszelkie dane połączeniowe musimy dodać do pliku tnsnames.ora by nazwa bazy była rozpoznawana. Moja baza katalogowa będzie rozpoznawana pod nazwą KATALOG.


Następnie musimy uruchomić RMANa i podłączyć się do naszej bazy, oraz do schematu bazy w której znajdować się będzie nasze dodatkowe repozytorium tj. do schematu który przed chwilą stworzyliśmy. Zauważ że podczas połączenia wskazujemy do której bazy łączymy się w jakim celu. Łącząc się z użyciem słówka TARGET wskazujemy RMANowi że ta baza będzie backupowana, odtwarzana, rejestrowana w CATALOGu lub duplifikowana. W każdym razie jest to nasza podstawowa baza na której chcemy wykonywać działania. Do bazy w której znajduje się nasze nowe repozytorium łączymy się z użyciem klauzuli CATALOG. Dzięki temu kiedy napiszemy „register database” RMAN będzie wiedział która baza jest bazą dla której tworzymy katalog, a która spełnia rolę repozytorium.
Po właściwym podłączeniu się do obu baz, tworzymy wszystkie niezbędne tabele w których będą przechowywane informacje o backupach. Robimy to klauzulą „CREATE CATALOG”. RMAN wie w którym schemacie ma te tabele utworzyć na podstawie informacji przekazanych mu podczas połączenia. Tabele stworzy w schemacie do którego podłączamy się z użyciem klauzuli CONNECT CATALOG. Takie tworzenie tabel w schemacie wykonujemy tylko raz, niezależnie od tego jak wiele baz ma korzystać z tego repozytorium. W raz utworzonym katalogu możemy zarejestrować wiele baz.
Kolejną czynnością jest rejestracja bazy w katalogu. Robimy to klauzulą REGISTER DATABASE. Rman doda do tabel w schemacie katalogowym wpisy o bazie do której jesteśmy podłączeni jako do bazy targetowej. Gdybyś zechciał zarejestrować więcej baz, rozłącz się i podłącz do kolejnej bazy z użyciem CONNECT TARGET oraz do bazy katalogowej. Nie będzie już konieczne ponowne tworzenie struktur poleceniem „CREATE CATALOG” , jedynie rejestrujemy kolejną bazę poleceniem „REGISTER DATABASE”.

Wujek Dobra Rada: Catalog z technicznego punktu widzenia możesz utworzyć również w bazie dla której tworzysz katalog. Z praktycznego punktu widzenia, jest to bez sensu :) Pomyśl – gdyby nastąpiła jakaś awaria tej bazy i i tak nie moglibyśmy jej podnieść, to do takiego katalogu byśmy się nie podłączyli :) Żeby sworzyć sobie taki katalog nie potrzebujesz żadnej komercyjnej licencji Oracle. Wystarczy Ci bazka Express Edition postawiona na komputerze choćby z Pentium III :). Przecież to tylko kilka tabel z wpisami znajdujących się w schemacie do którego mamy się podłączać przez sieć. That's all!





Zauważ że podczas rejestracji bazy w katalogu, następuje automatyczna synchronizacja repozytorium. Oznacza to że informacje o wszystkich backupach są kopiowane z Twojego pliku kontrolnego do schematu katalogowego. Zawsze możesz je ponownie zsynchronizować gdy będzie to konieczne (o tym dalej) poleceniem „resync catalog”.
Wykorzystajmy teraz możliwości takiego katalogu.




Odtwarzanie bazy w trybie nomount

W sytuacji gdybyśmy spotkali się z awarią bazy taką, że baza nie podnosi się wyżej niż do trybu NOMOUNT, nie mamy dostępu do informacji o backupach zawartych w pliku kontrolnym. Oczywiście zawsze pozostaje nam autobackup pliku kontrolnego lub zduplifikowany plik kontrolny (jeśli o to zadbaliśmy).
W tym przypadku wykonuję otwarzanie bazy w trybie nomount. Oczywiście aby to się udało, muszę być podłączony do bazy targetowej oraz katalogu.





Sam recover bazy wykonać musimy już w trybie mount. Po zakończeniu odtwarzania plików (restore) przechodzimy więc do trybu mount i wykonujemy recover.



Synchronizacja katalogu

Gdyby z różnych przyczyn (problemy z siecią, problemy sprzętowe serwera z katalogiem etc) nie było możliwe podłączenie się do bazy katalogowej przez jakiś czas, wszystkie czynności wykonujemy podłączeni tylko do bazy targetowej. Informacje o backupach znajdą się wtedy tylko w pliku kontrolnym.



Kiedy połączenie do katalogu znowu będzie możliwe, łączymy się do bazy targetowej i do katalogu i synchronizujemy repozytoria poleceniem „resync catalog”.



Po tej operacji nastąpi skopiowanie do katalogu informacji o backupach które zostały wykonane bez połączenia z nim.

Wyrejestrowanie bazy z katalogu

W każdej chwili możemy zrezygnować z opcji catalog i wyrejestrować bazę. Aby to zrobić, łączymy się do bazy targetowej i do katalogu, a następnie wykonujemy polecenie „unregister database”.




Kasowanie katalogu

Katalog możemy również skasować wraz z repozytoriami wszystkich baz w nim zarejestrowanych.




Skrypty

Posiadając katalog, możemy również stworzyć skrypty narzędziowe. Bez katalogu możliwość przechowywania skryptów ograniczała się do zapisywania ich w plikach. Mając katalog, możemy tworzyć skrypty i przechowywać je w nim. Dzięki temu wszystkie skrypty znajdują się w jednym miejscu i są dostępne z każdego miejsca z którego jesteśmy w stanie podłączyć się do katalogu.
Skrypty mogą być globalne albo lokalne. Globalne są dostępne dla wszystkich baz zarejestrowanych w katalogu, lokalne tylko dla jednej bazy.


Generalnie skrypty tworzymy poleceniem create [ global ] script. Na powyższej ilustracji stworzyłem skrypt do odtwarzania tablespace uzyszkodnicy. Sekwencję komend które wpisywałbym pojedynczo lub w bloku run , zamknąłem w skrypcie. Jest to skrypt lokalny.
Tylko w jednej bazie posiadam tablespace o takiej nazwie , dlatego stworzyłem skrypt dostępny tylko dla tej bazy.

Poniżej tworzę skrypt uniwersalny do odtwarzania całej bazy. Nie posiada on elementów różnych dla różnych baz, więc mogę go wykorzystywać do odwarzania dowolnej bazy. Zauważ że doszła nam klauzula GLOBAL. To sprawia, że skrypt będzie dostępny dla wszystkich baz zarejestrowanych w katalogu.



Mogę też stworzyć skrypt w oparciu o plik:



Zawartość pliku zostanie przeczytana i zaposana pon nazwą „przyrostowy”.

Aby uruchomić skrypt korzystam z komendy „execute”. Wywoływanie skryptów zawsze musi być objęte blokiem „run”.




Przy uruchomieniu w ten sposób RMAN będzie szukał skryptu lokalnego, choćby istniały dwa skrypty o takiej nazwie – lokalny i globalny. Gdybyśmy chcieli wywołać skrypt globalny :



Zawartość skryptów możemy również wypisać na ekran przy użyciu polecenia print. Jeśli mielibyśmy dwa skrypty o tej samej nazwie (jeden globalny a drugi lokalny), a chcielibyśmy uruchomić ten globalny posługujemy się dodatkowo klauzulą GLOBAL:




Możemy też skrypty wydrukować do pliku tekstowego:


Jeśli chcemy sprawdzić jakie mamy skrypty dostępne możemy posłużyć się dwoma klauzulami:

list script names
lub
list global script names







W pierwszym wypadku wyświetlone zostaną nazwy wszystkich skryptów, w drugim tylko globalnych.


Kasować skrypty możemy przy użyciu komendy delete script. Tak jak do tej pory, gdybyśmy mieli dwa skrypty (lokalny i globalny ) o tej samej nazwie, RMAN domyślnie skasuje lokalny. Możemy więc stosować też klauzulę GLOBAL:






Skrypty możemy ulepszać i podmieniać w katalogu poleceniem replace:


czwartek, 12 kwietnia 2012

Flashback w Oracle


Czym są dane UNDO

Czy zadałeś sobie kiedyś pytanie, co się właściwie dzieje kiedy wywołujesz rollback? Albo dlaczego przed commitem zmiany widzisz tylko Ty, a nie widzą ich inni użytkownicy? Te same dane muszą istnieć w dwóch postaciach : tej zmienionej i tej oryginalnej sprzed zmiany. Takie oryginalne dane (sprzed zmany) są nam potrzebne co najmniej w kilku sytuacjach:

  • Kiedy wywołujesz rollback – dane oryginalne muszą zostać przywrócone.
  • Kiedy rozłączasz sesję bez zatwierdzenia zmian – dane oryginalne muszą zostać przywrócone.
  • Kiedy inni użytkownicy przeglądają dane które Ty właśnie zmieniasz a jeszcze nie zatwierdziłeś – muszą widzieć dane oryginalne.
  • Kiedy przywracasz stan obiektu np. tabelki do punktu w czasie – odczytany musi zostać stan tego obiektu we wskazanym czasie.


Jak to wszystko właściwie się odbywa? Za każdym razem kiedy wykonujesz jakiekolwiek operacje DML ( DELETE, UPDATE,INSERT, MERGE), oryginalny stan danych które zmieniasz zostaje zapisany jako dane UNDO. Dane UNDO są z kolei zapisywane w tablespace UNDO (który wcale nie musi się tak nazywać). W bazie może być kilka tablespace'ów przeznaczonych do przechowywania danych UNDO, jednak w aktualnym użyciu może być tylko jeden. W tabeli undo znajduje się więc postać danych sprzed zmiany z informacją co to za dane oraz z kiedy pochodzą.
Po zakończeniu transakcji dane pozostają w UNDO, dzięki czemu możemy korzystać z FLASHBACK i np. przywrócić tabelę do stanu z określonego czasu. Jak długo te dane znajdują się w tablespace UNDO? To zależy od ustawienia parametru UNDO_RETENTION , rozszerzalności tablespace'u oraz ustawień gwarancji. Tym wszystkim zajmiemy się nieco później.





Dane UNDO a REDO logi

Musisz pamiętać o tym, że dane UNDO a archivelogi to dwie zupełnie różne rzeczy i służą do różnych celów. Przede wszystkim , archivelogi są tworzone na podstawie plików dziennika powtórzeń – a więc w pewnym sensie zawierają historię zmian nie zaś dane. Archivelogi mogą być tworzone lub nie, w zależności od włączenia trybu ARCHIVELOG. Instancja nie mogłaby w zasadzie funkcjonować bez danych UNDO. Bez nich nie byłaby możliwa żadna operacja DML. Różny jest też cel stosowania danych UNDO i REDO logów. Archivelogi wykorzystywane są przede wszystkim do odtwarzania bazy danych. Są czytane , a następnie zmiany które są w nich zawarte są aplikowane na bazie danych po odtworzeniu fizycznym plików z backupu.


Korzyści z wykorzystania FLASHBACK


Dzięki odtwarzaniu FLASHBACK które opiera się o dane UNDO jesteśmy w stanie:

  • Odtwarzać pojedyncze obiekty – np. tabele , bez potrzeby odtwarzania całej bazy czy tablespace.
  • Odtwarzanie z użyciem FLASHBACK jest znacznie szybsze niż odtwarzanie z backupu
  • Nie musimy wyłączać instancji , ani offline'ować całego tablespace by odtworzyć obiekt.



Co z tego wszystkiego wynika – czyli praktyczne wykorzystanie przestrzeni UNDO



Flashback Query

Wykorzystując dane które znajdują się w przestrzeni UNDO, możemy spojrzeć na stan danych z określonego czasu. Może mi to być potrzebne do określenia czasu do którego trzeba odtworzyć tabelę po błędnych operacjach, lub po prostu do porównania stanów. Przykład :

  1. Sprawdzam wynagrodzenie pracownika o id 100 w tabelce employees znajdującej się w schemacie użytkownika hr.
  2. Widzę że jego aktualne wynagrodzenie wynosie 24000 , więc zmieniam je na 22000 i zatwierdzam zmiany. Dla pewności sprawdzam, zmiany zostały dokonane.





  1. Chciałbym teraz dowiedzieć się, jak te dane wyglądały kilka minut temu. Sprawdzam jak wyglądają teraz.
  2. Przy użyciu klauzuli „as of timestamp” jestem w stanie podejrzeć dane z określonego czasu. Aby ten punkt w czasie do którego się odnoszę podać, posługuję się funkcją to_timestamp. Wyświetlone dane pochodzą z przestrzeni UNDO.








Klauzula „as of timestamp” występuje zawsze po nazwie tabeli do której operacja się odnosi. Wszelkie warunki występują po niej.
Mogę teraz wykonać flashback tabeli do punktu w czasie , i w ten sposób odzyskać stan obiektu w danym momencie. Co jednak jeśli dokonanych zostało wiele zmian, a ja nie wiem dokładnie w którym momencie dane znajdowały się w pożądanym przeze mnie stanie? Mogę sprawdzić różne wersje tych danych na przestrzeni czasu z użyciem Flashback Versions Query.


Flashback Versions Query

Jak wspomniałem wcześniej, flashback versions query pozwoli Ci porównać różne wersje tych samych danych na przestrzeni czasu. Najlepiej jeśli pokażę to na przykładzie. Sprawdzam najpierw ile aktualnie wynosi wynagrodzenie pracownika o id 103.




Następnie dokonuję kilku zmian wynagrodzenia, zatwierdzając je. Zmiana pierwsza:


Zmiana druga:




Chcąc porównać te same dane na przestrzeni czasu muszę posłużyć się klauzulą „versions between timestamp” zaraz po nazwie tabeli i wskazać zakres czasu który mnie interesuje. Pierwsza wartość zawsze musi być mniejsza:




Wyświetliłem tutaj również pseudo kolumnę versions_starttime która informuje mnie kiedy ta zmiana została dokonana. Do dyspozycji mam również kolumny:

  • versions_endtime – czyli do kiedy ta wersja danych obowiązywała
  • versions_startscn – scn podczas dokonania zmiany
  • versions_endscn – ostatni scn w czasie obowiązywania tej wersji danych
  • versions_operation – jaką operacją dane zostały zmienione



FLASHBACK tabeli ( Przywracanie tabeli do punktu w czasie )


Kiedy już jestem w stanie określić do jakiego czasu chcę przywrócić obiekt, mogę posłużyć się FLASHBACKIEM do dokonania tej czynności. Nie muszę wyłączać instancji , ani tablespace'a. Dane przywracane są z przestrzeni UNDO.


Pierwsze co muszę wykonać to włączyć „row movement” dla tabeli którą będę przywracał. Robi się to tylko raz dla tabeli. Nie musimy tego robic przed każdym przywracaniem.




Następnie przywracamy tabelę , podając czas do którego chcemy przywrócić przy pomocy funkcji to_timestamp. Nie musi być to dokładnie czas powstania wersji , który możemy zobaczyć stosując zapytanie z „versions between”. Ważne by trafić czas w którym interesująca nas wersja obowiązywała. Ja przywróciłem tabelę do stanu przed wszystkimi zmianami, do wersji początkowej:



Jeszcze mała weryfikacja:




Oczywiście nie możemy cofać się dowolnie daleko w przeszłość. Warunkiem przywrócenia tabeli do danego punktu w czasie , jest istnienie danych z tego okresu w przestrzeni UNDO. Przy użyciu takiej metody nie przywrócimy jednak tabeli która została usunięta. Aby to zrobić musimy posłużyć się nieco inną metodą, mianowicie „Flashback before drop”


Flashback before drop (Przywracanie tabelki po skasowaniu)


Ta funkcjonalność dostępna jest dopiero od wersji 10g. Tak więc jeśli zdarzy Ci się skasować tabelkę w 9 albo starszej wersji , to niestety konieczne będzie odtwarzanie bazy do punktu w czasie. Jako administrator możesz oczywiście uniemożliwić przywracanie skasowanych tabel :

alter system set recyclebin=off scope=spfile;

Po przestawieniu tego parametru musisz zrestartować instancję, aby nowe ustawienia zostały uwzględnione. Oczywiście możesz go również przywrócić:


alter system set recyclebin=on scope=spfile;


Nie musisz go włączać jeśli wcześniej nie wyłączałeś, ponieważ parametr ten domyślnie jest włączony.


Przyjrzyjmy się bliżej jakie mamy możliwości. Najpierw kasujemy tabelę:




Możemy teraz zajrzeć do naszego śmietnika z perspektywy użytkownika kasującego obiekt:




Widzimy że znajduje się w śmietniku przed momentem skasowana tabelka. W słowniku user_recyclebin widzimy tylko obiekty skasowane przez nas. Administrator może przejrzeć wszystkie skasowane obiekty w słowniku dba_recyclebin:



Jeśli obiekt znajduje się w śmietniku , to można go przywrócić:




Gdybyśmy jednak po skasowaniu stworzyli nowy obiekt o takiej samej nazwie jak ten skasowany , lub po prostu chcieli odtworzyć obiekt z nową nazwą możemy dodać klauzulę „rename to”:





Możesz też w przypadku konkretnych obiektów skasować je trwale. Tak by nie można ich było przywrócić flashbackiem. Dodajemy wtedy klauzulę „purge” przy kasowaniu:





Obiekt jak widać nie jest tym razem widoczny w śmietniku i nie można go odtworzyć.
Jeśli chciałbyś trwale usunąć wcześniej zdropowany obiekt tj. skasować go ze śmietnika:




możesz posłużyć się klauzulą „purge table”:





Sposób działania przywracania po skasowaniu jest nieco inny niż w przypadku przywracania do punktu w czasie. W przypadku kasowania, obiekt nie trafia do przestrzeni UNDO. Po prostu miejsce które zajmował w swoim tablespace jest oznaczane jako „do zapisu”. Dane ze skasowanej tabeli tak naprawdę nadal istnieją. Miejsce w którym znajdowała się tabela zostaje nadpisane dopiero kiedy nie będzie już wolnej przestrzeni w tablespace, a sam tablespace nie będzie mógł się rozszerzyć. W praktyce oznacza to , że takie skasowane tabele będą przywracalne przez bardzo długi okres, niezależnie od ustawień UNDO_RETENTION i własności przestrzeni UNDO.

Czasem przywracanie pojedynczych obiektów niestety nie wystarczy, musimy przywrócić bazę do punktu w czasie...


FLASHBACK database (Przywracanie bazy do punktu w czasie przy użyciu FLASHBACK)

Pamiętaj że przywracanie bazy przy użyciu FLASHBACK to zupełnie inny mechanizm niż przywracanie bazy danych przy użyciu backupu i archivelogów. Tutaj co prawda również są wykorzystywane archivelogi, ale nie potrzebujesz przywracania plików z backupu. Dane przywracane są z tzw. FLASHBACK LOGÓW do stanu przed momentem do kŧórego przywracamy , a następnie zmiany do wskazanego przez nas momentu doczytywane są z archivelogów. Oczywiście alternatywnie można posłużyć się zwyczajnym przywracaniem do punktu w czasie, jednak jeśli mamy do wyboru odtwarzanie z backupu mającego tydzień , a później doczytywanie archivelogów albo zaczytanie flashback logów i doczytanie minimalnej ilości archivelogów, to porównianie szybkości przyniesie oczywiste efekty. Aby przywracanie bazy z użyciem flashback działało, musimy mieć włączony tryb ARCHIVELOG bazy. Włączamy go jeśli jeszcze tego nie zrobiliśmy:





Musimy teraz przeprowadzić konfigurację wstępną , niezbędną do przywracania bazy danych z flashbacku. Konfigurację przeprowadzamy będąc w trybie MOUNT EXCLUSIVE. Logi flashback będą znajdować się w FRA, będą cyklicznie nadpisywane. Musimy więc ustalić czas do jakiego ewentualnie będziemy się cofać. Nie jest to wartość sztywna, jedynie orientacyjna. Czas ten określamy poprzez parametr db_flashback_retention_target podając czas w minutach. Ustawiłem 1440 minut czyli dobę. Następną czynnością jest włączenie wytwarzania logów flashback instrukcją alter database flashback on; To czy baza wytwarza logi flashback czy nie , możemy zweryfikować sprawdzając parametr flashback_on ze słownika v$database. Możemy również wyłączyć wytwarzanie logów flashback instrukcją alter database flashback off (również w trybie mount exclusive).



Konfiguracja za nami, przeprowadźmy więc test. Ja zmienię jedną tylko tabelkę a następnie odtworzę całą bazę przy użyciu flashback , jednak to jest tylko w celach testowych – pamiętamy że możemy przywracać pojedyncze obiekty, nie ma potrzeby w takiej sytuacji odtwarzać całej bazy.
Zalogowałem się jako użytkownik HR i sprawdzam aktualny stan zarobków w firmie:




Dokonuję więc zmiany wynagrodzenia dla wszystkich pracowników:



Przywrócę bazę z użyciem FLASHBACK. Aby to zrobić, muszę być w trybie MOUNT EXCLUSIVE. Po takim odtwarzaniu muszę otworzyć bazę z RESETLOGS:




Sprawdzam po przywróceniu czy moje dane wróciły do pierwotnej postaci:



Jest ok. Teraz drogi czytelniku, spróbuj odtworzyć bazę danych do tego samego punktu przy użyciu metod „tradycyjnych” tj . Restore , recover i porównaj czasy wykonania :)
Mimo że na pozór ta metoda wydaje się być świetna, to pamiętaj że ma też swoje ograniczenia. Ponieważ logi flashback są cyklicznie nadpisywane, możliwość powrotu do punktu w czasie jest ściśle uzależniona od tego, czy logi zostały już podmienione czy nie. Mógłbyś chcieć mieć np. punkty do których zawsze możesz powrócić , nawet po długim czasie. Możesz po prostu przechowywać backupy i archivelogi potrzebne do odtworzenia do danego momentu, ale taką funkcję spełniają również Gwarantowane Punkty Przywracania.....



Gwarantowane Punkty Przywracania (Guaranteed Restore Point)

Przy użyciu tej funkcjonalności , możesz utworzyć punkt do którego będziesz mógł wrócić zawsze niezależnie od ustawień parametru db_flashback_retention_target. Działa to podobnie jak „save” w grach. Baza zapisuje pod wyznaczoną przez Ciebie nazwą swój stan na dany moment. W razie potrzeby zawsze możesz do tego punktu powrócić.


Taki punkt przywracania tworzysz przy normalnie otwartej i działającej instancji. Możesz ich utworzyć wiele. W razie potrzeby odtwarzanie do takiego punktu przebiega bardzo szybko. Wskazujesz tylko do jakiego punktu przywracania odtwarzać chcesz bazę.




Przywracanie do takiego punktu również wykonujemy w trybie MOUNT EXCLUSIVE. Po wszystkim otwieramy bazę z RESETLOGS.

Flashback ma jeszcze jedną ciekawą własność. Pozwala cofnąć się przed RESETLOGS:



Aby świat nie był zbyt piękny a adminka zbyt prosta pamiętaj też o ograniczeniach. Nie będziesz mógł odtworzyć bazy flashbackiem jeśli :
  • plik kontrolny był odtwarzany
  • Skasowano tablespace
  • zmniejszono plik danych