Czy można uruchamiać aplikacje Hibernacji skonfigurowane hbm2ddl.auto=update
do aktualizowania schematu bazy danych w środowisku produkcyjnym?
Czy można uruchamiać aplikacje Hibernacji skonfigurowane hbm2ddl.auto=update
do aktualizowania schematu bazy danych w środowisku produkcyjnym?
Odpowiedzi:
Nie, to niebezpieczne.
Pomimo najlepszych starań zespołu Hibernacja, po prostu nie możesz polegać na automatycznych aktualizacjach w produkcji . Napisz własne łatki, przejrzyj je za pomocą DBA, przetestuj je, a następnie zastosuj ręcznie.
Teoretycznie, jeśli aktualizacja hbm2ddl działała w fazie rozwoju, powinna również działać w fazie produkcyjnej. Ale w rzeczywistości nie zawsze tak jest.
Nawet jeśli zadziałało OK, może nie być optymalne. DBA płaci się tyle z jakiegoś powodu.
Robimy to w produkcji, chociaż z aplikacją, która nie jest krytyczna dla misji i bez wysoko płatnych DBA dla personelu. To tylko jeden mniej ręczny proces, który jest obarczony ludzkim błędem - aplikacja może wykryć różnicę i zrobić właściwą rzecz, a także prawdopodobnie przetestowałeś ją w różnych środowiskach programistycznych i testowych.
Jedno zastrzeżenie - w środowisku klastrowym możesz tego uniknąć, ponieważ wiele aplikacji może jednocześnie wyświetlać i modyfikować schemat, co może być złe. Lub zastosuj jakiś mechanizm, w którym tylko jedna instancja może zaktualizować schemat.
Twórcy Hibernacji odradzają to w środowisku produkcyjnym w swojej książce „Java Persistence with Hibernate” :
OSTRZEŻENIE: Widzieliśmy użytkowników Hibernacji próbujących użyć SchemaUpdate do automatycznej aktualizacji schematu produkcyjnej bazy danych. Może to szybko zakończyć się katastrofą i nie pozwoli na to DBA.
Sprawdź LiquiBase XML, aby uzyskać dziennik zmian aktualizacji. Nigdy nie korzystałem z niego aż do tego roku, ale odkryłem, że bardzo łatwo jest się nauczyć i sprawić, że kontrola wersji DB / migracja / zarządzanie zmianami jest bardzo niezawodna. Pracuję nad projektem Groovy / Grails, a Grails używa Hibernacji pod spodem dla wszystkich swoich ORM (zwanych „GORM”). Używamy Liquibase do zarządzania wszystkimi zmianami schematu SQL, co robimy dość często, ponieważ nasza aplikacja ewoluuje z nowymi funkcjami.
Zasadniczo przechowujesz plik XML zestawów zmian, które dodajesz w miarę ewolucji aplikacji. Ten plik jest przechowywany w git (lub cokolwiek, którego używasz) z resztą projektu. Kiedy twoja aplikacja jest wdrożona, Liquibase sprawdza swoją tabelę dzienników zmian w DB, z którą się łączysz, aby wiedział, co zostało już zastosowane, a następnie inteligentnie stosuje tylko te zestawy zmian, które nie zostały jeszcze zastosowane z pliku. Działa absolutnie świetnie w praktyce, a jeśli użyjesz go do wszystkich zmian schematu, możesz być w 100% pewien, że kod, który pobierasz i wdrażasz, zawsze będzie w stanie połączyć się z w pełni kompatybilnym schematem bazy danych.
Niesamowite jest to, że mogę wziąć całkowicie pustą bazę danych mysql na moim laptopie, odpalić aplikację i od razu skonfigurować dla mnie schemat. Ułatwia także testowanie zmian schematu przez zastosowanie ich najpierw do lokalnego dewelopera lub tymczasowej bazy danych.
Najłatwiejszym sposobem na rozpoczęcie jest prawdopodobnie zabranie istniejącej bazy danych, a następnie użycie Liquibase do wygenerowania początkowego pliku baseline.xml. Następnie w przyszłości możesz po prostu do niego dołączyć i zezwolić Liquase na zarządzanie zmianami schematu.
hbm2ddl.auto=update
, aby twoje mapowania Class / DB były sprawdzane i abyś miał pełną kontrolę nad tworzeniem DB poprzez Liquibase. Co myślisz?
validate
Głosowałbym na nie. Hibernacja wydaje się nie rozumieć, kiedy zmieniły się typy danych dla kolumn. Przykłady (przy użyciu MySQL):
String with @Column(length=50) ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)
@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed
Prawdopodobnie istnieją też inne przykłady, takie jak zwiększenie długości kolumny String o ponad 255 i przekonwertowanie jej na tekst, średni tekst itp.
To prawda, nie sądzę, aby naprawdę istniał sposób na „konwersję typów danych” bez tworzenia nowej kolumny, kopiowania danych i niszczenia starej kolumny. Ale w chwili, gdy baza danych ma kolumny, które nie odzwierciedlają obecnego mapowania Hibernacji, żyjesz bardzo niebezpiecznie ...
Flyway to dobra opcja na rozwiązanie tego problemu:
@Column(length = 45)
na @Column(length = 255)
. Może sprawdzić, czy Hibernacja 4.3.6. Finał poprawnie zaktualizował schemat bazy danych za pomocą hbm2ddl.auto=update
. (Należy wspomnieć, że w bazie danych nie ma obecnie żadnych danych - tylko jej struktura).
Hibernacja musi umieścić oświadczenie o nieużywaniu automatycznych aktualizacji w prod, aby zakryć się, gdy ludzie, którzy nie wiedzą, co robią, używają go w sytuacjach, w których nie należy go używać.
Przyznaję, że sytuacje, w których nie należy go używać, znacznie przewyższają liczbę przypadków, w których jest w porządku.
Używałem go od lat do wielu różnych projektów i nigdy nie miałem ani jednego problemu. To nie jest kiepska odpowiedź i nie jest to kodowanie kowboja. To fakt historyczny.
Osoba, która mówi „nigdy nie rób tego w produkcji”, myśli o określonym zestawie wdrożeń produkcyjnych, a mianowicie tych, które zna (jego firma, branża itp.).
Wszechświat „wdrożeń produkcyjnych” jest ogromny i zróżnicowany.
Doświadczony programista Hibernacja dokładnie wie, co DDL będzie wynikało z danej konfiguracji mapowania. Dopóki testujesz i potwierdzasz, że to, czego oczekujesz, kończy się w DDL (w dev, qa, inscenizacji itp.), Wszystko jest w porządku.
Gdy dodajesz wiele funkcji, automatyczne aktualizacje schematów mogą oszczędzić czas.
Lista rzeczy, których automatyczne aktualizacje nie będą obsługiwane, jest nieskończona, ale niektóre przykłady to migracja danych, dodawanie niepustych kolumn, zmiany nazw kolumn itp.
Musisz także zachować ostrożność w środowiskach klastrowych.
Ale z drugiej strony, jeśli znałbyś wszystkie te rzeczy, nie zadawałbyś tego pytania. Hmm . . OK, jeśli zadajesz to pytanie, powinieneś poczekać, aż będziesz mieć dużo doświadczenia z Hibernacją i automatycznymi aktualizacjami schematu, zanim pomyślisz o użyciu go w prod.
Jak wyjaśniłem w tym artykule , nie jest dobrym pomysłem stosowanie hbm2ddl.auto
w produkcji.
Jedynym sposobem zarządzania schematem bazy danych jest użycie przyrostowych skryptów migracji, ponieważ:
Nawet Podręcznik użytkownika Hibernacji zaleca unikanie używania tego hbm2ddl
narzędzia w środowiskach produkcyjnych.
SchemaExport
jak pokazano w tym przypadku testowym .
Robimy to w projekcie trwającym od miesięcy i nigdy wcześniej nie mieliśmy problemu. Pamiętaj o 2 składnikach potrzebnych do tego przepisu:
Zaprojektuj model obiektowy przy użyciu podejścia zgodnego z poprzednimi wersjami, czyli nieaktualnych obiektów i atrybutów zamiast ich usuwania / modyfikowania. Oznacza to, że jeśli chcesz zmienić nazwę obiektu lub atrybutu, pozostaw stary bez zmian, dodaj nowy i napisz jakiś skrypt migracyjny. Jeśli musisz zmienić powiązanie między obiektami, jeśli już jesteś w produkcji, oznacza to, że twój projekt był w pierwszej kolejności niewłaściwy, więc spróbuj wymyślić nowy sposób wyrażenia nowej relacji, bez wpływu na stare dane.
Zawsze wykonuj kopię zapasową bazy danych przed wdrożeniem.
Mam wrażenie - po przeczytaniu tego postu - 90% osób biorących udział w tej dyskusji jest przerażonych samą myślą o zastosowaniu takich automatyzacji w środowisku produkcyjnym. Niektórzy rzucają piłkę w DBA. Zastanów się jednak, że nie wszystkie środowiska produkcyjne zapewnią DBA i niewiele zespołów programistów jest w stanie sobie na to pozwolić (przynajmniej w przypadku średnich projektów). Jeśli więc mówimy o drużynach, w których wszyscy muszą robić wszystko, piłka jest na nich.
W takim przypadku, dlaczego nie spróbować po prostu tego, co najlepsze z obu światów? Narzędzia tego typu są tutaj po to, aby pomóc pomocną dłoń, która - dzięki starannemu projektowi i planowi - może pomóc w wielu sytuacjach. I wierzcie mi, administratorzy mogą początkowo być trudni do przekonania, ale jeśli wiedzą, że piłka nie jest w ich rękach, pokochają ją.
Osobiście nigdy nie wrócę do ręcznego pisania skryptów w celu rozszerzenia dowolnego schematu, ale to tylko moja opinia. Po niedawnym przyjęciu baz danych bez schematu NoSQL widzę, że wkrótce wszystkie te operacje oparte na schemacie będą należeć do przeszłości, więc lepiej zacznij zmieniać swoją perspektywę i patrzeć w przyszłość.
Nie zaryzykowałbym tego, ponieważ możesz stracić dane, które powinny były zostać zachowane. hbm2ddl.auto = aktualizacja jest czystym łatwym sposobem na aktualizowanie bazy danych deweloperów.
W moim przypadku (Hibernate 3.5.2, Postgresql, Ubuntu) ustawienie hibernate.hbm2ddl.auto=update
spowodowało utworzenie tylko nowych tabel i utworzenie nowych kolumn w już istniejących tabelach.
Nie upuszczał tabel, nie upuszczał kolumn ani nie zmieniał kolumn. Można to nazwać bezpieczną opcją, ale coś takiego hibernate.hbm2ddl.auto=create_tables add_columns
byłoby bardziej jasne.
Nie jest to bezpieczne, nie zalecane, ale jest możliwe.
Mam doświadczenie w aplikacji korzystającej z opcji automatycznej aktualizacji w produkcji.
Cóż, główne problemy i zagrożenia znalezione w tym rozwiązaniu to:
Dlatego nie zalecam używania automatycznej aktualizacji w produkcji.
Jeśli naprawdę chcesz korzystać z automatycznej aktualizacji w produkcji, polecam:
I w przeciwieństwie do innych postów, nie sądzę, aby włączona była automatyczna aktualizacja, która jest związana z „bardzo dobrze płatnymi” DBA (jak wspomniano w innych postach). DBA mają ważniejsze rzeczy do zrobienia niż pisanie instrukcji SQL w celu tworzenia / zmiany / usuwania tabel i kolumn. Te proste codzienne zadania mogą być wykonywane i automatyzowane przez programistów i przekazywane do oceny przez zespół DBA, nie wymagając od Hibernate i DBA „bardzo dobrze płatnych”, aby je napisać.
Zazwyczaj aplikacje korporacyjne w dużych organizacjach działają ze zmniejszonymi uprawnieniami.
Nazwa użytkownika bazy danych może nie mieć DDL
uprawnień do dodawania hbm2ddl.auto=update
wymaganych kolumn .
Zgadzam się z Vladimirem. Administratorzy w mojej firmie na pewno nie doceniliby tego, gdybym nawet zaproponował taki kurs.
Co więcej, utworzenie skryptu SQL zamiast ślepego zaufania Hibernacji daje możliwość usunięcia pól, które nie są już używane. Hibernacja tego nie robi.
Uważam, że porównanie schematu produkcyjnego z nowym schematem daje jeszcze lepszy wgląd w zmiany dokonane w modelu danych. Wiesz oczywiście, ponieważ to zrobiłeś, ale teraz widzisz wszystkie zmiany za jednym razem. Nawet te, które sprawiają, że lubisz „Co do cholery ?!”.
Istnieją narzędzia, które mogą tworzyć dla ciebie deltę schematu, więc nie jest to nawet ciężka praca. I wtedy dokładnie wiesz, co się stanie.
Schemat aplikacji może ewoluować w czasie; jeśli masz kilka instalacji, które mogą być w różnych wersjach, powinieneś mieć sposób, aby upewnić się, że twoja aplikacja, jakieś narzędzie lub skrypt jest w stanie migrować schemat i dane z jednej wersji krokowo do dowolnej następnej.
Posiadanie całej swojej trwałości w mapowaniach hibernacji (lub adnotacjach) jest bardzo dobrym sposobem na kontrolowanie ewolucji schematu.
Należy wziąć pod uwagę, że ewolucja schematu obejmuje kilka aspektów:
ewolucja schematu bazy danych w dodawaniu kolejnych kolumn i tabel
usuwanie starych kolumn, tabel i relacji
wypełnianie nowych kolumn wartościami domyślnymi
Narzędzia hibernacji są szczególnie ważne w przypadku, gdy (jak z mojego doświadczenia) masz różne wersje tej samej aplikacji w wielu różnych bazach danych.
Punkt 3 jest bardzo wrażliwy w przypadku korzystania z Hibernacji, tak jak w przypadku wprowadzenia nowej właściwości o wartości logicznej lub wartości numerycznej, jeśli Hibernacja znajdzie w takich kolumnach wartość zerową, jeśli podniesie wyjątek.
Chciałbym więc: rzeczywiście użyć zdolności Hibernacji do aktualizacji schematu, ale oprócz tego trzeba dodać wywołanie zwrotne związane z obsługą danych i schematu, na przykład w celu wypełnienia wartości domyślnych, usunięcia nieużywanych kolumn i tym podobnych. W ten sposób zyskujesz zalety (skrypty aktualizacji schematu niezależne od bazy danych i unikanie powielania kodowania aktualizacji, w perystencji i skryptach), ale obejmuje również wszystkie aspekty operacji.
Na przykład, jeśli aktualizacja wersji polega po prostu na dodaniu właściwości o wartości varchar (stąd kolumna), która może domyślnie mieć wartość NULL, z automatyczną aktualizacją będziesz gotowy. Tam, gdzie konieczna jest większa złożoność, konieczne będą dalsze prace.
Zakłada się, że po aktualizacji aplikacja może zaktualizować swój schemat (można to zrobić), co oznacza również, że musi mieć uprawnienia użytkownika do wykonania tego schematu. Jeśli polityka klienta temu zapobiegnie (prawdopodobnie sprawa Lizard Brain), będziesz musiał dostarczyć skrypty specyficzne dla bazy danych.