Serwer Firebird SQL jest takim samym programem jak każdy inny program. Jedyne, co z całą pewnością można powiedzieć o wszelkich programach to to, że zdarzają się w nich błędy. Serwer Firebird SQL działa bardzo stabilnie (zwłaszcza pod kontrolą systemu operacyjnego Linux), ale oczywiście może się zdarzyć, że jakiś błąd w kodzie serwera spowoduje uszkodzenie bazy danych.
Oczywiście są również inne potencjalne powody uszkodzenia bazy danych, na przykład częściowo uszkodzona elektronika dysku, wirusy komputerowe, niepoprawne wyłączenie komputera lub po prostu błędne działania osoby administrującej serwerem.
Jeżeli serwer Firebird SQL działa na serwerze, który jest zasilany przez zasilacz awaryjny (UPS), system jest normalnie zamykany oraz administrator nie wykonuje opisanych dalej działań mogących uszkodzić bazę danych to prawdopodobieństwo uszkodzenia bazy danych jest bardzo małe.
W dalszych krokach niektóre działania wykonywane są przy pomocy standardowych programów GBAK oraz GFIX. Nie są to oczywiście najwygodniejsze programy, ale mają tę zaletę, że są dostępne praktycznie w każdej instalacji serwera Firebird SQL. Jeżeli w danym systemie są dostępne to oczywiście można również skorzystać z dowolnego innego programu realizującego analogiczne zadania w wygodniejszy sposób.
W programach GBAK i GFIX występują między innymi
parametry
−user SYSDBA −password masterkey
.
W tym miejscu zamiast masterkey
należy oczywiście użyć
odpowiedniego hasła użytkownika SYSDBA
. Jeżeli działania
wykonywane są w systemie Linux przez użytkownika root to
oba te parametry można całkowicie pominąć.
Po stwierdzeniu lub podejrzeniu uszkodzenia bazy danych jak najszybciej zablokuj możliwość pracy na uszkodzonej bazie danych.
Są co najmniej dwa powody takiego postępowania:
Najpewniejszym sposobem zapewnienia wyłącznego dostępu do bazy danych jest wykonanie polecenia
gfix uszkodzona.fdb -shut -force 240 -user SYSDBA -password masterkey
To polecenie będzie czekało nie dłużej niż 3 minuty (240 sek.) na zakończenie pracy przez użytkowników bazy danych. Po tym czasie odłączy wszystkich pozostałych użytkowników od bazy danych i zablokuje dostęp użytkowników do bazy danych (oprócz SYSDBA oczywiście).
Działania naprawcze zmieniają informacje w pliku bazy danych. Może się zdarzyć, że podjęte działania nie przyniosą oczekiwanego efektu. W skrajnym przypadku plik bazy danych może ulec dalszemu uszkodzeniu. Dlatego zawsze należy wykonać kopię uszkodzonej bazy danych — dzięki temu w razie potrzeby będzie można podjąć inne działania naprawcze.
copy uszkodzona.fdb naprawiana.fdb
Zanim przystąpimy do naprawy należy zweryfikować uszkodzenia pliku bazy danych. W tym celu wykonujemy polecenie
gfix naprawiana.fdb -validate -full -user SYSDBA -password masterkey
To polecenie nie tylko wykrywa uszkodzenia bazy danych, ale część z nich automatycznie naprawia. Jeżeli będą sygnalizowane błędy bazy danych to polecenie należy powtórzyć w celu upewnienia się czy wszystkie błędy zostały naprawione.
Jeżeli do powyższego polecenia zostanie dodana opcja
−no_update
to polecenie sprawdzi i pokaże wszystkie
wykryte błędy w strukturze bazy danych, ale nie będzie próbować niczego
zmieniać.
Jeżeli natomiast do powyższego polecenia zostanie dodana opcja
−ignore
to polecenie zignoruje wszelkie błędy sum
kontrolnych rekordów lub stron bazy danych.
Kolejnym krokiem może być pominięcie uszkodzonych części bazy danych. W tym celu należy wykonać polecenie
gfix naprawiana.fdb -mend -full -ignore -user SYSDBA -password masterkey
To polecenie oznacza wszystkie uszkodzone części bazy danych jako niedostępne. Dzięki temu będą pominięte przy najbliższym wykonywaniu kopii bezpieczeństwa bazy danych.
Po zaznaczeniu uszkodzonych fragmentów bazy danych jako niedostępne ponownie zweryfikuj bazę danych aby się upewnić czy wszystkie uszkodzenia zostały naprawione.
gfix naprawiana.fdb -validate -full -user SYSDBA -password masterkey
Następnym krokiem jest przebudowa bazy danych. W tym celu należy wykonać kopię bezpieczeństwa bazy danych.
gbak naprawiana.fdb kopia.fbk -backup_database -verify -ignore -garbage_collect -user SYSDBA -password masterkey
Teraz na podstawie kopii bezpieczeństwa utwórz bazę danych od nowa.
gbak kopia.fbk nowa.fdb -create_database -verify -user SYSDBA -password masterkey
Jeżeli podczas odtwarzania stwierdzisz, że uszkodzone są indeksy to
możesz do powyższego polecenia dodać opcję −inactive
.
Dzięki niej indeksy nie będą aktywowane w odtworzonej bazie danych. Po
utworzeniu bazy będzie można takie indeksy aktywować indywidualnie lub
zmienić ich definicję.
Użycie opcji −one_at_a_time
pozwoli na odtworzenie
każdej tabeli z danymi oddzielnie i pominięcie uszkodzonych tabel.
Upewnij się czy odtworzona baza danych jest poprawna. Zweryfikuj ją poleceniem
gfix nowa.fdb -valildate -full -user SYSDBA -password masterkey
Ostatnim krokiem jest przejrzenie danych w bazie w celu upewnienia się czy i jakie dane zostały utracone.
Wykonując opisane wyżej działania naprawcze może dojść do utraty części danych. Wtedy można spróbować innych działań. Jednym ze sprawdzonych w praktyce działań jest utworzenie pustej bazy danych o identycznej strukturze i próba przepisania do niej danych z uszkodzonej bazy.
gbak naprawiana.fdb struktura.fdb -backup_database -ignore -meta_data -verify -user SYSDBA -password masterkey gbak struktura.fdb nowa.fdb -create_database -verify -user SYSDBA -password masterkey
Teraz próbujemy przepisać z dane z uszkodzonej bazy danych do nowe bazy. Można do tego celu wykorzystać na przykład:
Jest też szereg działań, których wykonanie może spowodować uszkodzenie bazy danych.
Jednym z częściej popełnianych błędów jest wykonywanie kopii bezpieczeństwa bazy danych przez kopiowanie pliku bazy danych — na przykład przy pomocy programu do zapisywania kopii plików z dysku na streamer lub płyty CD/DVD itp. Takie działanie jest błędem z kilku powodów.
Najważniejszym powodem jest ryzyko uszkodzenia bazy danych. Programy kopiujące często na czas kopiowania blokują dostęp innych programów do pliku lub jego części. Natomiast serwer Firebird zakłada, że jest jedynym programem korzystającym z pliku bazy danych. Jeżeli cały lub część pliku bazy danych zostanie zablokowana to serwer może nie działać poprawnie i w efekcie uszkodzić plik bazy danych.
Jeżeli kopiujemy plik bazy danych podczas pracy użytkowników tej bazy to może się zdarzyć, że uszkodzone zostaną zarówno oryginalny plik bazy danych oraz wykonywana kopia! NIGDY nie kopiuj pliku bazy danych jeżeli nie masz pewności, że żaden użytkownik nie korzysta z tej bazy danych!
Kopię bezpieczeństwa należy wykonywać przy pomocy programu GBAK (lub innego działającego analogicznie programu). Podczas wykonywania kopii wykonywane jest również porządkowanie bazy danych (garbage collection). Jeżeli kopia bezpieczeństwa jest wykonywana regularnie to również regularnie baza jest porządkowana. Powoduje to stabilniejszą oraz szybszą pracę serwera i aplikacji korzystających z tej bazy danych.
Plik powstały w wyniku działania programu GBAK można oczywiście swobodnie kopiować.
Jeżeli podczas odtwarzania bazy danych pozwolimy użytkownikom na korzystanie z odtwarzanej właśnie bazy to niemal na pewno odtworzona baza będzie uszkodzona!
Aby uniknąć takiego niebezpieczeństwa najlepiej odtwarzać bazę do pliku
o innej nazwie i dopiero po utworzeniu pliku skopiować go w docelowe
miejsce lub zmienić nazwę na docelową. Jeżeli baza jest odtwarzana przy
pomocy standardowego programu GBAK to zamiast opcji
−replace_database
lepiej używać opcję
−create_database
.
Serwer Firebird pamięta wszelkie informacje o obiektach bazy
danych w samej bazie. Są to wszelkie obiekty o nazwach rozpoczynających
się od znaków rdb$
. Należy unikać bezpośredniego modyfikowania
tych tabel, tym bardziej że w kolejnych wersjach serwera znaczenie
informacji w tabelach systemowych może się zmienić.
Bazę danych można uszkodzić wykonując pozornie poprawną modyfikację struktury bazy danych. Przypuśćmy, że projektant chce do jednej z tabel dodać nowe pole. W tym celu wykonuje następującą instrukcję:
ALTER TABLE tabela ADD NowePole INTEGER NOT NULL;
Po wykonaniu tego polecenia pozornie wszystko jest w porządku. Co się
jednak stanie gdy w tabeli były już jakieś rekordy? Nowe pole w
dotychczasowych rekordach będzie miało wartość NULL
bo serwer
nie wie jaką wartością miałby to pole wypełnić.
Można by to tak zostawić. Przecież przy okazji modyfikacji dotychczasowych danych serwer wymusi wypełnienie nowego pola.
Niestety nie jest dobrze. Załóżmy, że użytkownik wykonał kopię bazy
danych. To oczywiście nie jest jeszcze problem — jak napisałem
wcześniej, kopię bazy danych należy wykonywać regularnie. Co się jednak
stanie gdy nastąpi awaria i użytkownik postanowi odbudować bazę na
podstawie takiej kopii? Niestety nie da się! Odtwarzanie bazy zostanie
przerwane. Serwer uzna, że kopia jest niepoprawna bo pole jest zdefiniowane
z klauzulą NOT NULL
, a przecież w kopii w niektórych rekordach
pole ma wartość NULL
.
Prawidłowa aktualizacja powinna mieć postać:
ALTER TABLE tabela ADD NowePole INTEGER NOT NULL; COMMIT; UPDATE tabela SET NowePole = 0;
Dodajemy nowe pole — tak jak powyżej. Następnie wypełniamy dodane
pole w dotychczasowych rekordach wartością domyślną. Obie instrukcje muszą
być rozdzielone instrukcją COMMIT
bo nie wolno w jednej
transakcji mieszać instrukcji modyfikujących strukturę bazy danych (pierwsza
instrukcja) z instrukcjami modyfikującymi dane (ostatnia instrukcja).
Wiele narzędzi przeznaczonych do wykonywania skryptów SQL udostępnia opcję AutoDDL. Włączenie tej opcji powoduje, że po wykonaniu jakiejkolwiek instrukcji modyfikującej dane automatyczmoie wykonywana jest instrukcja COMMIT. Bezpieczniej jednak nie polegać na tej opcji i w skryptach SQL wstawiać w odpowiednich miejscach instrukcję COMMIT. Jeżeli opcja AutoDDL jest aktywna to instrukcje COMMIT w skrypcie SQL będą po prostu instrukcjami pustymi. Jeżeli jednak z jakiegokolwiek powodu opcja AutoDDL nie zadziała to jawna instrukcja COMMIT uchroni przed problemami.
Powodem uszkodzenia bazy mogą być oczywiście wszelkiego rodzaju awarie sprzętu, a w szczególności: