Schemaverwaltung mit Skeema

Veröffentlicht: 2019-04-26

Hinweis: Dieser Beitrag stammt vom Engineering-Team von SendGrid. Weitere technische Beiträge wie diesen finden Sie in unserer technischen Blogroll.

Die Verwaltung von Datenbankschemata reicht von einem wilden Westen, den jeder im Produktionsprozess „live machen“ kann, bis hin zu einem wasserfallähnlichen mehrstufigen Überprüfungsprozess mit mehreren Teams, bei dem nur eine gesalbte Person die Produktionsdatenbank berühren kann.

Da die in relationalen Datenbanken enthaltenen Daten für ein Unternehmen immer wertvoller werden und die Verfügbarkeit der Datenbank für das Unternehmen immer wichtiger wird, tauchen Hindernisse für potenziell brechende Schemaänderungen auf.

Schon früh wurden Datenbankadministratoren (DBAs) zu Gatekeepern der Datenbank, um die Datenbank vor schädlichen Ereignissen zu schützen. Aber einen DBA der alten Schule zwischen Entwicklern und der Datenbank ihrer Anwendung sitzen zu haben, kann den Entwicklungslebenszyklus einer Anwendung erheblich verlangsamen, Entwicklungs- und Betriebssilos schaffen und Reibungen zwischen Teams erzeugen.

In der heutigen Mikroservice-Dev-Ops-orientierten Welt müssen Entwickler in der Lage sein, Datenbankschemaänderungen selbst zu verwalten, da es sich um ihre Daten handelt und sie letztendlich für die Leistung und Betriebszeit der Anwendung verantwortlich sind. DBAs und Betriebsteams müssen geeignete Tools und Ratschläge bereitstellen, um Entwicklungsteams dabei zu unterstützen, Eigentümer ihrer Datenbank zu werden.

Wie wir Schema verwalten

Unser aktueller Schemaverwaltungsprozess verwendet ein einziges Git-Repository, um das anfängliche Schema für alle unsere Datenbankcluster zu speichern, und enthält alle nachfolgenden Änderungen an diesem Schema, wenn einzelne Tabellenänderungen/-erstellungen und -löschungen angewendet werden:

  • Ein Entwickler nimmt lokal eine Schemaänderung vor und generiert eine Alter/Create/Drop-Anweisung und fügt sie als Pull-Request zu einem Integrationszweig hinzu.
  • Eine Reihe von Jira-Tickets für das Data Operations-Team wird erstellt, um die Schemaänderungen zu überprüfen und auf unsere Test-/Staging- und Produktionsumgebungen anzuwenden.
  • Ein Mitglied des Data Operations-Teams überprüft die angeforderte Änderung, wendet die Änderung auf die Test-/Staging-Umgebung an und führt den PR mit dem Integrationszweig zusammen.
  • Der anfordernde Entwickler testet die Änderung in unseren Test-/Staging-Umgebungen und genehmigt die Änderung, die in die Produktion übertragen werden soll.
  • Schließlich führt Data Operations den Integrationszweig mit dem Master zusammen und wendet die Schemaänderung auf die Produktionsumgebung an.

Angesichts des Wertes der in unseren Datenbanken gespeicherten Daten und des Wunsches, dass diese Datenbanken jederzeit gut funktionieren, haben wir uns für diese byzantinische Abfolge von Ereignissen entschieden, um uns vor uns selbst zu schützen.

Der Schutz der Datenbank ist eine Sache, aber dieser Prozess bringt mehrere Hürden mit sich, um Schemaänderungen auf zuverlässige und effiziente Weise vorzunehmen:

  • Das Überprüfen und Vornehmen von Schemaänderungen erfolgt zweimal wöchentlich und kann leicht entgleisen, da mehrere Teams an verschiedenen Datenbanken im selben Git-Repository arbeiten und jeder darauf angewiesen ist, dass jemand im Data Operations-Team verschiedene Umgebungen überprüft und Änderungen daran vornimmt.
  • Ein einziges Repository für alle Schemata relationaler Datenbanken zu haben, kann zu schwierigen Freigabeprozessen führen. Eine Änderung an einem Schema, das für die Produktion bereit ist, kann nicht in die Produktion gehen, wenn es andere Schemaänderungen gibt, die nicht bereit sind, in die Produktion gepusht zu werden, sich aber im Staging befinden und auf zusätzliche Tests warten.
  • Das Data Operations-Team, bei dem es sich um ein kleines Team handelt, wird zu einem Engpass, wenn es darum geht, zu verwalten, welche Änderungen wann in die Produktion gehen können und welche nicht. Planungskonflikte und Personalverfügbarkeit können die Veröffentlichung neuer Funktionen oder Korrekturen für aktuelle Anwendungen erheblich verlangsamen.
  • Wir wenden diese Änderungen manuell auf Produktionssysteme an, indem wir Kommentare in Pull-Requests und Jira-Tickets verwenden; Manchmal kann das Kopieren und Einfügen schrecklich schief gehen.

Auftritt Skeema (und ein paar Helfer)

Um diese Prozesshürden zu beseitigen, Schemaänderungen weniger anfällig für menschliche Fehler zu machen, Entwicklern die Verwaltung des Schemas ihrer eigenen Anwendung zu ermöglichen und möglicherweise die Entwicklungsgeschwindigkeit zu erhöhen, hat das Data Operations-Team große Anstrengungen unternommen, um die Verwaltung von zu automatisieren und zu rationalisieren Datenbankschema.

Wir haben die Anwendung von Schemaänderungen von der lokalen Entwicklung bis zur Produktion mithilfe unserer vorhandenen Tools Git, Buildkite CI und pt-online-schema-change automatisiert und Skeema um ein weiteres erweitert.

Die Idee ist, unser monolithisches DB-Schema-Repository in einzelne Schema-Repositorys aufzuteilen, eines pro Datenbank-Cluster, und es Entwicklern zu ermöglichen, ihre eigenen Schemaänderungen in einer ihnen vertrauten Umgebung vorzunehmen. Wir möchten auch vernünftige Leitplanken haben, um Entwicklern zu helfen, zusätzliche Unterstützung zu suchen, wenn sie große, komplexe oder potenziell destruktive Schemaänderungen vornehmen.

Skeema ist ein CLI-Tool, das das MySQL-Schema deklarativ mit SQL verwaltet.

Es kann die Data Definition Language (DDL) für jede Tabelle in einer Datenbank generieren und die DDL in ein lokales Dateisystem zur Integration mit einem Tracking-Repository über Git exportieren. Skeema kann die SQL-Dateien in einem Git-Repository mit einer aktiven MySQL-Datenbank vergleichen und diese Unterschiede als DDL-Anweisungen ausgeben.

Es kann auch so konfiguriert werden, dass es das pt-online-schema-change-Tool von Percona verwendet und den erforderlichen pt-online-schema-change-Befehl formatiert, um das Schema der laufenden MySQL-Datenbank mit dem im Git-Repository definierten Schema abzugleichen.

Skeema ist auch in der Lage, Schemas in mehreren Umgebungen zu verwalten, wie lokal, Test und Produktion mit jeweils unterschiedlichen Konfigurationen. Und schließlich kann es leicht an einen Pull-Request-basierten Workflow angepasst werden.

Das Erstellen individueller Schema-Repositories für MySQL-Datenbanken wird unser aktuelles monolithisches db-schema-Git-Repository aufschlüsseln und es Entwicklern in separaten Teams ermöglichen, das MySQL-Schema ihrer Anwendung in ihrem eigenen Repository anstelle eines gemeinsam genutzten Repositorys (db-schema) zu verwalten.

Ein separates Repository für jedes Datenbankschema ermöglicht dem Anwendungsentwicklungsteam eine größere Autonomie. Dadurch entfällt die Notwendigkeit, alle Schemaänderungen nach einem starren Zeitplan zu koordinieren, und Änderungen können nach Wunsch des Anwendungsteams in die Produktion verschoben werden.

Eine wichtige Komponente zur Automatisierung dieses Prozesses ist die CI-Pipeline von Buildkite. Wir haben eine Pipeline erstellt, die:

  • Prüft auf SQL-Syntaxfehler
  • Erstellt einen Test-MySQL-Server unter Verwendung des aktuellen Master-Zweigs des Datenbankschemas und testet die Anwendung der Änderungen in der Pull-Anforderung (PR).
  • Überprüfen Sie die Unterschiede und wenden Sie die PR-Änderungen auf unsere MySQL-Testumgebung an
  • Überprüfen Sie die Unterschiede und wenden Sie die PR-Änderungen auf unsere Staging-Umgebung an und geben Sie einige Tabellenstatistiken aus der Produktionsumgebung aus

Die Produktionsausgabestatistiken umfassen die Tabellengröße auf dem Datenträger und die geschätzte Zeilenanzahl. Diese Statistiken können bei der Bestimmung helfen, ob die Schemaänderung zu einer gewissen Dienstunterbrechung führen könnte und möglicherweise eine besondere Behandlung erfordert. Sobald der PR mit dem Master zusammengeführt wurde, prüft die Buildkite-Pipeline Unterschiede zwischen dem Master-Branch und dem, was in der Produktion ausgeführt wird.

Wenn es sich bei den Unterschieden um die erwarteten Änderungen gegenüber dem PR handelt, kann der Entwickler diesen letzten Schritt entsperren und Skeema wendet die Änderungen auf den Produktions-MySQL-Datenbankcluster an. Jeder dieser Schritte ist ein blockierender Schritt, der eine Genehmigung durch das für die angeforderte Änderung verantwortliche Engineering-Team erfordert, bevor mit dem nächsten Schritt fortgefahren werden kann.

In Bezug auf die Leitplanken haben wir Skeema so konfiguriert, dass es standardmäßig keine destruktiven Schemaänderungen in der Produktion zulässt.

Destruktive Änderungen sind in unseren Test- und Staging-Umgebungen erlaubt.

Wir haben Skeema auch so konfiguriert, dass es pt-online-schema-change verwendet, um Schemaänderungen vorzunehmen. Dies ist dasselbe Schemaänderungstool, mit dem das DataOps-Team vertraut ist und das seit vielen Jahren bei SendGrid verwendet wird. Wir haben eine Reihe vernünftiger Optionen für pt-online-schema-change entwickelt, um seine Änderungen rückgängig zu machen, wenn die Replikation ins Hintertreffen gerät oder aktive Threads in der Datenbank übermäßig werden.

Durch die Konfiguration von Skeema auf diese Weise werden die potenziellen Fehler beseitigt, die durch manuelle Schritte für die Anwendung und die manuelle Codierung von pt-online-schema-change-Befehlen durch DataOps-Teammitglieder entstehen.

Durch das Hinzufügen programmatischer Sicherheitsvorkehrungen können einzelne Teams mit relativer Sicherheit für die Verwaltung ihrer MySQL-Datenbankschemas und die Anwendung dieser Änderungen in Vorproduktions- und Produktionsumgebungen verantwortlich sein. Wenn Leitplanken getroffen werden, schlägt die Schemaänderung fehl und wird rückgängig gemacht. Gründe für das Scheitern der Schemaänderung werden zur weiteren Überprüfung in die Erstellungsprotokolle ausgegeben.

Entwicklern die Möglichkeit zu geben, ihre Änderungen vom lokalen Test auf einem Laptop bis zur Produktion zu übertragen, verbessert die Autonomie der Entwickler und den Besitz der Datenbank, die ihre Anwendung unterstützt. Die Automatisierung und Integration von Skeema in unseren MySQL-Datenbankverwaltungsprozess deckt problemlos etwa neunzig Prozent unserer allgemeinen Schemaänderungsverwaltungsaufgaben ab.

Die meisten Schemaänderungen dienen dem Hinzufügen von Spalten, dem Ändern von Aufzählungsfeldern, dem Ändern von Standardwerten und dem Hinzufügen von Indizes. Die restlichen zehn Prozent der Schemaänderungen betreffen Sonderfälle von großen Tabellen, sehr aktiven Datenbanken oder partitionierten Tabellen. Zum jetzigen Zeitpunkt befasst sich Skeema noch nicht mit Schemaänderungen an partitionierten Tabellen, aber ich höre, dass es sich um eine häufig angeforderte Ergänzung handelt und der Entwickler von Skeema aktiv um Hilfe bei der Implementierung dieser Funktion bittet.

Die Kombination von Git, pt-online-schema-change, Skeema und einer Buildkite-CI-Pipeline bringt einen zuverlässigen, wiederholbaren, programmgesteuerten Prozess für Änderungen des MySQL-Datenbankschemas. Es versetzt Entwickler in die Lage, das Schema ihrer Datenbanken sicher zu verwalten und zu steuern, wie schnell Features und Fixes in die Produktion eingeführt werden.

Das Einfügen geeigneter Leitplanken in die Konfigurationsdateien für Skeema- und pt-online-Schemaänderungen gibt Entwicklern, die Schemaänderungen implementieren, ein gewisses Maß an Vertrauen und gibt wertvolles Feedback zu möglichen Wegen, mit der Schemaänderung fortzufahren, wenn diese Leitplanken getroffen werden.

Das Data Operations-Team steht weiterhin zur Verfügung, um die verbleibenden zehn Prozent der Fälle zu unterstützen, auf die dieser Prozess nicht angewendet werden kann, und wird an zusätzlichen Tools arbeiten, um diesen Prozess in Zukunft zu verbessern.