Jak zaktualizować produkcyjny schemat bazy danych / schematu bazy danych bez powodowania przestojów?

42

Jakie są techniki aktualizacji schematu bazy / bazy danych serwera produkcyjnego bez powodowania przestojów?

Olivier Lalonde
źródło
1
Dobre pytanie, ponieważ widzę, że tak wielu ludzi przeoczyło to. Czas to pieniądz, a przestoje nigdy nie wyglądają dobrze dla użytkowników końcowych, niezależnie od tego, jak uzasadniony jest powód.
Dan McGrath
@ Dan McGrath: przypuszczam, że faktycznie możesz mieć przestoje, pracuję dla systemu, który jest (normalnie) wyłączony tylko 4 razy w roku (przerwa kwartalna) i maksymalnie przez 15 minut za każdym razem (w tym czasie ruch jest w kolejce). .. zmiany w bazie danych są dokładnie sprawdzane :)
Matthieu M.
2
To byłoby świetne pytanie dla dba.stackexchange.com , który przejdzie do publicznej wersji beta za kilka godzin.
Larry Coleman,

Odpowiedzi:

20

Ogólnie rzecz biorąc, strony, nad którymi pracowałem, które miały tego rodzaju wymagania, znajdowały się za modułami równoważenia obciążenia lub miały osobne lokalizacje przełączania awaryjnego. W tym przykładzie założę, że masz jeden moduł równoważenia obciążenia, 2 serwery WWW (A i B) i 2 serwery bazy danych (M i N - zwykle serwery DB są połączone poprzez logshipping - przynajmniej w świecie SQL Server ).

  1. Serwer WWW A ma zostać odłączony od modułu równoważenia obciążenia (więc cały ruch przychodzący trafia do B).
  2. Wysyłanie dziennika jest zatrzymane (DB Server M zostanie najpierw zaktualizowany).
  3. Zaktualizuj serwer WWW A. Wskaż konfigurację na DB Server M.
  4. Przetestuj i sprawdź, czy aktualizacja zadziałała (zwykle ludzie bezpośrednio uderzają w adres IP).
  5. Ustaw moduł równoważenia obciążenia tak, aby istniejące sesje były kontynuowane do B. Nowe sesje przejdź do A.
  6. Poczekaj, aż wszystkie sesje w B wygasną (może to potrwać pół godziny lub dłużej, zwykle obserwujemy ruch i planujemy 1 godzinę przerwy).
  7. Zaktualizuj B i N.
  8. Przetestuj i sprawdź, czy aktualizacja zadziałała.
  9. Ponownie skonfiguruj wysyłanie dziennika i sprawdź, czy działa.
  10. Ustaw moduł równoważenia obciążenia na normalną pracę.

W bardzo skomplikowanych aplikacjach internetowych czynności opisane w punktach 1-5 mogą zająć całą noc i być 50-stronicowym arkuszem kalkulacyjnym Excel z czasami i numerami alarmowymi. W takich sytuacjach aktualizacja połowy systemu planowana jest na 18:00 do 6:00, pozostawiając system dostępny dla użytkowników. Obsługa aktualizacji strony DR jest zwykle planowana na następną noc - mam tylko nadzieję, że pierwszego dnia nic nie zepsuje.

Tam, gdzie wymagany jest czas działania, łatki są najpierw testowane w środowisku kontroli jakości, którym idealnie jest ten sam sprzęt co produkcja. Jeśli nie wykazują zakłóceń, można je stosować zgodnie z regularnym harmonogramem, zwykle w weekend.

Tangurena
źródło
7
Jak proponujesz scalenie nowych danych z DB M i DB N? Obaj będą mieli nowe, zaktualizowane i usunięte rekordy, których drugi nie ma.
sixtyfootersdude
@Tangurena, czy możesz odpowiedzieć na powyższy komentarz?
sino,
9

W typowych bazach danych (na przykład Oracle) możliwa jest zmiana schematu bazy danych przy jednoczesnym równoległym uruchamianiu zapytań. Wymaga to jednak pewnego planowania.

Są pewne ograniczenia dotyczące zastosowania zmiany:

  • powinien działać z istniejącym kodem, co oznacza, że ​​kod powinien obsługiwać zarówno starą, jak i nową wersję schematu
  • nie powinno to powodować takiego obciążenia bazy danych, że transakcje by się zatrzymały (patrzę na ciebie CREATE INDEX)
  • nie powinno to spowodować utraty danych (nie można upuścić i ponownie utworzyć tabeli)

Aby schemat był kompatybilny z poprzednimi wersjami, zwykle możesz DODAĆ lub MODYFIKOWAĆ kolumnę, możesz ZROBIĆ coś tylko wtedy, gdy istniejący kod już go nie używa.

Jeśli Twój kod nie może obsłużyć zmiany w sposób transparentny, zmień kod przed zmianą bazy danych.

Prosta rada dotycząca planowania z wyprzedzeniem: zawsze podawaj nazwy kolumn we wnioskach DB (nie używaj SELECT * FROM). W ten sposób nie będziesz wyświetlać nowych kolumn w starych żądaniach.

Matthieu M.
źródło
1
W rzeczywistości, dla planowania z wyprzedzeniem i możliwości dostosowania, wybranie * z jest nieskończenie lepsze niż ręczne wyświetlanie kolumn. Użycie wyraźnych nazw kolumn w większości przypadków powoduje duże zadłużenie techniczne. Jeśli kod łamie się z nowych kolumn, kod jest już zepsuty.
Morg.
@Morg .: Nie bardzo. Ze względów bezpieczeństwa należy użyć zmiennych powiązania, które w ramach, których używam (przynajmniej), wymagają podania zmiennych do zapisu, i musi być dokładnie tyle zmiennych, ile jest kolumn wyjściowych, co select *oznacza, że ​​kod zepsuje się, jeśli dodawana jest nowa kolumna (z powodu braku zmiennej, w której można by ją zapisać). Oczywiście może to wynikać z używania silnie napisanego języka.
Matthieu M.,
Tak, naprawdę, nie ma dodatkowego bezpieczeństwa w unikaniu wyboru *. Nie ma to nic wspólnego z silnie pisanymi językami i wszystko z bardzo złym designem. Jeśli Twój framework nie może płynnie obsłużyć zmian, jest to bezużyteczne. Kiedy zmieniam kolumnę, moja aplikacja nigdy nie przestaje działać. Kiedy to zrobisz, psuje się. Nie sądzę, aby było pytanie, które z nich jest bardziej niezawodne lub bezpieczne.
Morg.
@Morg .: Nie rozumiem, jak select *jest bardziej niezawodny i bezpieczny. Jeśli kiedyś tak było, select one, two from ...wtedy używałeś tylko onei two; jeśli thirdzostanie dodany do tabeli, nie ma dla niego zastosowania (tutaj), więc nie ma powodu, aby go odzyskać. A jeśli musisz go nagle użyć, zmodyfikujesz kod, aby w tym momencie równie dobrze zmodyfikować zapytanie!
Matthieu M.,
@Morg .: Wygląda na to, że rozmawiamy obok siebie, prawdopodobnie dlatego, że nasze doświadczenia się różnią. Pracuję nad produktami, w których wydajność jest najważniejszą własnością, a to oznacza, że selectmuszą być tak selektywne, jak to możliwe (i objęte indeksem), w przeciwnym razie jestem toast (nawet przed obowiązkowym dołączeniem). Przykro mi to mówić, ale podejście, które opisujesz, było całkowitą porażką tych produktów.
Matthieu M.,
5

Nie wszystkie systemy mogą, należy je skonfigurować w sposób, który je obsługuje.

Na przykład jeden z naszych głównych systemów, który pomogłem zaktualizować kilka lat temu, powinien być dostępny 24/7. Składał się z wielu warstw, w tym czystej warstwy komunikacyjnej między zewnętrzną warstwą interfejsu użytkownika a warstwą biznesową. Ze względu na sposób kodowania warstwy komunikacyjnej wszelkie przyszłe zmiany w warstwie biznesowej lub schemacie DB można wdrożyć bez rzeczywistej awarii. W najgorszym przypadku użytkownik doświadczyłby 10-30 sekundowej przerwy, gdy zmiany zostały wprowadzone.

Gdyby zmiany były czysto kodowymi zmianami w warstwie biznesowej, mogłyby zostać umieszczone w kolejce i „włączone” z opóźnieniem tylko o milisekundy.

Może to zrobić, ponieważ:

  • Warstwa komunikacyjna może przechowywać wiadomości. Pozwoliło nam to na faktyczne wyłączenie dowolnego poziomu niż warstwa interfejsu użytkownika bez konieczności obniżania interfejsu użytkownika.
  • Warstwa biznesowa obsługiwana przez MVDB o nazwie UniData . Przechowuje cały kod w pamięci. Po skompilowaniu kodu można użyć polecenia, aby wymusić nowy kod obiektu w pamięci, zastępując stary.

Inne techniki obejmują replikację transakcji do innego serwera lustrzanego istniejącego systemu. Stosując aktualizację do jednej, przełączając i odtwarzając wszystkie transakcje wykonane między aktualizacją a przełączeniem. YMMV w zależności od systemu.

Dan McGrath
źródło
1

Oto inna perspektywa ze świata systemów wbudowanych baz danych i systemów wbudowanych. Systemy wbudowane obejmują różne urządzenia infrastruktury sieci / infrastruktury telekomunikacyjnej, aw tej dziedzinie często mówią o 99,999% (pięciu 9) przestojów.

My (McObject) jesteśmy dostawcą rodziny produktów wbudowanych baz danych eXtremeDB, w tym wysokiej dostępności eXtremeDB.

Po pierwsze, zrozum, że „osadzona baza danych” oznacza, że ​​system bazy danych jest biblioteką skompilowaną i połączoną z kodem aplikacji; w tym sensie jest „osadzony” w twojej aplikacji.

Dzięki eXtremeDB High Availability istnieje instancja MASTER aplikacji (która może być jednym lub kilkoma procesami) i jedna lub więcej instancji REPLICA aplikacji. Gdy replika ustanawia połączenie z serwerem głównym, otrzymuje kopię bazy danych jednostki głównej w procesie zwanym „synchronizacją początkową”. Można to zrobić, gdy aplikacja główna kontynuuje pracę. Po zsynchronizowaniu otrzymuje transakcje wzorca poprzez replikację. Dlatego replika zawsze ma bieżące dane i może przejąć (poprzez proces zwany przełączaniem awaryjnym) w przypadku awarii wzorca.

Jedną z cech początkowej synchronizacji jest „ewolucja schematu binarnego”. Mówiąc wprost, oznacza to, że proces zapełniania bazy danych repliki uwzględni różnice między schematem bazy danych repliki a schematem bazy danych wzorca.

W praktyce oznacza to, że możesz zbudować nowszą wersję aplikacji (z nowymi / usuniętymi tabelami, nowymi / usuniętymi / zmienionymi polami, nowymi / usuniętymi indeksami), dołączyć tę nową wersję aplikacji do wzorca, a następnie spowodować, że nowsza replika, aby stać się nowym masterem (tzn. wymusić przełączenie awaryjne do nowej repliki, aby stała się master, a stary master sam się wyłączył). Voila, migrowałeś aplikację z wersji N do N + 1, nie zakłócając dostępności twojego systemu. Teraz możesz przejść na aktualizację starego wzorca i wszelkich innych replik do wersji N + 1.


źródło