Czy tworzenie kopii zapasowych bazy danych MySQL w Git jest dobrym pomysłem?

57

Próbuję poprawić sytuację tworzenia kopii zapasowych mojej aplikacji. Mam aplikację Django i bazę danych MySQL. Przeczytałem artykuł sugerujący utworzenie kopii zapasowej bazy danych w Git.

Z jednej strony podoba mi się to, ponieważ pozwala zachować synchronizację kopii danych i kodu.

Ale Git jest przeznaczony do kodu, a nie do danych. W związku z tym wykona wiele dodatkowej pracy, różnicując zrzut MySQL przy każdym zatwierdzeniu, co nie jest tak naprawdę konieczne. Jeśli skompresuję plik przed zapisaniem, czy nadal będzie różnicował pliki?

(Plik zrzutu jest obecnie 100 MB nieskompresowany, 5,7 MB po skompresowaniu.)

Edycja: definicje kodu i schematu bazy danych są już w Git, to naprawdę dane, których tworzenia kopii zapasowej się obawiam.

wobbily_col
źródło
13
Jeśli Twoja firma ma dział IT, powinien się tym zająć.
Michael Hampton
1
czy aplikacja jest częścią danych lub co jest tworzone przez aplikację?
Winston Ewert
1
Git będzie próbował różnicować wszystkie pliki podczas uruchamiania git gc(lub jego bazy git repack; git, zgodnie z konfigurowalnymi ustawieniami, czasami uruchamia go automatycznie). Zawsze również je opróżni , więc może być lepiej przechowywać je bez kompresji.
Jan Hudec
1
Co to jest baza danych: czy jest to baza produkcyjna czy programistyczna?
el.pescado
6
viget.com/extend/backup-your-database-in-git , jest „starszym programistą”.
wobbily_col

Odpowiedzi:

101

Zanim stracisz jakiekolwiek dane, pozwól mi spróbować przedstawić perspektywę sysadmin do tego pytania.

Istnieje tylko jeden powód, dla którego tworzymy kopie zapasowe: aby umożliwić przywracanie, gdy coś pójdzie nie tak, jak zawsze . Jako taki, właściwy system tworzenia kopii zapasowych ma wymagania znacznie wykraczające poza to, co git może rozsądnie obsłużyć.

Oto niektóre problemy, które mogę przewidzieć podczas próby wykonania kopii zapasowej bazy danych w git:

  • Repozytorium powiększy się dramatycznie z każdą „kopią zapasową”. Ponieważ git przechowuje całe obiekty (aczkolwiek skompresowane), a następnie różnicuje je później (np. Po uruchomieniu git gc) i zachowuje historię na zawsze , będziesz mieć bardzo dużą ilość przechowywanych danych, których tak naprawdę nie potrzebujesz ani nawet nie chcesz. Może być konieczne ograniczenie ilości lub okresu przechowywania kopii zapasowych, aby zrobić miejsce na dysku lub z powodów prawnych, ale trudno jest usunąć stare wersje z repozytorium git bez dużych szkód ubocznych.
  • Przywracanie jest ograniczone do punktów w czasie przechowywanych w repozytorium, a ponieważ dane są tak duże, cofanie się o więcej niż trywialny czas może być powolne. Zaprojektowany w tym celu system tworzenia kopii zapasowych ogranicza ilość przechowywanych danych, potencjalnie zapewniając większą szczegółowość, i zapewnia szybsze przywracanie, zmniejszając przestoje w przypadku awarii. Rozwiązania do tworzenia kopii zapasowych obsługujące bazy danych ( przykład ) mogą również zapewniać ciągłe tworzenie kopii zapasowych, zapewniając, że nie zostanie utracona ani jedna transakcja.
  • Zatwierdzenia prawdopodobnie będą również powolne i będą spowalniać w miarę wzrostu bazy danych. Pamiętaj, że git jest zasadniczo magazynem danych klucz-wartość odwzorowanym na system plików , a zatem podlega charakterystyce wydajności bazowego systemu plików. Jest możliwe, że ten czas w końcu przekroczy interwał tworzenia kopii zapasowej, i w tym momencie nie będzie już można spełnić umowy SLA. Odpowiednie systemy tworzenia kopii zapasowych również zajmują więcej czasu, gdy dane rosną, ale nie aż tak dramatycznie, ponieważ automatycznie zarządzają własnym rozmiarem na podstawie skonfigurowanych przez Ciebie zasad przechowywania.

Pomimo faktu, że najwyraźniej istnieje kilka interesujących rzeczy, które możesz zrobić ze zrzutem bazy danych, jeśli umieścisz go w git, ogólnie nie mogę go polecić do przechowywania kopii zapasowych. Zwłaszcza, że systemy tworzenia kopii zapasowych są szeroko dostępne (a wiele z nich jest nawet open source) i działają znacznie lepiej, zapewniając bezpieczeństwo danych i umożliwiając ich jak najszybsze odzyskanie.

Michael Hampton
źródło
To najlepsza odpowiedź, ponieważ Michael omówił problemy ze spójnością. W zależności od wielkości i wykorzystania bazy danych migawka nie może w sposób wiarygodny odtworzyć danych w danym momencie i prawdopodobnie wystąpią problemy z ograniczeniami. Replikacja może być czymś, w co chcesz zajrzeć - dev.mysql.com/doc/refman/5.0/en/replication.html
Aaron Newton
4
To nie jest najlepsza odpowiedź, to jedyna odpowiedź. Zasadniczo jesteś programistą, więc kopie zapasowe nie są Twoją firmą; ktoś inny (lub powinien) już się nimi opiekuje, a jeśli zaczniesz się angażować, możesz zakłócać działanie systemu, który już działa. Kopie zapasowe tych skrzynek powinny już być tworzone, więc będziesz mieć kopię zapasową, własną kopię zapasową i kopię zapasową własnej kopii zapasowej - wszystkie o coraz większym rozmiarze. To tylko szalone. Plus: jesteś programistą: dlaczego (prawdopodobnie) zbliżasz się do pudeł produkcyjnych?
Maximus Minimus
2
@JimmyShelter Istnieje szkoła myślenia, że ​​DevOps oznacza nie tyle, że Dev i Ops ściśle ze sobą współpracują, ale że Dev faktycznie robi Ops. Zwykle nie działa dobrze, ale to nie powstrzymuje ludzi przed próbowaniem.
Michael Hampton
To powinna być zaakceptowana odpowiedź. Wyjaśnia jasno wymagania i cel systemu kopii zapasowych, a następnie pokazuje, jak git nie pasuje. Dodatkowe punkty bonusowe za omówienie spójności i wydajności.
Gabriel Bauman
Pragnę zauważyć, że opublikowałem odpowiedź, zakładając, że PO nie ma żadnego zespołu operacyjnego, który mógłby poradzić sobie z tym problemem. Zgadzam się z tobą, że tego rodzaju zadanie najlepiej pozostawić tym, którzy faktycznie obsługują system i znają się na tym. Ale są sytuacje, w których musisz założyć kapelusz, który nie jest dokładnie twój, i uważam, że w tej sytuacji lepiej jest nauczyć się najlepszych praktyk, niż po prostu wymyślić własne wymyślone rozwiązanie. Muszę powiedzieć, że uważam również twoją odpowiedź za bardzo pouczającą!
logc
39

Moje dwa centy: nie sądzę, że to dobry pomysł. GIT robi coś podobnego „Zapisywanie migawek z zestawu plików w różnych punktach w czasie”, dzięki czemu można idealnie wykorzystać GIT na coś takiego, ale to nie znaczy, że powinniśmy . GIT został zaprojektowany do przechowywania kodu źródłowego, więc straciłbyś większość jego funkcjonalności, a ty handlowałbyś dużą wydajnością za odrobinę wygody.

Załóżmy, że głównym powodem, dla którego myślisz o tym, jest „zsynchronizowanie kopii danych i kodu”, a to oznacza, że ​​martwisz się, że wersja 2.0 twojego kodu potrzebuje innego schematu bazy danych niż wersja 1.0 . Prostszym rozwiązaniem byłoby przechowywanie schematu bazy danych, jako zestawu skryptów SQL z CREATEinstrukcjami, wzdłuż kodu źródłowego w repozytorium Git. Następnie częścią procedury instalacji byłoby wykonanie tych skryptów na wcześniej zainstalowanym serwerze bazy danych.

Rzeczywista zawartość tych CREATEtabel -d nie ma nic wspólnego z wersją kodu źródłowego. Wyobraź sobie, że instalujesz oprogramowanie w wersji 1.0 na serwerze A i serwerze B, które są używane w różnych firmach przez różne zespoły. Po kilku tygodniach zawartość tabel będzie zupełnie inna, mimo że schematy są dokładnie takie same.

Ponieważ chcesz wykonać kopię zapasową zawartości bazy danych, sugeruję, abyś użył skryptu kopii zapasowej, który otacza zrzut kopii bieżącą wersją oprogramowania, do którego zrzut należy. Skrypt powinien znajdować się w repozytorium GIT (aby miał dostęp do ciągu wersji kodu źródłowego), ale same zrzuty nie należą do systemu kontroli wersji.

EDYCJA :

Po przeczytaniu oryginalnego postu, który uzasadniał pytanie , uważam to za jeszcze bardziej wątpliwy pomysł. Kluczową kwestią jest to, że mysqldumppolecenie przekształca bieżący stan DB w szereg INSERTinstrukcji SQL , a GIT może je różnicować, aby uzyskać tylko zaktualizowane wiersze tabeli.

mysqldumpCzęść jest dobra, ponieważ jest to jedna z metod tworzenia kopii zapasowych wymienionych w dokumentacji MySQL. Część GIT polega na tym, że autor nie zauważa, że ​​serwery bazy danych przechowują dziennik transakcji w celu odzyskiwania po awarii, w tym MySQL . To za pomocą tego dziennika , nie GIT, że należy tworzyć przyrostowe kopie zapasowe w bazie danych. Ma to przede wszystkim tę zaletę, że można obracać lub opróżniać dzienniki po odzyskaniu, zamiast nadmuchiwania repozytorium GIT w nieskończoność i poza nią ...

logc
źródło
2
Nie jestem pewien, czy widzę sensu w przechowywaniu schematu bazy danych bez danych w kontroli wersji. Dane są najważniejsze i właśnie to chcę wykonać kopię zapasową. Podoba mi się jednak pomysł oznaczenia kopii zapasowej bazy danych aktualną wersją oprogramowania. Spróbuję zaimplementować coś takiego.
wobbily_col
10
Punktem przechowywania schematu bez danych jest to, że zaraz po instalacji oprogramowanie powinno być „gotowe do użycia”. Jeśli jest to wiki, powinno być gotowe do rozpoczęcia tworzenia stron wiki i pisania na nich czegoś. Jeśli zainstalujesz schemat i zawartość, twoja wiki jest już wypełniona X stronami wiki po instalacji ... To nie jest dokładnie „instalacja systemu wiki, aby napisać naszą zawartość”, ale „kopiowanie wiki gdzieś, aby ją przeczytać” .
logc
3
Dobrym pomysłem może być zmodyfikowanie pytania w zależności od faktycznej sytuacji, w której się znajdujesz. Nawet jeśli nie możesz opublikować wszystkich szczegółów, ważne jest, aby stwierdzić, że potrzebujesz dużej ilości danych, aby wyglądały na niezmodyfikowane w każdej instalacji, lub jest jedna instalacja ...
logc
2
@wobbily_col Nietekstowy format binarny ma ograniczoną wartość w kontekście kontroli źródła. Nie możesz go rozróżnić , nie możesz rozgałęzić / scalić itp. Tak więc, chociaż na pewno MOŻESZ użyć git do przechowywania DB, większość ludzi woli pisać skrypty zarówno w strukturze DB, jak i niezbędnych danych. Jest to kompromis między odrobiną pracy, ale zapewnieniem powyższej listy funkcji. Musisz zastanowić się, czy jest to dobry pomysł na twoje rozwiązanie. W przeciwnym razie prawdopodobnie GIT może przechowywać DB bezpośrednio, po prostu nie jest to najlepsze dopasowanie do zadania.
Daniel B
3
@RaduMurzea: Myślę, że to kwestia zasad. System kontroli wersji został zaprojektowany do zarządzania kodem źródłowym, a nie plikami binarnymi, to wszystko. To nie jest kwestia rozmiaru. Nie, zrzuty bazy danych nie powinny być rejestrowane w repozytorium, podobnie jak filmy szkoleniowe również nie powinny być rejestrowane. Ale nikt cię nie powstrzymuje. :)
logc
7

Osobiście nie sądzę, że dobrym pomysłem jest używanie systemu wersji kontroli źródła do przechowywania plików kopii zapasowych, ponieważ kontrola wersji GIT jest przeznaczona dla plików danych, a nie dla plików binarnych lub plików zrzutu, takich jak plik zrzutu kopii zapasowej MySQL. Fakt, że możesz to zrobić, nie oznacza automatycznie, że powinieneś to zrobić. Co więcej, Twoje repozytorium, biorąc pod uwagę nową kopię zapasową bazy danych dla każdego nowego zatwierdzenia, dramatycznie się powiększy, wykorzystując dużo miejsca na dysku twardym, co wpłynie na wydajność GIT, co spowoduje powolny system kontroli źródła. Dla mnie dobrze jest wykonać strategię tworzenia kopii zapasowych i zawsze mieć gotowy plik kopii zapasowej, gdy trzeba przywrócić bazę danych, gdy coś w kodzie pójdzie nie tak, ale narzędzia kontroli źródła nie są przeznaczone do przechowywania danych binarnych.

Z tych powodów nie widzę żadnego narzędzia do przechowywania plików kopii zapasowej na dzień 1 i na dzień 2, a następnie widzę różnice między dwoma plikami kopii zapasowej. Będzie to wymagało dużo dodatkowej i bezużytecznej pracy. Zamiast używać GIT do przechowywania kopii zapasowych bazy danych podczas zatwierdzania nowego kodu, przechowuj kopie zapasowe bazy danych w innej ścieżce, oddzielone datą i godziną, i wstaw w kodzie odniesienie do nowych kopii zapasowych bazy danych utworzonych dla każdej wersji, używając tagów, jak ktoś już zasugerował.

Moja ostatnia uwaga na temat kopii zapasowych bazy danych i GIT: Administrator bazy danych, gdy musi przywrócić bazę danych, ponieważ niektóre dane zostały utracone, nie musi sprawdzać różnic między plikiem kopii zapasowej dla pierwszego dnia a plikiem kopii zapasowej dla drugiego dnia, musi tylko wiedzieć, która jest ostatni plik kopii zapasowej, który pozwoli mu przywrócić bazę danych, bez błędów i utraty danych, zmniejszając przestoje. W rzeczywistości zadaniem administratora bazy danych jest jak najszybsze udostępnienie danych do odzyskania, gdy system z jakichś powodów ulegnie awarii. Jeśli przechowujesz kopie zapasowe bazy danych w GIT, powiązane ze swoimi zatwierdzeniami, nie pozwalasz administratorowi bazy danych na szybkie przywracanie danych, ponieważ kopie zapasowe są ograniczone do punktów w czasie przechowywanych w repozytorium GIT i skracają przestoje systemu,

Następnie nie zalecam przechowywania kopii zapasowych za pomocą GIT, zamiast tego używaj dobrego oprogramowania do tworzenia kopii zapasowych (jest ich tutaj kilka ), które zapewni większą szczegółowość i pozwoli ci zachować bezpieczeństwo danych odzyskiwanie danych proste i szybkie w przypadku katastrof.

Alberto Solano
źródło
Może downvoter wyjaśni, dlaczego on / ona przegłosował ...
Alberto Solano
1
Nie downvoter, ale myślę, że takie podejście wprowadza zawsze obecny konflikt scalania, który nie sprzyja szczególnie przepływowi pracy często rozgałęzionego, często preferowanemu przez większość użytkowników git.
Daniel B
@DanielB Proponuję nie używać systemu kontroli wersji do przechowywania plików kopii zapasowych bazy danych. Myślę, że problem z kopią zapasową bazy danych można łatwo rozwiązać bez użycia systemu kontroli wersji. Systemy kontroli wersji (GIT, TFS, SVN itd.) Są przeznaczone do oprogramowania, a nie do zrzutów plików lub kopii zapasowych baz danych lub do przechowywania danych (istnieje na to wiele rozwiązań).
Alberto Solano
Myślę, że większość użytkowników czyta kilka pierwszych zdań i głosuje negatywnie, ponieważ wydaje się, że będziesz mówić, że można z niego korzystać.
1
@AlbertoSolano Widzę; ale czytając pytanie („czy mogę wykonać kopię zapasową mojej bazy danych w GIT?”), a następnie pierwsze zdanie („dobrze jest przechowywać plik kopii zapasowej ...”), wygląda na to, że mówisz coś przeciwnego. Reszta odpowiedzi wydaje się mówić, że nie ma jej ani tu, ani tam, podczas gdy podejrzewam, że większość ludzi uważa, że ​​czeka na nią wrak pociągu.
Daniel B
1

Nie powinieneś przechowywać danych binarnych w Git - szczególnie w bazie danych.
Zmiany kodu i zmiany DML bazy danych to zupełnie inne rzeczy.

MySQL i Oracle mogą zapisywać dzienniki archiwalne w celu przywrócenia do dowolnego momentu w czasie. Po prostu wykonaj kopię zapasową tych dzienników w bezpiecznym miejscu i wszystko będzie dobrze.

Używanie Git do tworzenia kopii zapasowych tych „dzienników archiwów” nie ma sensu. Dzienniki archiwów w środowisku produkcyjnym są dość ciężkie i powinny być usuwane po regularnych pełnych kopiach zapasowych. Również bezużyteczne jest umieszczanie ich w git - są one już w pewnym sensie repozytorium.

Jehy
źródło
1
dlaczego nie należy używać Git do tworzenia kopii zapasowych tych „dzienników archiwów” utworzonych przez MySQL?
komar
1
Tylko dlatego, że to nie ma sensu. Dzienniki archiwów w środowisku produkcyjnym są dość ciężkie i powinny być usuwane po regularnych pełnych kopiach zapasowych. Również bezużyteczne jest umieszczanie ich w git - są one już w pewnym sensie repozytorium. Michael Hampton daje całkiem dobrą odpowiedź na ten temat (na tej stronie).
Jehy
1
Po co zawracać sobie głowę obracaniem dzienników, jeśli zamierzasz przechowywać kopię wszystkiego w git? Równie dobrze może zachować tylko jeden plik dziennika potwora.
wobbily_col