Ist es in Ordnung, Ruhezustandsanwendungen auszuführen, die hbm2ddl.auto=update
zum Aktualisieren des Datenbankschemas in einer Produktionsumgebung konfiguriert sind ?
Ist es in Ordnung, Ruhezustandsanwendungen auszuführen, die hbm2ddl.auto=update
zum Aktualisieren des Datenbankschemas in einer Produktionsumgebung konfiguriert sind ?
Antworten:
Nein, es ist unsicher.
Trotz aller Bemühungen des Hibernate-Teams können Sie sich einfach nicht auf automatische Updates in der Produktion verlassen . Schreiben Sie Ihre eigenen Patches, überprüfen Sie sie mit DBA, testen Sie sie und wenden Sie sie dann manuell an.
Wenn das hbm2ddl-Update in der Entwicklung funktioniert hat, sollte es theoretisch auch in der Produktion funktionieren. In Wirklichkeit ist dies jedoch nicht immer der Fall.
Selbst wenn es in Ordnung funktioniert hat, ist es möglicherweise nicht optimal. DBAs werden aus einem bestimmten Grund so viel bezahlt.
Wir tun dies in der Produktion, allerdings mit einer Anwendung, die nicht geschäftskritisch ist und keine hochbezahlten DBAs im Personal hat. Es ist nur ein manueller Prozess weniger, der menschlichen Fehlern unterliegt - die Anwendung kann den Unterschied erkennen und das Richtige tun, und Sie haben ihn vermutlich in verschiedenen Entwicklungs- und Testumgebungen getestet.
Eine Einschränkung: In einer Clusterumgebung möchten Sie dies möglicherweise vermeiden, da mehrere Apps gleichzeitig gestartet werden und versuchen können, das möglicherweise fehlerhafte Schema zu ändern. Oder setzen Sie einen Mechanismus ein, bei dem nur eine Instanz das Schema aktualisieren darf.
Entwickler von Ruhezuständen raten in ihrem Buch "Java Persistence with Hibernate" davon ab, dies in einer Produktionsumgebung zu tun :
WARNUNG: Wir haben gesehen, dass Benutzer im Ruhezustand versuchen, SchemaUpdate zu verwenden, um das Schema einer Produktionsdatenbank automatisch zu aktualisieren. Dies kann schnell zu einer Katastrophe führen und wird von Ihrem DBA nicht zugelassen.
In LiquiBase XML finden Sie ein Änderungsprotokoll mit Updates. Ich hatte es bis zu diesem Jahr noch nie benutzt, aber ich fand, dass es sehr einfach zu erlernen ist und DB-Revisionskontrolle / Migration / Änderungsmanagement sehr kinderleicht macht. Ich arbeite an einem Groovy / Grails-Projekt, und Grails verwendet Hibernate darunter für alle ORMs ("GORM" genannt). Wir verwenden Liquibase, um alle Änderungen am SQL-Schema zu verwalten, was wir ziemlich oft tun, wenn sich unsere App mit neuen Funktionen weiterentwickelt.
Grundsätzlich behalten Sie eine XML-Datei mit Änderungssätzen bei, die Sie im Zuge der Weiterentwicklung Ihrer Anwendung weiterhin hinzufügen. Diese Datei wird mit dem Rest Ihres Projekts in Git (oder was auch immer Sie verwenden) gespeichert. Wenn Ihre App bereitgestellt wird, überprüft Liquibase die Änderungsprotokolltabelle in der Datenbank, mit der Sie eine Verbindung herstellen, damit es weiß, was bereits angewendet wurde, und wendet dann intelligent nur die Änderungssätze an, die noch nicht aus der Datei angewendet wurden. In der Praxis funktioniert es absolut hervorragend. Wenn Sie es für alle Schemaänderungen verwenden, können Sie zu 100% sicher sein, dass der Code, den Sie auschecken und bereitstellen, immer eine Verbindung zu einem vollständig kompatiblen Datenbankschema herstellen kann.
Das Tolle ist, dass ich eine völlig leere MySQL-Datenbank auf meinem Laptop speichern, die App starten und sofort das Schema für mich einrichten kann. Es macht es auch einfach, Schemaänderungen zu testen, indem diese zuerst auf einen lokalen Entwickler oder eine Staging-Datenbank angewendet werden.
Der einfachste Weg, um damit zu beginnen, besteht wahrscheinlich darin, Ihre vorhandene Datenbank zu verwenden und dann Liquibase zu verwenden, um eine erste Datei base.xml zu generieren. Dann können Sie in Zukunft einfach daran anhängen und liquibase die Verwaltung von Schemaänderungen übernehmen lassen.
hbm2ddl.auto=update
damit Ihre Klassen- / DB-Zuordnungen validiert werden und Sie die vollständige Kontrolle über die DB-Erstellung durch Liquibase haben. Was denken Sie?
validate
Ich würde nein stimmen. Der Ruhezustand scheint nicht zu verstehen, wann sich Datentypen für Spalten geändert haben. Beispiele (mit 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
Es gibt wahrscheinlich auch andere Beispiele, z. B. das Erhöhen der Länge einer String-Spalte um mehr als 255 und das Konvertieren in Text, Mediumtext usw. usw.
Zugegeben, ich glaube nicht, dass es wirklich eine Möglichkeit gibt, "Datentypen zu konvertieren", ohne eine neue Spalte zu erstellen, die Daten zu kopieren und die alte Spalte wegzublasen. Aber sobald Ihre Datenbank Spalten enthält, die nicht die aktuelle Hibernate-Zuordnung widerspiegeln, leben Sie sehr gefährlich ...
Flyway ist eine gute Option, um dieses Problem zu lösen:
@Column(length = 45)
zu @Column(length = 255)
. Kann überprüfen, ob Hibernate 4.3.6.Final das Datenbankschema mit korrekt aktualisiert hat hbm2ddl.auto=update
. (Eine Sache zu erwähnen ist, dass die Datenbank derzeit keine Daten enthält - nur die Struktur.)
Hibernate muss den Haftungsausschluss darüber enthalten, dass keine automatischen Updates in prod verwendet werden, um sich zu versichern, wenn Personen, die nicht wissen, was sie tun, es in Situationen verwenden, in denen es nicht verwendet werden sollte.
Zugegeben, die Situationen, in denen es nicht verwendet werden sollte, sind weitaus zahlreicher als die, in denen es in Ordnung ist.
Ich habe es jahrelang für viele verschiedene Projekte verwendet und hatte nie ein einziges Problem. Das ist keine lahme Antwort, und es ist keine Cowboy-Codierung. Es ist eine historische Tatsache.
Eine Person, die sagt "Mach es niemals in der Produktion", denkt an eine bestimmte Reihe von Produktionsbereitstellungen, nämlich die, mit denen sie vertraut ist (sein Unternehmen, seine Branche usw.).
Das Universum der "Produktionsbereitstellungen" ist groß und vielfältig.
Ein erfahrener Hibernate-Entwickler weiß genau, welche DDL aus einer bestimmten Mapping-Konfiguration resultieren wird. Solange Sie testen und validieren, dass das, was Sie erwarten, in der DDL landet (in dev, qa, staging usw.), geht es Ihnen gut.
Wenn Sie viele Funktionen hinzufügen, können automatische Schemaaktualisierungen Zeit sparen.
Die Liste der Dinge, die bei automatischen Updates nicht verarbeitet werden, ist endlos, aber einige Beispiele sind Datenmigration, Hinzufügen von nicht nullbaren Spalten, Änderungen des Spaltennamens usw. usw.
Sie müssen auch in Clusterumgebungen vorsichtig sein.
Aber andererseits, wenn Sie all dieses Zeug wüssten, würden Sie diese Frage nicht stellen. Hmm. . . OK, wenn Sie diese Frage stellen, sollten Sie warten, bis Sie viel Erfahrung mit Hibernate- und Auto-Schema-Updates haben, bevor Sie darüber nachdenken, sie in prod zu verwenden.
Wie ich in diesem Artikel erklärt habe , ist es keine gute Idee, sie hbm2ddl.auto
in der Produktion zu verwenden.
Die einzige Möglichkeit, das Datenbankschema zu verwalten, besteht in der Verwendung inkrementeller Migrationsskripts, da:
Selbst im Hibernate-Benutzerhandbuch wird empfohlen, das hbm2ddl
Tool nicht für Produktionsumgebungen zu verwenden.
SchemaExport
wie in diesem Testfall gezeigt .
Wir machen das in einem Projekt, das seit Monaten in Produktion ist und bisher noch nie ein Problem hatte. Beachten Sie die 2 Zutaten für dieses Rezept:
Entwerfen Sie Ihr Objektmodell mit einem Abwärtskompatibilitätsansatz, bei dem Objekte und Attribute veraltet sind, anstatt sie zu entfernen / zu ändern. Dies bedeutet, dass Sie, wenn Sie den Namen eines Objekts oder Attributs ändern müssen, den alten unverändert lassen, den neuen hinzufügen und eine Art Migrationsskript schreiben müssen. Wenn Sie eine Zuordnung zwischen Objekten ändern müssen, wenn Sie bereits in der Produktion sind, bedeutet dies, dass Ihr Design an erster Stelle falsch war. Überlegen Sie sich also eine neue Art, die neue Beziehung auszudrücken, ohne die alten Daten zu beeinflussen.
Immer Sicherung der Datenbank vor der Bereitstellung.
Nach dem Lesen dieses Beitrags habe ich das Gefühl, dass 90% der Teilnehmer an dieser Diskussion entsetzt sind, wenn sie nur daran denken, solche Automatisierungen in einer Produktionsumgebung einzusetzen. Einige werfen den Ball auf den DBA. Nehmen Sie sich einen Moment Zeit, um zu bedenken, dass nicht alle Produktionsumgebungen einen DBA bereitstellen und sich nicht viele Entwicklerteams einen leisten können (zumindest für mittelgroße Projekte). Wenn wir also über Teams sprechen, in denen jeder alles tun muss, ist der Ball auf ihnen.
Warum versuchen Sie in diesem Fall nicht einfach, das Beste aus beiden Welten zu haben? Tools wie dieses sind hier, um zu helfen, was - mit einem sorgfältigen Design und Plan - in vielen Situationen helfen kann. Und glauben Sie mir, Administratoren sind anfangs vielleicht schwer zu überzeugen, aber wenn sie wissen, dass der Ball nicht auf ihren Händen liegt, werden sie ihn lieben.
Persönlich würde ich nie wieder Skripte von Hand schreiben, um irgendeine Art von Schema zu erweitern, aber das ist nur meine Meinung. Und nachdem ich kürzlich damit begonnen habe, schemalose NoSQL-Datenbanken einzuführen, kann ich feststellen, dass all diese schemabasierten Vorgänge mehr als bald der Vergangenheit angehören werden. Sie sollten also besser Ihre Perspektive ändern und nach vorne schauen.
Ich würde es nicht riskieren, weil Sie möglicherweise Daten verlieren, die erhalten bleiben sollten. hbm2ddl.auto = update ist eine einfache Möglichkeit, Ihre Entwicklerdatenbank auf dem neuesten Stand zu halten.
In meinem Fall (Hibernate 3.5.2, Postgresql, Ubuntu) wurden durch die Einstellung hibernate.hbm2ddl.auto=update
nur neue Tabellen und neue Spalten in bereits vorhandenen Tabellen erstellt.
Es wurden weder Tabellen gelöscht, noch Spalten gelöscht oder Spalten geändert. Es kann als sichere Option bezeichnet werden, aber so etwas hibernate.hbm2ddl.auto=create_tables add_columns
wäre klarer.
Es ist nicht sicher, nicht empfohlen, aber es ist möglich.
Ich habe Erfahrung in einer Anwendung mit der Option zur automatischen Aktualisierung in der Produktion.
Nun, die Hauptprobleme und Risiken dieser Lösung sind:
Daher werde ich nicht empfehlen, das automatische Update in der Produktion zu verwenden.
Wenn Sie das automatische Update wirklich in der Produktion verwenden möchten, empfehle ich:
Und anders als bei den anderen Posts glaube ich nicht, dass das automatische Update aktiviert ist, da es mit "sehr gut bezahlten" DBAs zusammenhängt (wie in anderen Posts erwähnt). DBAs haben wichtigere Aufgaben als das Schreiben von SQL-Anweisungen zum Erstellen / Ändern / Löschen von Tabellen und Spalten. Diese einfachen alltäglichen Aufgaben können von Entwicklern erledigt und automatisiert werden und werden nur dem DBA-Team zur Überprüfung übergeben, ohne dass Hibernate und DBAs "sehr gut bezahlt" sind, um sie zu schreiben.
In der Regel werden Unternehmensanwendungen in großen Organisationen mit eingeschränkten Berechtigungen ausgeführt.
Der Datenbankbenutzername hat möglicherweise keine DDL
Berechtigung zum Hinzufügen von hbm2ddl.auto=update
erforderlichen Spalten .
Ich stimme Vladimir zu. Die Administratoren in meiner Firma würden es definitiv nicht schätzen, wenn ich überhaupt einen solchen Kurs vorschlagen würde.
Wenn Sie ein SQL-Skript erstellen, anstatt Hibernate blind zu vertrauen, können Sie außerdem Felder entfernen, die nicht mehr verwendet werden. Hibernate macht das nicht.
Und ich finde, wenn Sie das Produktionsschema mit dem neuen Schema vergleichen, erhalten Sie noch bessere Einblicke in das, was Sie im Datenmodell geändert haben. Sie wissen natürlich, weil Sie es geschafft haben, aber jetzt sehen Sie alle Änderungen auf einmal. Sogar diejenigen, die dich dazu bringen, wie "Was zum Teufel?!"
Es gibt Tools, mit denen Sie ein Schemadelta erstellen können, sodass es nicht einmal harte Arbeit ist. Und dann wissen Sie genau, was passieren wird.
Das Anwendungsschema kann sich mit der Zeit ändern. Wenn Sie mehrere Installationen haben, die sich in unterschiedlichen Versionen befinden können, sollten Sie eine Möglichkeit haben, um sicherzustellen, dass Ihre Anwendung, ein Tool oder ein Skript in der Lage ist, Schema und Daten schrittweise von einer Version auf eine folgende zu migrieren.
Wenn Sie Ihre gesamte Persistenz in Zuordnungen (oder Anmerkungen) im Ruhezustand haben, ist dies eine sehr gute Möglichkeit, die Schemaentwicklung unter Kontrolle zu halten.
Sie sollten berücksichtigen, dass die Schemaentwicklung mehrere Aspekte berücksichtigt:
Weiterentwicklung des Datenbankschemas beim Hinzufügen weiterer Spalten und Tabellen
Löschen alter Spalten, Tabellen und Beziehungen
Füllen neuer Spalten mit Standardeinstellungen
Tools für den Ruhezustand sind insbesondere dann wichtig, wenn Sie (wie meiner Erfahrung nach) unterschiedliche Versionen derselben Anwendung in vielen verschiedenen Arten von Datenbanken haben.
Punkt 3 ist sehr empfindlich, wenn Sie den Ruhezustand verwenden, wie wenn Sie eine neue boolesche oder numerische Eigenschaft einführen, wenn der Ruhezustand in solchen Spalten einen Nullwert findet, wenn eine Ausnahme ausgelöst wird.
Was ich also tun würde, ist: Verwenden Sie zwar die Kapazität der Hibernate-Tools für die Schemaaktualisierung, aber Sie müssen daneben einige Rückrufe für Daten und Schemawartung hinzufügen, z. B. zum Ausfüllen von Standardeinstellungen, Löschen nicht mehr verwendeter Spalten und Ähnliches. Auf diese Weise erhalten Sie die Vorteile (datenbankunabhängige Schemaaktualisierungsskripte und Vermeidung einer doppelten Codierung der Aktualisierungen, in der Peristenz und in Skripten), aber Sie decken auch alle Aspekte des Vorgangs ab.
Wenn eine Versionsaktualisierung beispielsweise einfach darin besteht, eine varchar-bewertete Eigenschaft (daher Spalte) hinzuzufügen, die standardmäßig null sein kann, sind Sie mit der automatischen Aktualisierung fertig. Wo mehr Komplexität erforderlich ist, ist mehr Arbeit erforderlich.
Dies setzt voraus, dass die Anwendung bei der Aktualisierung in der Lage ist, ihr Schema zu aktualisieren (dies ist möglich). Dies bedeutet auch, dass sie über die Benutzerrechte für das Schema verfügen muss. Wenn die Richtlinie des Kunden dies verhindert (wahrscheinlich Lizard Brain), müssen Sie die datenbankspezifischen Skripte bereitstellen.