{"id":70973,"date":"2020-02-23T00:58:26","date_gmt":"2020-02-22T21:58:26","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase"},"modified":"2020-03-03T16:14:41","modified_gmt":"2020-03-03T13:14:41","slug":"kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","title":{"rendered":"Wie man sich nicht selbst ins Knie schie\u00dft, wenn man Liquibase verwendet","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Es war nie so, und nun wieder!<\/p>\n<p><\/p>\n<p>In unserem n\u00e4chsten Projekt haben wir beschlossen, Liquibase von Anfang an zu verwenden, um zuk\u00fcnftige Probleme zu vermeiden. Wie sich herausstellte, k\u00f6nnen nicht alle jungen Teammitglieder es richtig nutzen. Ich habe einen internen Workshop durchgef\u00fchrt, den ich dann in einen Artikel umwandeln wollte. <\/p>\n<p><\/p>\n<p>Der Artikel enth\u00e4lt n\u00fctzliche Tipps und eine Beschreibung der drei offensichtlichsten Fallstricke, in die man beim Arbeiten mit Migrationswerkzeugen f\u00fcr relationale Datenbanken, insbesondere Liquibase, geraten kann. Er richtet sich an Junior- und Mittelstufen-Java-Entwickler; f\u00fcr erfahrenere Entwickler k\u00f6nnte er interessant sein, um Strukturen zu organisieren und Bekanntes zu wiederholen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Wie man sich nicht selbst ins Knie schie\u00dft, wenn man Liquibase verwendet\" src=\"\/wp-content\/uploads\/2020\/02\/f8b3c9a456bde7aa123702fae132b4b8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Liquibase und Flyway sind die beiden Hauptkonkurrenten im Bereich der Versionskontrolle relationaler Strukturen in der Java-Welt. Erstere ist v\u00f6llig kostenlos und wird in der Praxis h\u00e4ufig bevorzugt, weshalb Liquibase als Held dieser Publikation gew\u00e4hlt wurde. Dennoch k\u00f6nnen einige der beschriebenen Praktiken je nach Architektur Ihrer Anwendung universell sein. <\/p>\n<p><\/p>\n<p>Migrationen relationaler Strukturen sind eine notwendige Antwort auf die geringe Flexibilit\u00e4t relationaler Datenbankspeicher. In einer Zeit, in der objektorientierte Programmierung in Mode war, betrachtete man die Arbeit mit Datenbanken so, dass man einmal das Schema beschreibt und es dann nicht mehr anfasst. Aber die Realit\u00e4t ist immer so, dass alles sich \u00e4ndert, und \u00c4nderungen an der Tabellenstruktur erforderlich sind, und zwar ziemlich h\u00e4ufig. Nat\u00fcrlich kann der Prozess an sich schmerzhaft und unangenehm sein. <\/p>\n<p><\/p>\n<p>Ich werde nicht n\u00e4her auf die Technologie und die Anleitung zur Hinzuf\u00fcgung der Bibliothek in Ihr Projekt eingehen; dazu wurden bereits gen\u00fcgend Artikel geschrieben:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460377\/\">Verwendung von Liquibase zur Verwaltung der Datenbankstruktur in einer Spring Boot-Anwendung. Teil 1<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460907\/\">Verwendung von Liquibase zur Verwaltung der Datenbankstruktur in einer Spring Boot-Anwendung. Teil 2<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/436994\/\">Liquibase und Maven<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/330662\/\">Ans\u00e4tze zur Versionierung von Datenbank\u00e4nderungen<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/271719\/\">Spring MVC\/Security, REST, Hibernate, Liquibase in zwei Zeilen starten<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<p>Dar\u00fcber hinaus gab es bereits einen gro\u00dfartigen Artikel mit n\u00fctzlichen Tipps:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/179425\/\">Liquibase ohne Kopfschmerzen nutzen. 10 Tipps aus der Praxis der echten Entwicklung<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"sovety\">Tipps<\/h2>\n<p><\/p>\n<p>Ich m\u00f6chte meine Tipps und Kommentare teilen, die durch Schwei\u00df, Blut und Schmerz beim L\u00f6sen von Migrationsproblemen entstanden sind.<\/p>\n<p><\/p>\n<h3 id=\"1--pered-rabotoy-sleduet-oznakomitsya-s-razdelom-luchshih-praktik-na-saytehttpswwwliquibaseorgbestpracticeshtml-liquibase\">1. Vor der Arbeit sollte man sich mit dem Abschnitt der besten Praktiken auf <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/bestpractices.html\">Website<\/a><\/noindex> Liquibase<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/bestpractices.html\">dort vertraut machen.<\/a><\/noindex> Es werden einfache, aber sehr wichtige Aspekte beschrieben, ohne die die Nutzung der Bibliothek Ihnen das Leben erschweren kann. Zum Beispiel f\u00fchrt ein unstrukturierter Ansatz bei der Verwaltung von Changesets fr\u00fcher oder sp\u00e4ter zu Verwirrung und fehlerhaften Migrationen. Wenn Sie abh\u00e4ngige \u00c4nderungen in der Struktur der Datenbank und der Logik der Dienste nicht gleichzeitig einf\u00fchren, besteht eine gro\u00dfe Wahrscheinlichkeit, dass dies zu roten Tests oder einer fehlerhaften Umgebung f\u00fchrt. Dar\u00fcber hinaus enth\u00e4lt die Empfehlung zur Nutzung von Liquibase auf der offiziellen Website einen Punkt zur Entwicklung und \u00dcberpr\u00fcfung von Rollback-Skripten zusammen mit den Hauptmigrationsskripten. Nun, und im Artikel <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/178665\/\">https:\/\/habr.com\/ru\/post\/178665\/<\/a><\/noindex> gibt es Codebeispiele zu Migrationen und dem Rollback-Mechanismus. <\/p>\n<p><\/p>\n<h3 id=\"2-esli-nachali-ispolzovat-sredstva-migracii--ne-dopuskayte-manualnyh-ispravleniy-v-strukture-bazy\">2. Wenn Sie mit Migrationstools begonnen haben, vermeiden Sie manuelle \u00c4nderungen an der Datenbankstruktur.<\/h3>\n<p><\/p>\n<p>Wie gesagt: \u201eEinmal Persil \u2013 immer Persil\u201c. Wenn die Datenbank Ihrer Anwendung mit Liquibase verwaltet wird, f\u00fchren manuelle \u00c4nderungen sofort zu einem inkonsistenten Zustand, und das Vertrauen in die Changesets wird gleich null. Potentielle Risiken sind mehrere Stunden, die f\u00fcr die Wiederherstellung der Datenbank aufgewendet werden m\u00fcssen, im schlimmsten Fall ein defekter Server. Wenn in Ihrem Team ein DBA-Architekt \u201ealter Schule\u201c ist, erkl\u00e4ren Sie ihm geduldig und durchdacht, wie schlecht es l\u00e4uft, wenn er die Datenbank nach seinem eigenen Ermessen mit einem hypothetischen SQL Developer bearbeitet. <\/p>\n<p><\/p>\n<h3 id=\"3-esli-chendzhset-uzhe-byl-zapushen-v-repozitoriy-izbegayte-redaktirovaniya\">3. Wenn ein Changeset bereits in das Repository gepusht wurde, vermeiden Sie Bearbeitungen.<\/h3>\n<p><\/p>\n<p>Wenn ein anderer Entwickler einen Pull gemacht hat und ein Changeset angewendet hat, das sp\u00e4ter bearbeitet wird, wird er Sie bei einem Fehler beim Start der Anwendung sicherlich mit einem netten Wort erw\u00e4hnen. Wenn die Bearbeitung des Changesets irgendwie in die Entwicklung geleitet wird, wird es m\u00fchsam, durch Hotfixes zu navigieren. Das Problem liegt in der Validierung der \u00c4nderungen durch die Pr\u00fcfziffer \u2013 der Hauptmechanismus von Liquibase. Bei der Bearbeitung des Codes eines Changesets \u00e4ndert sich die Pr\u00fcfziffer. Das Bearbeiten von Changesets ist nur m\u00f6glich, wenn die M\u00f6glichkeit besteht, die gesamte Datenbank ohne Datenverlust von Grund auf neu zu erstellen. In diesem Fall kann das Refactoring von SQL- oder XML-Code im Gegenteil das Leben erleichtern und Migrationen leserlicher machen. Ein Beispiel k\u00f6nnte die Situation sein, wenn zu Beginn der Anwendung das Schema der urspr\u00fcnglichen Datenbank im Team abgestimmt wurde. <\/p>\n<p><\/p>\n<h3 id=\"4--imey-proverennye-bekapy-baz-dannyh-esli-eto-vozmozhno\">4. Haben Sie, wenn m\u00f6glich, gepr\u00fcfte Datenbank-Backups.<\/h3>\n<p><\/p>\n<p>Hier sollte alles klar sein. Falls die Migration unerwartet fehlschl\u00e4gt, kann alles zur\u00fcckgesetzt werden. Liquibase bietet ein Tool zum Zur\u00fccksetzen von \u00c4nderungen, aber die Skripte f\u00fcr das Zur\u00fccksetzen m\u00fcssen ebenfalls vom Entwickler geschrieben werden, wobei sie die gleiche Wahrscheinlichkeit f\u00fcr Probleme aufweisen k\u00f6nnen wie die Skripte des Haupt-Changesets. Das bedeutet, dass es in jedem Fall sinnvoll ist, sich mit Backups abzusichern. <\/p>\n<p><\/p>\n<h3 id=\"5-ispolzuy-proverennye-bekapy-baz-dannyh-v-razrabotke-esli-eto-vozmozhno\">5. Verwenden Sie gepr\u00fcfte Datenbank-Backups in der Entwicklung, wenn m\u00f6glich.<\/h3>\n<p><\/p>\n<p>Wenn dies nicht gegen Vertr\u00e4ge oder Datenschutzbestimmungen verst\u00f6\u00dft, keine pers\u00f6nlichen Daten in der Datenbank vorhanden sind und sie nicht so viel wie zwei Sonnen wiegt \u2013 vor der Anwendung von Migrationen auf Live-Servern kann getestet werden, wie es auf der Maschine des Entwicklers funktioniert, um fast 100% potenzielle Probleme bei der Migration zu erkennen. <\/p>\n<p><\/p>\n<h3 id=\"6-obschaysya-s-drugimi-razrabotchikami-v-komande\">6. Kommunizieren Sie mit anderen Entwicklern im Team.<\/h3>\n<p><\/p>\n<p>In einem gut organisierten Entwicklungsprozess wei\u00df jeder im Team, wer an was arbeitet. In der Realit\u00e4t ist das oft nicht der Fall, daher ist es ratsam, das gesamte Team zus\u00e4tzlich zu informieren, wenn Sie \u00c4nderungen an der Datenbankstruktur im Rahmen Ihrer Aufgabe vorbereiten. Wenn jemand parallel \u00c4nderungen vornimmt, sollten Sie sich vorsichtig organisieren. Es ist auch wichtig, nach Abschluss der Arbeit mit den Kollegen zu kommunizieren, nicht nur zu Beginn. Viele potenzielle Probleme mit Changesets lassen sich in der Phase der Code\u00fcberpr\u00fcfung l\u00f6sen. <\/p>\n<p><\/p>\n<h3 id=\"7-dumay-chto-delaesh\">7. Denken Sie daran, was Sie tun!<\/h3>\n<p><\/p>\n<p>Es scheint ein offensichtlicher Ratschlag zu sein, der in allen Situationen anwendbar ist. Viele Probleme k\u00f6nnten vermieden werden, wenn der Entwickler noch einmal analysieren w\u00fcrde, was er tut und welche Auswirkungen dies haben k\u00f6nnte. Die Arbeit mit Migrationen erfordert stets zus\u00e4tzliche Aufmerksamkeit und Sorgfalt. <\/p>\n<p><\/p>\n<h2 id=\"lovushki\">Fallen<\/h2>\n<p><\/p>\n<p>Betrachten wir nun typische Fallen, in die man geraten kann, wenn man die obigen Ratschl\u00e4ge nicht befolgt, und was man eigentlich tun sollte.<\/p>\n<p><\/p>\n<h3 id=\"situaciya-1-dva-razrabotchika-pytayutsya-odnovremenno-dobavlyat-novye-chendzhsety\">Situation 1. Zwei Entwickler versuchen gleichzeitig, neue Changesets hinzuzuf\u00fcgen.<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Wie man sich nicht selbst ins Knie schie\u00dft, wenn man Liquibase verwendet\" src=\"\/wp-content\/uploads\/2020\/02\/20706fc970510bc06634fa001a4c7ceb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nWanja und Petja wollen ein Changeset der Version 4 erstellen, ohne voneinander zu wissen. Sie haben \u00c4nderungen an der Datenbankstruktur vorgenommen und einen Pull-Request mit unterschiedlichen Changeset-Dateien erstellt. Der folgende Aktionsmechanismus wird vorgeschlagen:<\/p>\n<p><\/p>\n<h4 id=\"kak-reshat\">Wie man es l\u00f6st.<\/h4>\n<p><\/p>\n<ol>\n<li>Irgendwie sollten die Kollegen sich einigen, in welcher Reihenfolge ihre Changesets erfolgen sollen, z. B. sollte Petjas zuerst angewendet werden. <\/li>\n<li>Jemand muss das zweite zu sich hinzuf\u00fcgen und den \u00c4nderungsdatensatz von Wanja mit Version 5 kennzeichnen. Dies kann \u00fcber Cherry Pick oder einen sorgf\u00e4ltigen Merge erfolgen. <\/li>\n<li>Nach den \u00c4nderungen sollte unbedingt die G\u00fcltigkeit der durchgef\u00fchrten Aktionen \u00fcberpr\u00fcft werden.<br \/>\nTats\u00e4chlich erm\u00f6glichen die Mechanismen von Liquibase, zwei \u00c4nderungsdatens\u00e4tze der Version 4 im Repository zu haben, daher kann alles so bleiben, wie es ist. Das bedeutet, dass es einfach zwei \u00c4nderungen der Version 4 mit unterschiedlichen Bezeichnungen geben wird. Bei diesem Ansatz wird es sp\u00e4ter sehr schwierig, in den Versionen der Datenbank den \u00dcberblick zu behalten. <\/li>\n<\/ol>\n<p><\/p>\n<p>Dar\u00fcber hinaus birgt Liquibase, wie das Zuhause der Hobbits, viele Geheimnisse. Eines davon ist der Schl\u00fcssel validCheckSum, der seit Version 1.7 existiert und es erm\u00f6glicht, einen g\u00fcltigen Hashwert f\u00fcr einen bestimmten \u00c4nderungsdatensatz anzugeben, unabh\u00e4ngig von dem, was in der Datenbank gespeichert ist. Dokumentation <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/changeset.html\">https:\/\/www.liquibase.org\/documentation\/changeset.html<\/a><\/noindex> besagt Folgendes:<\/p>\n<p><\/p>\n<blockquote><p>Add a checksum that is considered valid for this changeSet, regardless of what is stored in the database. Used primarily when you need to change a changeSet and don&#8217;t want errors thrown on databases on which it has already run (not a recommended procedure)<\/p><\/blockquote>\n<p>Ja, ja, ein solches Verfahren wird nicht empfohlen. Aber manchmal beherrscht ein m\u00e4chtiger heller Magier auch dunkle Techniken. <\/p>\n<p><\/p>\n<h3 id=\"situaciya-2-migraciya-kotoraya-zavisit-ot-dannyh\">Situation 2. Migration, die von Daten abh\u00e4ngt.<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Wie man sich nicht selbst ins Knie schie\u00dft, wenn man Liquibase verwendet\" src=\"\/wp-content\/uploads\/2020\/02\/31a6eebb55278c0631115bf16483c7b8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Angenommen, Sie haben keine M\u00f6glichkeit, Sicherungskopien von Datenbanken von Live-Servern zu verwenden. Petja hat einen \u00c4nderungsdatensatz erstellt, ihn lokal \u00fcberpr\u00fcft und mit voller \u00dcberzeugung seiner Richtigkeit einen Pull-Request in die Entwicklung gestellt. Der Projektleiter hat zur Sicherheit nachgefragt, ob Petja ihn \u00fcberpr\u00fcft hat, und hat dann die \u00c4nderungen gemerged. Aber die Bereitstellung auf dem Entwicklungserver ist gescheitert.<\/p>\n<p><\/p>\n<p>Tats\u00e4chlich ist so etwas m\u00f6glich, und niemand ist davor gesch\u00fctzt. Dies geschieht, wenn Modifikationen der Tabellenstruktur in irgendeiner Weise an bestimmten Daten in der Datenbank gebunden sind. Offensichtlich ist es so, dass wenn die Datenbank von Petja nur mit Testdaten gef\u00fcllt ist, sie m\u00f6glicherweise nicht alle problematischen F\u00e4lle abdeckt. Zum Beispiel ergibt sich beim L\u00f6schen einer Tabelle, dass es Eintr\u00e4ge in anderen Tabellen mit Foreign Key gibt, die mit den Eintr\u00e4gen in der gel\u00f6schten Tabelle verbunden sind. Oder beim \u00c4ndern des Datentyps einer Spalte stellt sich heraus, dass nicht 100% der Daten in den neuen Typ konvertiert werden k\u00f6nnen. <\/p>\n<p><\/p>\n<h4 id=\"kak-reshat-1\">Wie man es l\u00f6st.<\/h4>\n<p><\/p>\n<ul>\n<li>Speziell entwickelte Skripte zu erstellen, die einmalig zusammen mit der Migration angewendet werden und die Daten in den richtigen Zustand bringen. Dies ist ein allgemeiner Ansatz zur L\u00f6sung des Problems der Datenmigration in neue Strukturen nach der Anwendung von Migrationen, aber etwas \u00c4hnliches kann auch in bestimmten F\u00e4llen vorher angewendet werden. Dieser Weg ist nat\u00fcrlich nicht immer verf\u00fcgbar, da das Bearbeiten von Daten auf aktiven Servern gef\u00e4hrlich und sogar verheerend sein kann. <\/li>\n<li>Ein weiterer komplizierter Weg besteht darin, das bestehende Change-Set zu bearbeiten. Die Schwierigkeit besteht darin, dass alle Datenbanken, in denen es in der aktuellen Form bereits angewendet wurde, wiederhergestellt werden m\u00fcssen. Es ist gut m\u00f6glich, dass das gesamte Backend-Team gezwungen sein wird, die Datenbank lokal von Grund auf neu zu installieren. <\/li>\n<li>Und der universellste Weg ist, das Problem mit den Daten auf die Umgebung des Entwicklers zu \u00fcbertragen, wobei die gleiche Situation wiederhergestellt wird, und ein neues Change-Set bis zu dem defekten hinzuzuf\u00fcgen, das das Problem umgeht.<br \/>\n<img decoding=\"async\" alt=\"Wie man sich nicht selbst ins Knie schie\u00dft, wenn man Liquibase verwendet\" src=\"\/wp-content\/uploads\/2020\/02\/b5d28a940a7a35b6cd7a819a8e68f027.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ul>\n<p><\/p>\n<p>Im Allgemeinen gilt: Je \u00e4hnlicher die Datenbasis der Produktionsumgebung ist, desto geringer ist die Wahrscheinlichkeit, dass Probleme mit Migrationen weitreichend sind. Und nat\u00fcrlich sollte man, bevor man das Change-Set in das Repository hochl\u00e4dt, mehrmals \u00fcberlegen, ob es nicht etwas kaputt macht. <\/p>\n<p><\/p>\n<h3 id=\"situaciya-3-liquibase-nachinaet-primenyatsya-uzhe-posle-vyhoda-v-prodakshn\">Situation 3. Liquibase wird bereits nach dem Go-Live in der Produktion angewendet<\/h3>\n<p><\/p>\n<p>Angenommen, der Teamleiter hat Petja gebeten, Liquibase in das Projekt einzubinden, jedoch ist das Projekt bereits in der Produktion und es existiert bereits eine bestehende Datenbankstruktur.<\/p>\n<p><\/p>\n<p>Dementsprechend besteht das Problem darin, dass auf allen neuen Servern oder Entwickler-Maschinen die Daten dieser Tabellen von Grund auf neu erstellt werden m\u00fcssen, w\u00e4hrend die bereits bestehende Umgebung konsistent bleiben muss und bereit ist, neue Change-Sets zu akzeptieren. <\/p>\n<p><\/p>\n<h4 id=\"kak-reshat-2\">Wie man es l\u00f6st.<\/h4>\n<p><\/p>\n<p>Es gibt auch hier mehrere M\u00f6glichkeiten:<\/p>\n<p><\/p>\n<ul>\n<li>Der erste und offensichtlichste Weg ist, ein separates Skript zu haben, das manuell bei der Initialisierung einer neuen Umgebung angewendet werden muss. <\/li>\n<li>Der zweite, weniger offensichtliche Weg besteht darin, eine Liquibase-Migration zu haben, die sich in einem anderen Liquibase-Kontext befindet und angewendet wird. Mehr \u00fcber den Liquibase-Kontext kann hier gelesen werden: <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/contexts.html\">https:\/\/www.liquibase.org\/documentation\/contexts.html<\/a><\/noindex>. Insgesamt ist dies ein interessantes Konzept, das beispielsweise erfolgreich f\u00fcr Tests angewendet werden kann. <\/li>\n<li>Der dritte Weg besteht aus mehreren Schritten. Zun\u00e4chst muss eine Migration f\u00fcr bereits vorhandene Tabellen erstellt werden. Anschlie\u00dfend muss sie in einer bestimmten Umgebung angewendet werden, wodurch ihr Hash-Wert erhalten wird. Der n\u00e4chste Schritt besteht darin, auf unserem nicht leeren Server leere Liquibase-Tabellen zu initialisieren, und in die Tabelle mit der Historie der angewendeten Changesets kann man manuell einen Eintrag \u00fcber das \"angeblich angewendete\" Changeset mit den bereits vorhandenen \u00c4nderungen in der Datenbank hinzuf\u00fcgen. Auf diese Weise beginnt die Historie auf dem bereits existierenden Server mit Version 2, w\u00e4hrend sich alle neuen Umgebungen identisch verhalten.<br \/>\n<img decoding=\"async\" alt=\"Wie man sich nicht selbst ins Knie schie\u00dft, wenn man Liquibase verwendet\" src=\"\/wp-content\/uploads\/2020\/02\/78881ee56a6ee3ba4e0cd1089598c3c7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"situaciya-4-migracii-stanovyatsya-ogromnymi-i-ne-uspevayut-vypolnyatsya\">Situation 4. Migrationen werden riesig und schaffen es nicht, rechtzeitig ausgef\u00fchrt zu werden.<\/h3>\n<p><\/p>\n<p>Zu Beginn der Entwicklung des Dienstes wird Liquibase in der Regel als externe Abh\u00e4ngigkeit verwendet, und alle Migrationen werden beim Start der Anwendung verarbeitet. Mit der Zeit k\u00f6nnen jedoch die folgenden Szenarien auftreten:<\/p>\n<p><\/p>\n<ul>\n<li>Migrationen werden riesig und ben\u00f6tigen lange f\u00fcr ihre Ausf\u00fchrung.<\/li>\n<li>Es entsteht die Notwendigkeit, Migrationen in verteilten Umgebungen durchzuf\u00fchren, beispielsweise auf mehreren Instanzen von Datenbankservern gleichzeitig.<br \/>\nIn einem solchen Fall kann die zu lange Ausf\u00fchrung von Migrationen zu einem Timeout beim Start der Anwendung f\u00fchren. Zudem kann die Anwendung von Migrationen f\u00fcr jede Instanz der Anwendung separat dazu f\u00fchren, dass verschiedene Server in unsynchronisiertem Zustand enden. <\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"kak-reshat-3\">Wie man es l\u00f6st.<\/h4>\n<p><\/p>\n<p>In solchen F\u00e4llen ist Ihr Projekt bereits gro\u00df, m\u00f6glicherweise sogar vollj\u00e4hrig, und Liquibase beginnt als separates externes Tool zu fungieren. Liquibase wird als Bibliothek in eine JAR-Datei gepackt und kann sowohl als Abh\u00e4ngigkeit innerhalb des Projekts als auch autonom arbeiten. <\/p>\n<p><\/p>\n<p>Im autonomen Modus k\u00f6nnen die Migrationen von Ihrer CI\/CD-Umgebung oder von den erfahrenen Systemadministratoren, die f\u00fcr die Bereitstellung zust\u00e4ndig sind, in die Hand genommen werden. Dazu wird die Befehlszeile von Liquibase ben\u00f6tigt. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/command_line.html\">https:\/\/www.liquibase.org\/documentation\/command_line.html<\/a><\/noindex>In diesem Modus besteht die M\u00f6glichkeit, die Anwendung bereits zu starten, nachdem alle erforderlichen Migrationen durchgef\u00fchrt wurden.<\/p>\n<p><\/p>\n<h2 id=\"vyvod\">Ausgabe<\/h2>\n<p><\/p>\n<p>Tats\u00e4chlich kann es bei der Arbeit mit Datenbankmigrationen viel mehr Fallstricke geben, und viele von ihnen erfordern einen kreativen Ansatz. Es ist wichtig zu verstehen, dass die korrekte Verwendung des Werkzeugs es erm\u00f6glicht, die meisten dieser Fallstricke zu vermeiden. Konkrett habe ich in unterschiedlichen Formen mit allen genannten Problemen zu tun gehabt, und einige davon waren das Ergebnis meiner eigenen Fehler. In der Regel passiert dies, nat\u00fcrlich, durch Unachtsamkeit, aber manchmal auch aus einer kriminellen Unf\u00e4higkeit, das Werkzeug zu nutzen.<\/p>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/epam_systems\/blog\/489198\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":70974,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-70973","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u043d\u0435 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0441\u0435\u0431\u0435 \u0432 \u043d\u043e\u0433\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Liquibase | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-22T21:58:26+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-03T13:14:41+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Wie man sich mit Liquibase nicht ins eigene Knie schie\u00dft | ProHoster","description":"Es war noch nie der Fall, und da ist es wieder! In einem aktuellen Projekt haben wir beschlossen, Liquibase von Anfang an zu verwenden, um k\u00fcnftige Probleme zu vermeiden.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u043d\u0435 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0441\u0435\u0431\u0435 \u0432 \u043d\u043e\u0433\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Liquibase | ProHoster","og:description":"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-22T21:58:26+00:00","article:modified_time":"2020-03-03T13:14:41+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"70973","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:10:24","updated":"2022-09-28 08:39:22","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/70973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=70973"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/70973\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/70974"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=70973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=70973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=70973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}