Naprawa uszkodzonej bazy danych

Spis treści

  1. Powody uszkodzeń baz danych
  2. Ratowanie uszkodzonej bazy danych
    1. Zablokuj dostęp do bazy danych
    2. Wykonaj kopię pliku bazy danych
    3. Zweryfikuj bazę danych
    4. Pomiń uszkodzone części bazy danych
    5. Ponownie zweryfikuj bazę danych
    6. Przebuduj bazę danych
    7. Zweryfikuj odtworzoną bazę danych
    8. Działania alternatywne
  3. Działania, które prawdopodobnie uszkodzą bazę danych
    1. Kopiowanie pliku bazy danych
    2. Używanie odtwarzanej bazy danych
    3. Bezpośrednie modyfikowanie tabel systemowych
    4. Błędna modyfikacja struktury bazy danych
    5. Powody sprzętowe

Powody uszkodzeń baz danych

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.

Ratowanie uszkodzonej bazy danych

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ąć.

Zablokuj dostęp do bazy danych

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:

  1. niektóre działania naprawcze wymagają wyłącznego dostępu do bazy danych oraz
  2. dalsza praca na uszkodzonej bazie danych może spowodować jeszcze większe uszkodzenie bazy (a programy użytkowników mogą nie działać prawidłowo).

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

Wykonaj kopię pliku bazy danych

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 

Zweryfikuj bazę danych

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.

Pomiń uszkodzone części 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.

Ponownie zweryfikuj bazę 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 

Przebuduj bazę danych

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.

Zweryfikuj odtworzoną bazę danych

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.

Działania alternatywne

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:

Działania, które prawdopodobnie uszkodzą bazę danych

Jest też szereg działań, których wykonanie może spowodować uszkodzenie bazy danych.

Kopiowanie pliku 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ć.

Używanie odtwarzanej bazy danych

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.

Bezpośrednie modyfikowanie tabel systemowych

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

Błędna modyfikacja struktury bazy danych

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.

Powody sprzętowe

Powodem uszkodzenia bazy mogą być oczywiście wszelkiego rodzaju awarie sprzętu, a w szczególności: