Kopia zapasowa, której nigdy nie odtworzono, nie jest kopią zapasową
Nieprzetestowane kopie zapasowe baz danych zawodzą w przewidywalny sposób: puste zrzuty, brakujące role, nieprawidłowe flagi, brak klucza szyfrowania. Dowiedz się, jak zweryfikować odtwarzanie, aby przechowywany plik rzeczywiście działał.
Najgorszym momentem na odkrycie, że kopia zapasowa nie działa, jest chwila, w której jej potrzebujesz. A jednak właśnie tak wygląda najczęstszy scenariusz: kopie zapasowe skonfigurowane raz, zielony status na dashboardzie przez osiemnaście miesięcy, a następnie odtwarzanie, które tworzy pustą bazę danych.
Testowanie odtwarzania kopii zapasowej bazy danych nie jest dobrą praktyką w takim sensie, w jakim większość dobrych praktyk jest opcjonalna. Kopia zapasowa to deklaracja, a dopóki jej nie odtworzysz, pozostaje ona nieprzetestowaną deklaracją.
Oto jak dochodzi do awarii i co musi faktycznie sprawdzać weryfikacja.
Cztery sposoby, na które kopia zapasowa może po cichu stać się bezużyteczna
1. Jest pusta i nikt tego nie sprawdził
pg_dump, który zakończy działanie w połowie, może mimo wszystko utworzyć plik. Zrzut wykonany dla nieprawidłowej nazwy bazy danych tworzy poprawny, prawidłowy, ale pusty plik. Dla każdego mechanizmu sprawdzającego jedynie niezerowy kod wyjścia lub istnienie pliku oba przypadki wyglądają jak sukces.
Najtańsza kontrola na świecie: sprawdź rozmiar i porównaj go z wczorajszym. Kopia zapasowa o rozmiarze 400 bajtów, gdy wczorajsza miała 40 MB, mówi ci wszystko. Kopia, która od sześciu miesięcy ma 400 bajtów, mówiła ci to przez cały czas.
2. Zawiera dane, ale nie zawiera elementów, które je otaczają
pg_dump pojedynczej bazy danych nie obejmuje ról ani innych baz danych. Odtwórz ją na świeżym serwerze, a tabele się pojawią, podczas gdy każde GRANT będzie odwoływać się do roli, która nie istnieje. Twoja aplikacja połączy się z bazą, ale przy każdej operacji otrzyma błąd odmowy uprawnień.
Z rozszerzeniami jest tak samo. Jeśli twój schemat zależy od pgcrypto lub uuid-ossp, a środowisko docelowe ich nie ma, odtwarzanie zakończy się błędem w połowie, pozostawiając część tabel.
3. Flagi były nieprawidłowe dla odtwarzania, którego potrzebujesz
pg_dump tworzy różne artefakty zależnie od formatu, a pomyłka zwykle wychodzi na jaw dopiero pod presją:
- Plain SQL odtwarza się za pomocą
psqli jest czytelny dla człowieka. Nie można go odtwarzać wybiórczo, a w przypadku dużych baz danych jest powolny. - Custom format (
-Fc) odtwarza się za pomocąpg_restore, obsługuje równoległość i wybiórcze odtwarzanie. To właśnie tego formatu potrzebujesz w przypadku większych baz danych.
Wykonywanie kopii zapasowej w formacie plain, bo tak pokazano w tutorialu, a następnie odkrycie podczas incydentu, że nie można odtworzyć pojedynczej tabeli, to szczególny i całkowicie możliwy do uniknięcia rodzaj pechowego dnia.
4. Nie możesz jej odszyfrować
Jeśli kopie zapasowe są zaszyfrowane — a powinny być — klucz jest częścią kopii zapasowej. Klucz, który znajduje się wyłącznie na utraconej maszynie albo tylko w zmiennej środowiskowej niedziałającej usługi, jest kluczem, którego nie masz wtedy, gdy ma znaczenie.
Jak wygląda prawdziwa weryfikacja
Test nie polega na sprawdzeniu, „czy plik istnieje”. Odtwórz go w innym miejscu i zadaj mu pytanie.
# 1. Restore into a scratch database, not the live one
createdb verify_$(date +%Y%m%d)
pg_restore -d verify_$(date +%Y%m%d) --no-owner --no-privileges latest.dump
# 2. Ask it something only real data can answer
psql -d verify_$(date +%Y%m%d) -c "
select
(select count(*) from users) as users,
(select count(*) from orders) as orders,
(select max(created_at) from orders) as newest_order;
"
# 3. Drop it
dropdb verify_$(date +%Y%m%d)
Krok 2 jest sednem całego procesu. Odtwarzanie, które kończy się bez błędu, nadal nic nie mówi o tym, czy dane rzeczywiście tam są. Liczba wierszy i kontrola aktualności już tak.
Warto sprawdzić trzy rzeczy:
- Liczba wierszy jest właściwego rzędu wielkości. Nie musi być dokładna — dane się zmieniają — ale tabela, która miała 200 000 wierszy, a teraz ma ich 12, oznacza awarię.
- Najnowszy rekord jest aktualny. Jeśli najnowsze zamówienie w twojej „nocnej” kopii zapasowej pochodzi z marca, zadanie tworzenia kopii zatrzymało się w marcu.
- Aplikacja rzeczywiście może się połączyć. Skieruj instancję staging na odtworzoną bazę danych i wczytaj jedną stronę.
Rób to według harmonogramu, a nie przy okazji postanowienia
Realistyczna częstotliwość to raz w miesiącu, automatycznie, z wynikiem dostępnym w miejscu, na które zwrócisz uwagę. Przypomnienie w kalendarzu „przetestuj kopie zapasowe” to przypomnienie, które odłożysz.
Aby proces rzeczywiście działał, trzeba sprawić, by awaria była głośna: jeśli zapytanie weryfikacyjne zwróci mniej wierszy niż określony próg, powinno wysłać alert do odpowiedniej osoby tak samo, jak zrobiłby to błąd produkcyjny. System kopii zapasowych, który zawodzi po cichu, jest nie do odróżnienia od braku systemu kopii zapasowych — aż do chwili, gdy ma znaczenie.
Jak Dockup sobie z tym radzi
Trzy decyzje, z których każda jest wymierzona w konkretny opisany wyżej rodzaj awarii.
Kopie zapasowe trafiają gdzie indziej. Kopia zapasowa na tym samym dysku co baza danych nie jest kopią zapasową — to kopia, która zginie razem z dyskiem. Dockup przesyła kopie zapasowe baz danych bezpośrednio do object storage w miarę ich tworzenia, dzięki czemu plik nigdy nie zależy od hosta, na którym powstał.
Są szyfrowane, a klucza nie ma na maszynie. Kopie zapasowe są szyfrowane za pomocą AES-256-GCM podczas przesyłania. Z punktu widzenia odzyskiwania najważniejsze jest to, że klucz jest przechowywany przez platformę, a nie znajduje się w środowisku usługi, której kopia jest tworzona.
Kopia, która niczego nie utworzyła, nie jest zapisywana jako kopia zapasowa. To bezpośrednie rozwiązanie problemu pustego pliku: jeśli dump zakończy się z niezerowym kodem wyjścia albo utworzy zero bajtów, przesłany plik zostanie usunięty, a kopia zapasowa otrzyma status niepowodzenia. Nie otrzymujesz listy zielonych wpisów, wśród których jeden jest plikiem o rozmiarze 400 bajtów.
dockup db backup my-project/main-db --json # take one now
dockup db backups my-project/main-db --json # list them with sizes
Rozmiary na tej liście to najtańsza kontrola kondycji, jaką masz. Obserwuj ich trend.
Niewygodne pytanie
Jeśli twoja produkcyjna baza danych zostałaby zniszczona w ciągu najbliższych dziesięciu minut, ile czasu zajęłoby jej przywrócenie i ile danych byś utracił?
Jeśli nie potrafisz podać obu tych liczb, nie masz strategii tworzenia kopii zapasowych — masz pliki kopii zapasowych. Różnica sprowadza się wyłącznie do tego, czy ktoś kiedykolwiek wykonał odtwarzanie.
Najczęściej zadawane pytania
Jak często powinienem testować odtwarzanie? Raz w miesiącu to rozsądny domyślny wybór, najlepiej automatycznie, a nie ręcznie. Najważniejsze jest to, aby awaria była głośna, a nie to, żeby częstotliwość była wysoka.
Dlaczego odtwarzanie zakończyło się pomyślnie, ale nie utworzyło żadnych danych? Zwykle zrzut został wykonany dla nieprawidłowej bazy danych albo zakończył się w połowie, nadal zapisując plik. Porównuj rozmiary kopii w czasie — pusty zrzut jest oczywisty na wykresie rozmiaru i niewidoczny w kolumnie statusu.
Czy kopie zapasowe powinny być szyfrowane? Tak, a klucz musi znajdować się w miejscu, które przetrwa utratę maszyny. Zaszyfrowana kopia zapasowa, której klucz znajdował się na utraconym serwerze, nie nadaje się do odzyskania.
Czy snapshot jest tym samym co kopia zapasowa? Nie. Snapshot woluminu przechwytuje dysk, w tym stan bazy danych w danej chwili. Logical dump jest spójny z założenia. Większość zespołów chce mieć oba rozwiązania, ponieważ chronią przed różnymi rodzajami awarii.
