Ta strona została przetłumaczona maszynowo. Przeczytaj oryginał angielski. English

Biblioteka IBSurgeon

Przewodnik po odzyskiwaniu danych w InterBase i Firebird

NOTICE: Ten dokument jest rozdziałem z książki “The InterBase World”, która została napisana przez Aleksieja Kowiazina i Serga Wostrikowa.

Rozdział z książki “The InterBase World” poświęcony naprawie baz danych.

1. Historia tego przewodnika

Rosyjska książka “The InterBase World” została opublikowana we wrześniu 2002 roku.

Jej nakład wynosił 3000 egzemplarzy. Po 3 miesiącach została wyprzedana, a drugie, poprawione wydanie zostało opublikowane w kwietniu 2003 roku z nakładem 5000 egzemplarzy.

Obecnie znajduje się na szczycie największych rosyjskich księgarni internetowych i mamy nadzieję, że wkrótce zostanie wyprzedana.

Autorami książki są Alexey Kovyazin, twórca IBSurgeon i

znany rosyjski specjalista od InterBase, oraz Serg Vostrikov, dyrektor generalny Devrace

firmy www.devrace.com

To zabawne, że ani jedna książka poświęcona InterBase nie została opublikowana w języku angielskim!

Tysiące i tysiące programistów używa InterBase i Firebird, dyskutuje na ten

temat na różnych konferencjach (zobacz tutaj: Linki).

Społeczność programistów InterBase liczy średnio dziesiątki tysięcy

ludzi. Silne zapotrzebowanie na książki o InterBase w różnych krajach dowodzi, że społeczność InterBase jest naprawdę duża.

Możemy postawić skrzynkę piwa na to, że nakład 10000 egzemplarzy zostanie zmieciony z Amazon.com w ciągu miesiąca. Ale ludzie w firmach wydawniczych

“wiedzą wszystko” i są pewni, że nikt nie kupi książki o InterBase. To prawdziwa szkoda.

Tutaj chcielibyśmy zaproponować Ci szkic jednego rozdziału tej książki poświęconego odzyskiwaniu baz danych InterBase/Firebird.

2. Jak odzyskać bazę danych InterBase/Firebird

2.1. Przegląd głównych przyczyn uszkodzenia bazy danych

Niestety zawsze istnieje prawdopodobieństwo, że jakikolwiek magazyn informacji zostanie

uszkodzony i część informacji z niego zostanie utracona. Baza danych nie jest wyjątkiem od tej reguły. W tym rozdziale rozważymy główne przyczyny prowadzące do uszkodzenia bazy danych InterBase, niektóre metody naprawy baz danych i wyodrębniania z nich informacji. Poznamy również zalecenia i środki ostrożności, które zminimalizują prawdopodobieństwo utraty informacji z bazy danych.

Przede wszystkim, jeśli mówimy o naprawie bazy danych, powinniśmy wyjaśnić pojęcie

“uszkodzenia bazy danych”. Baza danych jest zwykle nazywana uszkodzoną, jeśli podczas próby wyodrębnienia lub zmodyfikowania informacji pojawiają się błędy i/lub wyodrębniona informacja okazuje się utracona, niekompletna lub całkowicie błędna. Zdarzają się przypadki, gdy uszkodzenia bazy danych są ukryte i wykrywane dopiero przez testowanie specjalnymi narzędziami, ale istnieją również realne uszkodzenia bazy danych, gdy niemożliwe jest połączenie się z bazą danych, gdy dostosowane programy-klienci pokazują dziwne błędy (gdy nie wykonano żadnych manipulacji na bazie danych) lub gdy niemożliwe jest przywrócenie bazy danych z kopii zapasowej.

2.2. Główne przyczyny uszkodzenia bazy danych to:

  • Nieprawidłowe zakończenie działania komputera serwera, zwłaszcza przerwa w dostawie energii elektrycznej. Dla branży IT to prawdziwa plaga i dlatego mamy nadzieję, że nie trzeba przypominać o konieczności posiadania źródła zasilania awaryjnego na serwerze.
  • Wady i usterki komputera serwera, zwłaszcza dysku twardego (HDD), kontrolerów dysków, pamięci głównej komputera i pamięci podręcznej kontrolerów RAID.
  • Nieprawidłowy ciąg połączenia z wieloklientową bazą danych jednego lub więcej użytkowników (w wersjach wcześniejszych niż 6.x). Podczas łączenia przez TCP/IP, ścieżka do bazy danych musi wskazywać nazwę serwera: dysk:/ścieżka/nazwabazy /dla serwerów na platformie UNIX nazwaserwera: /ścieżka/nazwabazy /, zgodnie z protokołem NETBEUI \\nazwaserwera\dysk:\ścieżka\nazwabazy. Nawet podczas łączenia z bazy danych z komputera, na którym znajduje się baza danych i działa serwer, należy użyć tej samej linii, zmieniając nazwę serwera na localhost. Nie można używać zamapowanych dysków w linii połączenia. Jeśli złamiesz jedną z tych zasad, serwer uzna, że pracuje z różnymi bazami danych, a uszkodzenie bazy danych jest gwarantowane.
  • Kopiowanie plików lub inny dostęp do plików bazy danych, gdy serwer działa. Wykonanie polecenia “shut-down” lub rozłączenie użytkowników w zwykły sposób nie jest gwarancją, że serwer nic nie robi z bazą danych, jeśli interwał zamiatania nie jest ustawiony na “0”, może zostać wykonane czyszczenie śmieci. Zazwyczaj czyszczenie śmieci jest wykonywane natychmiast po rozłączeniu ostatniego użytkownika z bazą danych. Zwykle trwa to kilka sekund, ale jeśli wcześniej zatwierdzono wiele operacji DELETE lub UPDATE, proces może trwać dłużej.
  • Używanie niestabilnych wersji serwera InterBase 5.1-.5.5. Firma Borland oficjalnie przyznała, że w tych serwerach było kilka błędów, a stabilna aktualizacja 5.6 została usunięta dopiero po wydaniu certyfikowanego InterBase 6 w trybie swobodnym dla wszystkich klientów serwerów 5.1-5.5 na swojej stronie internetowej.
  • Przekroczenie limitu rozmiaru pliku bazy danych (nie bazy danych!). Dla wersji przed InterBase 6 i niektórych wersji beta InterBase 6 limit pliku bazy danych wynosi 4 GB, dla InterBase 6.5 i wszystkich wydań Firebird (1.0, 1.5, 2.0, 2.1) - 32 TB. Gdy rozmiar bazy danych zbliża się do wartości granicznej, należy utworzyć dodatkowy plik.
  • Wyczerpanie wolnego miejsca na dysku podczas pracy z bazą danych.
  • Dla serwerów Borland InterBase w wersjach poniżej 6.0.1.6 - przekroczenie limitu liczby generatorów zdefiniowanego przez Borland InterBase R & D w następujący sposób (patrz tabela 1).
Wersja Rozmiar strony=1024 Rozmiar strony=2048 Rozmiar strony=4096 Rozmiar strony=8192
Przed 6 248 504 1016 2040
6.0.x 124 257 508 102

Tabela 1: Krytyczna liczba generatorów we wczesnych wersjach InterBase

• Dla wszystkich serwerów Borland InterBase - przekroczenie dopuszczalnej liczby

transakcji bez wykonania kopii zapasowej/przywrócenia. Liczbę transakcji, które miały miejsce w bazie danych od czasu ostatniego utworzenia, można poznać, wywołując narzędzie gstat z kluczem - h - parametr NEXT TRANSACTION ID będzie pożądaną

liczbą transakcji. Według Ann W. Harrison krytyczna liczba

transakcji zależy od rozmiaru strony i ma następujące wartości (patrz tabela 2):

Rozmiar strony bazy danych Krytyczna liczba transakcji
1024 bajty 131 596 287
2048 bajtów 265 814 016
4096 bajtów 534 249 472
8192 bajty 1 071 120 384

Tabela 2: Krytyczna liczba transakcji w serwerach Borland InterBase

Ograniczenia serwerów Borland InterBase wymienione powyżej nie dotyczą

serwerów Firebird, z wyjątkiem najwcześniejszych wersji 0.x., których istnienie przeszło już do historii. Jeśli używasz finalnej wersji Firebird 1.0 lub InterBase 6.5-7.x, nie powinieneś martwić się punktami 5, 6, 8 i 9 i powinieneś skupić swoje wysiłki na innych przyczynach. Teraz rozważymy najczęstsze z nich szczegółowo.

2.3. Awaria zasilania

Po wyłączeniu zasilania na serwerze wszystkie czynności przetwarzania danych są

przerywane w najbardziej nieoczekiwanym i (zgodnie z prawem Murphy’ego) niebezpiecznym

miejscu. W rezultacie informacje w bazie danych mogą zostać zniekształcone lub utracone. Najprostszym przypadkiem jest utrata wszystkich niezatwierdzonych danych z aplikacji klienckich w wyniku awaryjnego wyłączenia serwera. Po ponownym uruchomieniu po awarii zasilania serwer analizuje dane, zauważa niekompletne transakcje niezwiązane z żadnym z klientów i anuluje wszystkie modyfikacje dokonane w ramach tych “martwych” transakcji. Takie zachowanie jest w rzeczywistości normalne i zakładane od początku przez twórców InterBase.

Jednak przerwa w dostawie energii nie zawsze wiąże się tylko z tak nieznacznymi

stratami. Jeśli serwer wykonywał rozszerzanie bazy danych w momencie przerwy w dostawie energii, istnieje duże prawdopodobieństwo wystąpienia osieroconych stron w pliku bazy danych (strony fizycznie przydzielone i zarejestrowane na stronie inwentarza stron (PIP), na których zapis danych jest niemożliwy). Jeśli chcesz dowiedzieć się więcej o osieroconych stronach, zajrzyj do rozdziału “Struktura bazy danych InterBase”.

Tylko narzędzie do naprawy i modyfikacji gfix (rozważymy je poniżej) jest w stanie walczyć z osieroconymi stronami w pliku bazy danych. W rzeczywistości osierocone strony prowadzą do niepotrzebnego wydatku miejsca na dysku i jako takie nie są przyczyną utraty danych ani uszkodzenia.

Utrata zasilania prowadzi do poważniejszych uszkodzeń. Na przykład po wyłączeniu

zasilania i ponownym uruchomieniu duża ilość danych, w tym zatwierdzonych, może zostać utracona (po dodaniu lub modyfikacji, po której wykonano polecenie “commit transaction”). Dzieje się tak, ponieważ potwierdzone dane nie są zapisywane bezpośrednio do pliku bazy danych na dysku. Do tego celu wykorzystywana jest pamięć podręczna plików systemu operacyjnego (OS). Proces serwera wydał polecenie zapisu danych do OS. Następnie OS zapewnił serwer, że wszystkie dane zostały zapisane na dysku, a w rzeczywistości dane były przechowywane w pamięci podręcznej plików. OS nie spieszy się z zapisaniem tych danych na dysk, ponieważ uważa, że pozostało dużo pamięci głównej i odkłada wolne operacje zapisu na dysk, dopóki pamięć główna nie zostanie wypełniona.

2.4. Wymuszone zapisy - miecz obosieczny

Aby wpłynąć na tę sytuację, w InterBase 6 przewidziano dostrajanie trybu zapisu danych. Parametr ten nazywa się forced writes (FW) i ma 2 tryby - ON (synchroniczny) i OFF (asynchroniczny). Tryby FW określają, w jaki sposób InterBase komunikuje się z dyskiem. Jeśli FW jest włączony, ustawienie synchronicznego zapisu na dysk jest włączone, gdy potwierdzone dane są zapisywane na dysk tuż po poleceniu commit, serwer czeka na zakończenie zapisu i dopiero wtedy kontynuuje przetwarzanie. Jeśli FW jest wyłączony, InterBase nie spieszy się z zapisem danych na dysk po poleceniu zatwierdzenia transakcji i deleguje to zadanie do równoległego wątku, podczas gdy główny wątek kontynuuje przetwarzanie danych, nie czekając na zakończenie zapisów na dysku. Tryb zapisu synchronicznego jest jednym z najbardziej ostrożnych i minimalizuje wszelkie możliwe straty danych, jednak może powodować pewną utratę wydajności. Tryb zapisu asynchronicznego zwiększa prawdopodobieństwo utraty dużej ilości danych. Aby osiągnąć maksymalną wydajność, zwykle ustawia się tryb FW Off. Ale w wyniku przerwy w zasilaniu podczas zapisu asynchronicznego traci się znacznie więcej danych niż podczas zapisu synchronicznego. Ustawiając tryb zapisu, powinieneś zdecydować, czy kilka procent wydajności jest ważniejsze niż kilka godzin pracy, jeśli przerwa w zasilaniu nastąpi nieoczekiwanie.

Bardzo często użytkownicy są nieostrożni wobec InterBase. Małe organizacje oszczędzają na wszystkim, często na komputerze-serwerze, na którym zainstalowany jest serwer DBMS i różne programy serwerowe (i nie tylko serwerowe). Jeśli się zawieszą, ludzie myśląc, że nie na długo, naciskają RESET (zdarza się to kilka razy dziennie). Chociaż InterBase jest bardzo odporny na takie działania w porównaniu z innymi DBMS i pozwala rozpocząć pracę z bazą danych tuż po awaryjnym ponownym uruchomieniu, takie użycie nie jest pożądane. Liczba osieroconych stron wzrasta, a dane tracą ze sobą połączenia w wyniku błędnych ponownych uruchomień.

Może to trwać długo, ale prędzej czy później nadejdzie koniec. Gdy uszkodzone strony pojawią się wśród PIP lub stron generatorów, lub jeśli strona nagłówka bazy danych zostanie uszkodzona, baza danych może nigdy więcej się nie otworzyć i stać się dużym kawałkiem oddzielnych danych, z których nie można wyodrębnić ani jednego bajtu użytecznych informacji.

2.5. Uszkodzenie dysku twardego

Uszkodzenia dysku twardego prowadzą do utraty ważnych stron systemowych bazy danych i/lub uszkodzenia połączeń między pozostałymi stronami. Takie uszkodzenia są jednymi z najtrudniejszych przypadków, ponieważ prawie zawsze wymagają interwencji niskiego poziomu, aby przywrócić bazę danych.

2.6. Błędy projektowania bazy danych

Musisz wiedzieć o niektórych błędach popełnianych przez twórców baz danych, które

mogą prowadzić do niemożności odzyskania bazy danych z kopii zapasowej (*.gbk pliki utworzone przez program gbak). Przede wszystkim jest to nieostrożne używanie ograniczeń na poziomie bazy danych. Typowym przykładem są ograniczenia NOT NULL. Załóżmy, że mamy tabelę wypełnioną liczbą rekordów. Teraz dodamy do tej tabeli za pomocą polecenia ALTER TABLE jeszcze jedną kolumnę i wskażemy, że nie może ona zawierać niezdefiniowanych wartości NULL. Coś takiego:

ALTER TABLE sometable Field/INTEGER NOT NULL

I w tym przypadku nie będzie błędu serwera, jak można by się spodziewać. Ta

modyfikacja metadanych zostanie zatwierdzona i nie otrzymamy żadnego błędu ani komunikatu ostrzegawczego, co stwarza złudzenie normalności tej sytuacji.

Jednak jeśli wykonamy kopię zapasową bazy danych i spróbujemy ją przywrócić z kopii zapasowej, otrzymamy

komunikat o błędzie na etapie przywracania (ponieważ wartości NULL są wstawiane do kolumny z ograniczeniem NOT NULL, a proces przywracania zostanie przerwany. (Ważna uwaga od Craiga Stuntza - w wersji InterBase 7.1 ograniczenia są domyślnie ignorowane podczas przywracania (można to kontrolować przełącznikiem wiersza poleceń) i prawie każda nieuszkodzona kopia zapasowa może zostać przywrócona. Zawsze warto wykonać testowe przywracanie po utworzeniu kopii zapasowej, ale ten problem powinien w dużej mierze zniknąć w wersji 7.1.) Ta kopia zapasowa nie może zostać przywrócona. Jeśli przywracanie zostało skierowane do pliku o tej samej nazwie co istniejąca baza danych (podczas przywracania plik roboczy istniejącej bazy danych był nadpisywany), stracimy wszystkie informacje.

Jest to związane z faktem, że ograniczenia NOT NULL są implementowane przez systemowe triggery, które sprawdzają tylko przychodzące dane. Podczas przywracania danych z kopii zapasowej są one wstawiane do pustych, nowo utworzonych tabel - tutaj możemy znaleźć niedozwolone wartości NULL w kolumnie z ograniczeniem NOT NULL.

Niektórzy programiści uważają, że takie zachowanie InterBase jest nieprawidłowe, ale inni nie będą w stanie dodać pola z ograniczeniem NOT NULL do tabeli bazy danych.

Pytanie o wymaganej wartości domyślnej i wypełnianiu nią w momencie

tworzenia było szeroko dyskutowane przez architektów Firebird, ale nie zostało zaakceptowane, ponieważ programista oczywiście będzie ją wypełniał zgodnie z algorytmem, dość skomplikowanym i być może iteracyjnym. Ale nie ma gwarancji, czy będzie w stanie odróżnić rekordy pominięte przez poprzednią iterację od rekordów niewypełnionych.

Podobny problem może być spowodowany błędem działania garbage collection z powodu ustawienia nieprawidłowej ścieżki do bazy danych (przyczyna uszkodzenia 3) w momencie połączenia oraz dostępu do plików bazy danych, gdy serwer z nią pracuje (przyczyna uszkodzenia 4), a rekordy w całości wypełnione wartością NULL mogą pojawić się w niektórych tabelach. Bardzo trudno jest wykryć te rekordy, ponieważ nie odpowiadają one ograniczeniom kontroli integralności, a operator Select po prostu ich nie widzi, chociaż trafiają one do kopii zapasowej. Jeśli przywrócenie jest niemożliwe z tego powodu, należy uruchomić program gfix (patrz poniżej), znaleźć i usunąć te rekordy, używając nieindeksowanych pól jako warunków wyszukiwania, a następnie ponowić próbę utworzenia kopii zapasowej i przywrócenia z niej bazy danych. Podsumowując, można powiedzieć, że istnieje ogromna liczba przyczyn uszkodzenia bazy danych i zawsze należy być przygotowanym na najgorsze - że baza danych zostanie uszkodzona z tego czy innego powodu. Musisz być również gotowy do przywrócenia i zapisania cennych informacji. A teraz rozważymy środki ostrożności, które gwarantują bezpieczeństwo bazy danych InterBase, a także metody naprawy uszkodzonych baz danych.

2.7. Środki ostrożności przeciwko uszkodzeniu bazy danych InterBase

Aby zapobiec uszkodzeniu bazy danych, należy zawsze tworzyć kopie zapasowe (jeśli chcesz dowiedzieć się więcej o kopiach zapasowych, zajrzyj do rozdziału „Kopia zapasowa i przywracanie”). To najbardziej niezawodny sposób przeciwko uszkodzeniu bazy danych. Tylko kopia zapasowa daje 100% gwarancję bezpieczeństwa bazy danych. Jak opisano powyżej, w wyniku kopii zapasowej możemy otrzymać bezużyteczną kopię (kopię, której nie można przywrócić), dlatego przywracanie bazy z kopii nie powinno być wykonywane przez nadpisywanie skryptu, a kopia zapasowa musi być wykonywana zgodnie z określonymi zasadami. Po pierwsze, kopia zapasowa musi być wykonywana tak często, jak to możliwe, po drugie musi być sekwencyjna, a po trzecie, kopie zapasowe muszą być sprawdzane pod kątem możliwości przywrócenia.

Częstotliwość kopii zapasowej oznacza, że należy tworzyć kopię zapasową dość często, na przykład raz na dwadzieścia cztery godziny. Im krótszy okres między kopiami zapasowymi bazy danych, tym mniej danych zostanie utraconych w wyniku awarii. Sekwencyjność kopii zapasowej oznacza, że liczba kopii zapasowych musi wzrastać i być przechowywana przez co najmniej tydzień. Jeśli istnieje możliwość, należy zapisywać kopie zapasowe na specjalnych urządzeniach, takich jak streamer, a jeśli nie - po prostu kopiować je na inny komputer. Historia kopii zapasowych pomoże wykryć ukryte uszkodzenia i poradzić sobie z błędem, który powstał dawno temu i ujawnił się nieoczekiwanie. Należy sprawdzić, czy możliwe jest przywrócenie otrzymanej kopii zapasowej bez błędów. Można to sprawdzić tylko w jeden sposób - poprzez proces testowego przywracania. Należy powiedzieć, że proces przywracania zajmuje 3 razy więcej czasu niż kopia zapasowa, a wykonywanie walidacji przywracania codziennie dla dużych baz danych jest trudne, ponieważ może przerwać pracę użytkowników na kilka godzin (przerwa nocna może nie wystarczyć).

Byłoby lepiej, gdyby duże organizacje nie oszczędzały na „zapałkach” i zostawiły jeden komputer do tych celów.

W takim przypadku, jeśli serwer musi pracować z poważnym obciążeniem 24 godziny 7 dni w tygodniu, możemy użyć mechanizmu SHADOW do robienia migawek z bazy danych i dalszych operacji kopii zapasowej z natychmiastowej kopii. Proces kopii zapasowej i przywracania bazy danych jest szczegółowo opisany w rozdziale „Kopia zapasowa i przywracanie”. Podczas tworzenia kopii zapasowej, a następnie przywracania z niej bazy danych, następuje odtworzenie wszystkich danych w bazie. Ten proces (kopia zapasowa/przywracanie lub b/r) przyczynia się do korekty większości niekrytycznych błędów w bazie danych, związanych z uszkodzeniami dysku twardego, wykrywania problemów z integralnością w bazie danych, czyszczenia bazy z śmieci (starych wersji i fragmentów rekordów, niekompletnych transakcji), znacznego zmniejszenia rozmiaru bazy danych.

Regularne b/r jest gwarancją bezpieczeństwa bazy danych InterBase. Jeśli baza danych działa, zaleca się wykonywanie b/r co tydzień. Prawdę mówiąc, istnieją przykłady baz danych InterBase, które są intensywnie używane przez wiele lat bez kopii zapasowej/przywracania.

Niemniej jednak, dla bezpieczeństwa wskazane jest wykonanie tej procedury, zwłaszcza że można ją łatwo zautomatyzować (zobacz rozdział „Kopia zapasowa”).

Jeśli z jakichś powodów niemożliwe jest częste wykonywanie kopii zapasowej/przywracania, można użyć narzędzia gfix do sprawdzania i przywracania bazy danych. gfix pozwala sprawdzić i usunąć wiele błędów bez b/r.

2.8. Narzędzie wiersza poleceń gfix

Narzędzie wiersza poleceń gfix jest używane do sprawdzania i przywracania bazy danych. Ponadto gfix może również wykonywać różne czynności kontroli bazy danych: zmianę dialektu bazy danych, ustawianie i anulowanie trybu „tylko do odczytu”, ustawianie rozmiaru pamięci podręcznej dla konkretnej bazy danych, a także niektóre ważne funkcje (można się o nich dowiedzieć w InterBase 6 Operations Guide [4.) gfix jest uruchamiany w trybie wiersza poleceń i ma następującą składnię:

Gfix [opcje] nazwa_bazy

Opcje - to zestaw opcji do wykonania gfix, nazwa_bazy to nazwa bazy danych, na której będą wykonywane operacje, określona przez zestaw opcji. Tabela 3 przedstawia opcje gfix związane z naprawą bazy danych:

Opcja Opis
-f[ull] Ta opcja jest używana w połączeniu z -v i
oznacza, że należy sprawdzić wszystkie fragmenty rekordów
-i[gnore] Opcja powoduje, że gfix ignoruje błędy sum kontrolnych podczas
walidacji lub czyszczenia bazy danych
-m[end] Oznacza uszkodzone rekordy jako niedostępne, w
wyniku czego zostaną one usunięte podczas
kolejnej kopii zapasowej/przywracania. Opcja jest używana w
momencie przygotowania uszkodzonej bazy danych do b/r.
-n[o_update] Opcja jest używana w połączeniu z -v do
walidacji bazy danych tylko do odczytu bez korygowania
uszkodzeń
-pas[sword] Opcja pozwala ustawić hasło podczas
łączenia z bazą danych. (Uwaga: to błąd w
dokumentacji InterBase -pa[ssword], ale
skrót “-pa” nie zadziała - użyj “-pas”)
-user Opcja pozwala ustawić nazwę użytkownika łączącego
się z bazą danych
-v[alidate] Opcja ustawiająca walidację bazy danych, w wyniku
której wykrywane są błędy
-m[ode] Opcja ustawiająca tryb zapisu dla bazy danych - tylko
do odczytu lub odczyt/zapis. Ten parametr może
przyjmować 2 wartości - read write lub read only.
-w[rite] {sync | async} Opcja włączająca i wyłączająca tryb
synchronicznych/asynchronicznych wymuszonych zapisów do
bazy danych. sync - włącza zapisy synchroniczne
(FW ON); async - włącza zapisy asynchroniczne
(FW OFF);

Tabela 1: Opcje narzędzia gfix do przywracania bazy danych

Oto kilka typowych przykładów użycia gfix:

gfix -w sync -user SYSDBA -pass masterkey firstbase.gdb

W tym przykładzie ustawiamy dla naszej testowej bazy danych firstbase.gdb tryb zapisów synchronicznych (FW ON). (Oczywiście warto to zrobić przed wystąpieniem uszkodzenia). A poniżej jest pierwsze polecenie, którego należy użyć do sprawdzenia bazy danych po wystąpieniu uszkodzenia:

gfix -v -full -user SYSDBA -pass masterkey firstbase.gdb

W tym przykładzie rozpoczynamy sprawdzanie naszej testowej bazy danych (opcja -v) i wskazujemy, że fragmenty rekordów również muszą być sprawdzone (opcja -full). Oczywiście wygodniej jest ustawić różne opcje procesu sprawdzania i przywracania za pomocą dowolnego GUI, ale rozważymy funkcje odzyskiwania bazy danych za pomocą narzędzi wiersza poleceń. Te narzędzia są zawarte w InterBase i możesz być pewien, że ich zachowanie będzie takie samo na wszystkich systemach operacyjnych obsługujących InterBase. Bardzo ważne jest, aby zawsze były pod ręką.

Ponadto istniejące narzędzia, pozwalające na administrowanie bazą danych z

komputera klienta, używają do tego Services API, które nie jest obsługiwane przez architekturę serwera Classic InterBase. Oznacza to, że możesz używać produktów innych firm z architekturą serwera SuperServer.

2.9. Naprawa uszkodzonej bazy danych

Załóżmy, że w naszej bazie danych są pewne błędy. Po pierwsze, musimy sprawdzić istnienie tych błędów; po drugie, musimy spróbować je poprawić. Należy postępować zgodnie z poniższymi instrukcjami.

Należy zatrzymać serwer InterBase, jeśli nadal działa, i wykonać kopię pliku lub plików bazy danych. Wszystkie czynności przywracania powinny być wykonywane tylko na kopii bazy danych, ponieważ wybrana metoda może prowadzić do niepomyślnego wyniku, a procedurę przywracania trzeba będzie rozpocząć od nowa (od punktu początkowego). Po utworzeniu kopii wykonamy pełną walidację bazy danych (sprawdzenie fragmentów rekordów).

W tym celu należy wykonać następujące polecenie:

gfix -v - full corruptbase gdb -user SYSDBA - password

W tym przypadku corruptbase.gdb - to kopia uszkodzonej bazy danych. Polecenie sprawdzi bazę danych pod kątem jakichkolwiek uszkodzeń struktury i poda listę nierozwiązanych problemów. Jeśli takie błędy zostaną wykryte, będziemy musieli usunąć uszkodzone dane i przygotować się do kopii zapasowej/przywracania za pomocą następującego polecenia:

gfix -mend -user SYSDBA -password your_masterkey corruptbase gdb

Po wykonaniu polecenia należy sprawdzić, czy w bazie danych pozostały jakieś błędy. W tym celu należy uruchomić gfix z opcjami -v -full, a gdy proces się zakończy, wykonać kopię zapasową bazy danych:

gbak -b -v -ig -user SYSDBA -password corruptbase.gdb corruptbase.gbk

To polecenie wykona kopię zapasową bazy danych (opcja - b o tym mówi) i otrzymamy szczegółowe informacje o procesie wykonywania kopii zapasowej (opcja -v). Błędy dotyczące sum kontrolnych zostaną zignorowane (opcja - ig). Jeśli chcesz dowiedzieć się więcej o opcjach narzędzia wiersza poleceń gbak, znajdziesz je w rozdziale „Kopia zapasowa i przywracanie”. Jeśli podczas kopii zapasowej wystąpią błędy, należy uruchomić ją w innej konfiguracji:

gbak -b -v -ig -g -user SYSDBA -password corruptbase.gdb

corruptbase.gbk

Gdzie opcja - g wyłączy garbage collection podczas kopii zapasowej. Często pomaga to rozwiązać problem z kopią zapasową.

Możliwe jest również wykonanie kopii zapasowej bazy danych, jeśli wcześniej ustawimy bazę w trybie tylko do odczytu. Ten tryb zapobiega zapisywaniu jakichkolwiek modyfikacji do bazy danych i czasami pomaga wykonać kopię zapasową uszkodzonej bazy danych. Aby ustawić bazę w trybie tylko do odczytu, należy użyć następującego polecenia: gfix -m read_only

-user SYSDATA -password masterkey Disk:\Path\file.gdb

Po tym należy ponownie spróbować wykonać kopię zapasową bazy danych, używając parametrów podanych powyżej.

Jeśli kopia zapasowa została wykonana pomyślnie, należy przywrócić bazę danych z kopii zapasowej. Należy użyć następującego polecenia:

gbak -c -user SYSDATA -password masterkey Disk:\Path\backup.gbk

Disk:\Path\newbase,gdb

Podczas przywracania bazy danych mogą wystąpić pewne problemy, zwłaszcza podczas tworzenia indeksów. W takim przypadku do polecenia przywracania należy dodać opcje -inactive i -one_at_a_time. Opcje te dezaktywują indeksy tworzone z kopii zapasowej bazy danych i zatwierdzają dane dla każdej tabeli.

2.10. Jak można spróbować wyodrębnić dane z uszkodzonej bazy danych

Możliwe, że powyższe operacje nie doprowadzą do odzyskania bazy danych. Oznacza to, że baza danych jest poważnie uszkodzona lub nie może zostać przywrócona jako całość, albo wymaga włożenia ogromnego wysiłku w jej odzyskanie. Na przykład można dokonać modyfikacji metadanych systemowych, użyć nieudokumentowanych funkcji itp. Jest to bardzo ciężka, długotrwała i niewdzięczna praca z wątpliwymi szansami na sukces. Jeśli to możliwe, należy jej unikać i stosować inne metody. Jeśli uszkodzona baza danych otwiera się i pozwala na wykonywanie operacji odczytu i modyfikacji niektórych danych, należy wykorzystać tę możliwość i zapisać dane, kopiując je do nowej bazy, a starą pożegnać na dobre.

Tak więc przed przeniesieniem danych ze starej bazy danych konieczne jest utworzenie bazy docelowej. Jeśli baza danych nie była zmieniana przez długi czas, można użyć starej kopii zapasowej, z której można wyodrębnić metadane do utworzenia bazy docelowej. Na podstawie tych metadanych należy utworzyć bazę docelową i rozpocząć kopiowanie danych. Głównym zadaniem jest wyodrębnienie danych z uszkodzonej bazy danych. Następnie trzeba będzie rozmieścić dane w nowej bazie, ale nie jest to bardzo trudne, nawet jeśli trzeba będzie odtworzyć strukturę bazy z pamięci. Podczas wyodrębniania danych z tabel należy zastosować następujący algorytm operacji:

  • Najpierw należy spróbować wykonać SELECT* z tabeli N. Jeśli przebiegło normalnie, można zapisać uzyskane dane w źródle zewnętrznym. Lepiej przechowywać dane w skrypcie (prawie wszystkie GUI oferują tę funkcję), o ile tabela nie zawiera pól BLOB. Jeśli w tabeli znajdują się pola BLOB, dane z nich należy zapisać do innej bazy danych za pomocą programu klienckiego, który będzie pełnił rolę pośrednika. Być może trzeba będzie napisać ten prosty program specjalnie do celów odzyskiwania danych.
  • Jeśli nie udało się pobrać wszystkich danych, należy usunąć wszystkie indeksy i spróbować ponownie. W praktyce indeksy można usunąć ze wszystkich tabel od początku przywracania, ponieważ nie będą już potrzebne. Oczywiście, jeśli nie masz struktury metadanych identycznej z uszkodzoną, konieczne jest wprowadzenie protokołu wszystkich operacji wykonywanych na uszkodzonej bazie źródłowej.
  • Jeśli po usunięciu indeksów nie uda się odczytać wszystkich danych z tabeli, można spróbować wykonać zapytanie zakresowe po kluczu głównym. Oznacza to wybranie określonego zakresu danych. Na przykład:

SELECT * FROM table N WHERE field_PK >=0 and field_PK <=10000 Field_PK

tutaj jest kluczem głównym. InterBase ma stronicową organizację danych i dlatego zapytania zakresowe mogą być dość skuteczne, chociaż wydaje się to czymś w rodzaju szamanizmu. Niemniej jednak to działa, ponieważ możemy wykluczyć dane z zapytania z uszkodzonych stron i szczęśliwie odczytać pozostałe. Można przypomnieć sobie naszą tezę, że w SQL nie ma określonej kolejności przechowywania rekordów. Naprawdę nikt nie gwarantuje, że nieuporządkowane zapytanie podczas ponownych uruchomień zwróci rekordy w tej samej kolejności, ale mimo to rekordy fizyczne są przechowywane w bazie danych w określonej kolejności wewnętrznej. Oczywiście serwer nie będzie mieszał rekordów tylko po to, aby przestrzegać standardu SQL. Można spróbować wykorzystać tę wewnętrzną kolejność do wyodrębnienia danych z uszkodzonej bazy danych (jeśli chcesz dowiedzieć się więcej o stronach danych i ich korelacjach, zajrzyj do rozdziału „Struktura bazy danych InterBase”).

Vitaliy Barmin, jeden z doświadczonych rosyjskich programistów InterBase, poinformował, że w ten sposób udało mu się odzyskać do 98% informacji z nieodzyskiwalnej bazy danych (było tam wiele uszkodzonych stron). Tak więc dane z uszkodzonej bazy danych należy przenieść do nowej bazy danych lub do źródeł zewnętrznych, takich jak skrypty SQL. Podczas kopiowania danych zwróć uwagę na wartości generatorów w uszkodzonej bazie danych (muszą zostać zapisane, aby zapewnić prawidłowe działanie nowej bazy danych. Jeśli nie masz pełnej kopii metadanych, powinieneś wyodrębnić teksty procedur składowanych, wyzwalaczy, ograniczeń i definicji indeksów.

2.11. Przywracanie beznadziejnej bazy danych

Ogólnie rzecz biorąc, przywracanie bazy danych może być bardzo kłopotliwe i trudne, dlatego lepiej jest wykonać kopię zapasową bazy danych niż odzyskiwać uszkodzone dane i cokolwiek się stanie, nie należy rozpaczać, ponieważ w najtrudniejszych sytuacjach można znaleźć rozwiązanie. Teraz rozważymy 2 przypadki.

Pierwszy przypadek (klasyczny problem). Kopia zapasowa, której nie można przywrócić z powodu wartości NULL w kolumnie z ograniczeniem NOT NULL (proces przywracania został uruchomiony na działającym pliku). Plik roboczy został usunięty, a proces przywracania został przerwany z powodu błędu. W wyniku bezmyślnych działań zamiast kopii zapasowej otrzymaliśmy ogromną ilość bezużytecznych danych (których nie można przywrócić). Ale znaleziono rozwiązanie. Programiście udało się przypomnieć sobie, która tabela i która kolumna miały ograniczenie NOT NULL. Plik kopii zapasowej został załadowany do edytora szesnastkowego. I kombinacja bajtów odpowiadająca definicji tej kolumny została znaleziona przez wyszukiwanie. Po niezliczonych eksperymentach okazało się, że ograniczenie NOT NULL dodaje 1 gdzieś w pobliżu nazwy kolumny. W edytorze HEX ta „1” została poprawiona na „0” i kopia zapasowa została przywrócona. Po tym przypadku programista zapamiętał raz na zawsze, jak wykonywać proces tworzenia kopii zapasowej i przywracania.

Drugi przypadek. Sytuacja była katastrofalna. Baza danych została uszkodzona na etapie rozszerzania z powodu braku miejsca na dysku. Podczas zwiększania rozmiaru bazy danych serwer tworzy serię krytycznie ważnych stron (na przykład stronę transakcji i stronę inwentaryzacji stron, dodatkowe strony dla relacji RDB$Pages) i zapisuje je na końcu bazy danych. W rezultacie baza danych nie otwierała się ani za pomocą narzędzi administracyjnych, ani za pomocą narzędzia GBAK. A gdy próbowaliśmy połączyć się z bazą danych, pojawiał się komunikat o błędzie („Unexpected end of file”).

Kiedy uruchomiliśmy narzędzie gfix, działy się dziwne rzeczy: program działał w nieskończonej pętli. Gdy gfix działał, serwer zapisywał błędy do dziennika (plik InterBase log) z dużą prędkością (około 100 Kb na sekundę). W rezultacie plik dziennika bardzo szybko wypełnił całe wolne miejsce na dysku. Musieliśmy nawet napisać program, który kasował ten dziennik za pomocą timera. Proces ten trwał długo - gfix działał ponad 16 godzin bez żadnych rezultatów. Dziennik był wypełniony błędami następującego typu: „Page XXX doubly allocated”. W źródłach InterBase (w pliku val.#) znajduje się krótki opis tego błędu. Mówi on, że błąd ten pojawia się, gdy ta sama strona danych jest używana dwukrotnie. Oczywiście błąd ten jest wynikiem uszkodzenia krytycznie ważnych stron.

W rezultacie po kilku dniach nieudanych eksperymentów porzucono próby przywrócenia danych standardowymi metodami. Dlatego musieliśmy zastosować analizę niskopoziomową danych przechowywanych w uszkodzonej bazie danych.

Alexander Kozelskiy, szef działu technologii informatycznych East View Publications Inc, jest autorem pomysłu, jak wyodrębnić informacje z podobnych nieodzyskiwalnych baz danych.

Metoda przywracania, którą otrzymaliśmy w wyniku badań, opierała się na fakcie, że baza danych ma organizację stronicową, a dane z każdej tabeli są gromadzone na stronach danych. Każda strona danych zawiera identyfikator tabeli, dla której przechowuje dane. Szczególnie ważne było przywrócenie danych z kilku krytycznych tabel. Były tam dane z podobnych tabel, otrzymane ze starej kopii zapasowej, która działała doskonale i mogła być wzorcem. Baza wzorcowa została załadowana do edytora źródeł szesnastkowych, a następnie szukaliśmy wzorców tych danych, które nas interesowały. Dane te zostały skopiowane do bufora w formacie szesnastkowym, a następnie pozostałości uszkodzonej bazy danych zostały załadowane do edytora. Sekwencja bajtów odpowiadająca wzorcowi została znaleziona w uszkodzonej bazie danych, a strona (na której znaleziono tę sekwencję) została przeanalizowana.

Najpierw określiliśmy początek strony, ale nie było to trudne, ponieważ rozmiar pliku bazy danych jest podzielny przez rozmiar strony danych. Numer bieżącego bajtu podzielony przez rozmiar strony - 8192 bajty, przybliża wynik do liczby całkowitej (i otrzymaliśmy numer bieżącej strony). Następnie pomnożyliśmy numer bieżącej strony przez rozmiar strony i otrzymaliśmy numer bajtu odpowiadający początkowi bieżącej strony. Po przeanalizowaniu nagłówka określiliśmy typ strony (dla stron z danymi typ to 5 - patrz plik ods.h z zestawu źródeł InterBase oraz rozdział „Struktura bazy danych InterBase”) oraz identyfikator potrzebnej tabeli.

Następnie napisano program, który analizował całą bazę danych, zbierał wszystkie strony dla potrzebnej tabeli w jedną całość i przenosił je do pliku.

Tak więc, gdy otrzymaliśmy potrzebne dane w pierwszej kolejności, zaczęliśmy analizować zawartość wybranych stron. InterBase szeroko stosuje kompresję danych w celu oszczędzania miejsca. Na przykład ciąg znaków typu VARCHAR zawierający „ABC” przechowuje sekwencję następujących wartości: długość ciągu (2 bajty), w naszym przypadku 0003, a następnie same znaki i sumę kontrolną. Musieliśmy napisać analizator ciągów, a także innych typów baz danych, który konwertował dane z formatu szesnastkowego na zwykły widok. Udało nam się wyodrębnić do 80% informacji z kilku krytycznych tabel za pomocą „ręcznej” metody analizy zawartości bazy danych. Później, na podstawie doświadczeń, Oleg Kulkov i Alexey Kovyazin, jeden z autorów tej książki, opracowali narzędzie InterBase Surgeon, które wykonuje bezpośredni dostęp do bazy danych, omijając silnik InterBase i pozwala bezpośrednio odczytywać i interpretować dane w bazie danych InterBase w odpowiedni sposób.

Korzystając z InterBase Surgeon, udaje nam się wykryć przyczyny uszkodzeń i przywrócić do 90% całkowicie nieodzyskiwalnych baz danych, których nie można otworzyć przez InterBase i przywrócić standardowymi metodami.

Program można pobrać z oficjalnej strony programu www.ib-aid.com.

3. Podziękowania

Chciałbym podziękować wszystkim, którzy pomogli mi w stworzeniu tego przewodnika:

Craig Stuntz, Alexander Nevsky, Konstantin Sipachev, Tatjana Sipacheva oraz wszystkim innym życzliwym i kompetentnym osobom ze społeczności InterBase i Firebird.

Jeśli masz jakiekolwiek sugestie lub pytania dotyczące tego rozdziału, prosimy o kontakt e-mailowy.

© 2002 AIexey Kovyazin, Serge Vostrikov.

Copyright © 2004 IBSurgeon Team. Wszelkie prawa zastrzeżone.