Comment gérez-vous les bases de données en développement, en test et en production?

171

J'ai eu du mal à trouver de bons exemples de gestion des schémas de base de données et des données entre les serveurs de développement, de test et de production.

Voici notre configuration. Chaque développeur dispose d'une machine virtuelle exécutant notre application et la base de données MySQL. C'est leur bac à sable personnel pour faire ce qu'ils veulent. Actuellement, les développeurs apporteront une modification au schéma SQL et effectueront un vidage de la base de données dans un fichier texte qu'ils valideront dans SVN.

Nous souhaitons déployer un serveur de développement d'intégration continue qui exécutera toujours le dernier code validé. Si nous faisons cela maintenant, il rechargera la base de données à partir de SVN pour chaque build.

Nous avons un serveur de test (virtuel) qui exécute des "release candidates". Le déploiement sur le serveur de test est actuellement un processus très manuel et implique généralement de charger le dernier SQL à partir de SVN et de le peaufiner. En outre, les données sur le serveur de test sont incohérentes. Vous vous retrouvez avec les données de test que le dernier développeur à s'engager avait sur son serveur sandbox.

Là où tout tombe en panne, c'est le déploiement en production. Étant donné que nous ne pouvons pas remplacer les données en direct par des données de test, cela implique de recréer manuellement toutes les modifications de schéma. S'il y avait un grand nombre de changements de schéma ou de scripts de conversion pour manipuler les données, cela peut devenir vraiment poilu.

Si le problème n'était que le schéma, ce serait un problème plus facile, mais il y a des données «de base» dans la base de données qui sont également mises à jour pendant le développement, comme les méta-données dans les tables de sécurité et d'autorisations.

C'est le plus gros obstacle que je vois dans la transition vers une intégration continue et des constructions en une étape. Comment le résolvez- vous ?


Une question de suivi: comment suivre les versions de base de données afin de savoir quels scripts exécuter pour mettre à niveau une instance de base de données donnée? Une table de version comme Lance mentionne-t-elle en dessous de la procédure standard?


Merci pour la référence à Tarantino. Je ne suis pas dans un environnement .NET, mais j'ai trouvé leur page wiki DataBaseChangeMangement très utile. Surtout cette présentation Powerpoint (.ppt)

Je vais écrire un script Python qui vérifie les noms des *.sqlscripts dans un répertoire donné par rapport à une table de la base de données et exécute ceux qui ne sont pas là dans l'ordre basé sur un entier qui forme la première partie du nom de fichier. Si c'est une solution assez simple, comme je suppose que ce sera le cas, je la posterai ici.


J'ai un script de travail pour cela. Il gère l'initialisation de la base de données si elle n'existe pas et exécute des scripts de mise à niveau si nécessaire. Il existe également des commutateurs pour effacer une base de données existante et importer des données de test à partir d'un fichier. Il fait environ 200 lignes, donc je ne le posterai pas (bien que je puisse le mettre sur pastebin s'il y a de l'intérêt).

Matt Miller
la source
"Je vais écrire un script Python qui vérifie les noms des scripts * .sql dans un répertoire donné par rapport à une table de la base de données et exécute ceux qui ne sont pas là dans l'ordre basé sur un entier qui forme la première partie de le nom du fichier. Si c'est une solution assez simple, comme je le soupçonne, je la posterai ici. " On dirait que vous implémentez une voie de migration.
masterxilo

Réponses:

53

Il y a quelques bonnes options. Je n'utiliserais pas la stratégie «restaurer une sauvegarde».

  1. Script toutes vos modifications de schéma et demandez à votre serveur CI d'exécuter ces scripts sur la base de données. Ayez une table de version pour garder une trace de la version actuelle de la base de données et n'exécutez les scripts que s'ils concernent une version plus récente.

  2. Utilisez une solution de migration. Ces solutions varient selon la langue, mais pour .NET, j'utilise Migrator.NET. Cela vous permet de versionner votre base de données et de monter et descendre entre les versions. Votre schéma est spécifié dans le code C #.

Lance Fisher
la source
28

Vos développeurs doivent écrire des scripts de modification (changement de schéma et de données) pour chaque bogue / fonctionnalité sur laquelle ils travaillent, et pas simplement vider la base de données entière dans le contrôle de code source. Ces scripts mettront à niveau la base de données de production actuelle vers la nouvelle version en développement.

Votre processus de génération peut restaurer une copie de la base de données de production dans un environnement approprié et exécuter tous les scripts du contrôle de code source dessus, ce qui mettra à jour la base de données vers la version actuelle. Nous faisons cela quotidiennement pour nous assurer que tous les scripts fonctionnent correctement.

tbreffni
la source
13

Regardez comment Ruby on Rails fait cela.

Il y a d'abord ce que l'on appelle les fichiers de migration, qui transforment essentiellement le schéma et les données de la base de données de la version N à la version N + 1 (ou en cas de rétrogradation de la version N + 1 à N). La base de données a une table qui indique la version actuelle.

Les bases de données de test sont toujours nettoyées avant les tests unitaires et remplies de données fixes provenant de fichiers.

Juha Syrjälä
la source
10

Le livre Refactoring Databases: Evolutionary Database Design pourrait vous donner quelques idées sur la façon de gérer la base de données. Une version courte est également lisible sur http://martinfowler.com/articles/evodb.html

Dans un projet PHP + MySQL, le numéro de révision de la base de données est stocké dans la base de données, et lorsque le programme se connecte à la base de données, il vérifie d'abord la révision. Si le programme nécessite une révision différente, il ouvrira une page pour mettre à niveau la base de données. Chaque mise à niveau est spécifiée dans le code PHP, ce qui modifiera le schéma de la base de données et migrera toutes les données existantes.

Esko Luontola
la source
5
  • Nommez vos bases de données comme suit - dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>>(Évidemment, vous ne devez jamais coder en dur les noms de base de données
  • Ainsi, vous seriez en mesure de déployer même les différents types de bases de données sur le même serveur physique (je ne le recommande pas, mais vous devrez peut-être ... si les ressources sont limitées)
  • Assurez-vous de pouvoir déplacer automatiquement les données entre celles-ci
  • Séparez les scripts de création de base de données de la population = Il devrait toujours être possible de recréer la base de données à partir de zéro et de la remplir (à partir de l'ancienne version de la base de données ou de la source de données externe
  • n'utilisez pas de chaînes de connexion de code en dur dans le code (même pas dans les fichiers de configuration) - utilisez dans les fichiers de configuration des modèles de chaîne de connexion, que vous remplissez dynamiquement, chaque reconfiguration de l'application_layer qui nécessite une recompilation est MAUVAISE
  • utilisez la gestion des versions de la base de données et des objets de la base de données - si vous pouvez vous le permettre, utilisez des produits prêts à l'emploi, sinon développez quelque chose par vous-même
  • suivre chaque modification DDL et l'enregistrer dans une table d'historique ( exemple ici )
  • Sauvegardes QUOTIDIENNES! Testez à quelle vitesse vous seriez en mesure de restaurer quelque chose de perdu à partir d'une sauvegarde (utilisez des scripts de restauration automatique
  • même votre base de données DEV et le PROD ont exactement le même script de création, vous aurez des problèmes avec les données, alors permettez aux développeurs de créer la copie exacte de prod et de jouer avec (je sais que je recevrai des inconvénients pour celui-ci, mais changez dans le l'état d'esprit et le processus métier vous coûteront beaucoup moins cher lorsque la merde frappe le fan - alors forcez les codeurs à souscrire légalement tout ce qu'ils font, mais assurez-vous que celui-ci
Yordan Georgiev
la source
Le dernier point est en effet l'humeur. Si c'est nécessaire, cela montre que la définition du projet est cassée. Le développement doit mener avant la production. Si les données de production induisent des effets secondaires, cela montre des problèmes plus importants. Nettoyez les données de production. Clarifiez également la dernière étape avec le délégué à la protection des données, s'il y a une raison - comme vous le suggérez - que les données en direct doivent être sur des systèmes de développement, vérifiez si cela est légalement applicable. De plus, une copie exacte des données de production ralentit dans une large mesure le développement et l'intégration. Envisagez un processus moins coûteux si vous ne pouvez pas vous permettre un tel luxe.
hakre
Le fait est que pendant le développement, il n'est tout simplement pas possible d'envisager tous les cas de coin dans le flux de contrôle et les variations de la qualité des données qui vont se produire en production. Si vous êtes dans un si grand corp, pour avoir des problèmes juridiques pour cela, une sorte de solution de brouillage et / ou de masquage des données doit être mise en œuvre, ce qui ajoute une couche supplémentaire de complexité, mais elle doit toujours préserver les aspects de qualité des données qui ont causé le bogue. en premier lieu de toute façon ...
Yordan Georgiev
4

C'est quelque chose dont je suis constamment insatisfait - notre solution à ce problème qui est. Pendant plusieurs années, nous avons maintenu un script de changement distinct pour chaque version. Ce script contiendrait les deltas de la dernière version de production. Avec chaque version de l'application, le numéro de version s'incrémenterait, donnant quelque chose comme ce qui suit:

  • dbChanges_1.sql
  • dbChanges_2.sql
  • ...
  • dbChanges_n.sql

Cela a assez bien fonctionné jusqu'à ce que nous ayons commencé à maintenir deux lignes de développement: Trunk / Mainline pour les nouveaux développements, et une branche de maintenance pour les corrections de bogues, les améliorations à court terme, etc. Inévitablement, le besoin s'est fait sentir de modifier le schéma dans la branche. À ce stade, nous avions déjà dbChanges_n + 1.sql dans le Trunk, donc nous avons fini par utiliser un schéma comme celui-ci:

  • dbChanges_n.1.sql
  • dbChanges_n.2.sql
  • ...
  • dbChanges_n.3.sql

Encore une fois, cela fonctionnait assez bien, jusqu'au jour où nous avons levé les yeux et vu 42 scripts delta dans la ligne principale et 10 dans la branche. ARGH!

De nos jours, nous maintenons simplement un script delta et laissons SVN la version - c'est-à-dire que nous écrasons le script à chaque version. Et nous évitons de faire des changements de schéma dans les branches.

Donc, je ne suis pas satisfait de cela non plus. J'aime beaucoup le concept des migrations depuis Rails. Je suis devenu assez fasciné par LiquiBase . Il prend en charge le concept de refactorisation incrémentielle de base de données. Cela vaut le coup d'œil et je vais bientôt l'examiner en détail. Quelqu'un en a-t-il l'expérience? Je serais très curieux de connaître vos résultats.

Matt Stine
la source
4

Vous pouvez également envisager d'utiliser un outil comme SQL Compare pour créer un script de la différence entre les différentes versions d'une base de données, ce qui vous permet de migrer rapidement entre les versions

Rad
la source
3

Nous avons une configuration très similaire à l'OP.

Les développeurs développent dans des VM avec des bases de données privées.

[Les développeurs s'engageront bientôt dans des succursales privées]

Les tests sont exécutés sur différentes machines (en fait dans des VM hébergées sur un serveur) [Sera bientôt exécuté par le serveur Hudson CI]

Testez en chargeant le vidage de référence dans la base de données. Appliquer les correctifs de schéma des développeurs puis appliquer les correctifs de données des développeurs

Exécutez ensuite les tests unitaires et système.

La production est déployée chez les clients en tant qu'installateurs.

Ce que nous faisons:

Nous prenons un vidage de schéma de notre base de données sandbox. Puis un vidage de données SQL. Nous différons cela de la ligne de base précédente. cette paire de deltas doit mettre à niveau n-1 en n.

nous configurons les dumps et les deltas.

Donc, pour installer la version N CLEAN, nous exécutons le vidage dans une base de données vide. Pour patcher, appliquez les patchs intermédiaires.

(Juha a mentionné que l'idée de Rail d'avoir une table enregistrant la version actuelle de la base de données est bonne et devrait rendre l'installation des mises à jour moins compliquée.)

Les deltas et les vidages doivent être examinés avant le test bêta. Je ne vois aucun moyen de contourner cela car j'ai vu des développeurs insérer des comptes de test dans la base de données pour eux-mêmes.

Tim Williscroft
la source
3

J'ai bien peur d'être d'accord avec d'autres affiches. Les développeurs doivent écrire leurs modifications.

Dans de nombreux cas, un simple ALTER TABLE ne fonctionnera pas, vous devez également modifier les données existantes - les développeurs doivent se demander quelles migrations sont nécessaires et s'assurer qu'elles sont correctement scriptées (bien sûr, vous devez tester cela attentivement à un moment donné dans le cycle de libération).

De plus, si vous avez le moindre sens, vous demanderez à vos développeurs de script des annulations de leurs modifications afin qu'elles puissent être annulées si nécessaire. Cela doit également être testé pour s'assurer que leur restauration ne s'exécute pas seulement sans erreur, mais laisse la base de données dans le même état que précédemment (ce n'est pas toujours possible ou souhaitable, mais c'est une bonne règle la plupart du temps) .

Comment vous connectez cela à un serveur CI, je ne sais pas. Peut-être que votre serveur CI doit avoir un instantané de construction connu sur lequel il revient chaque nuit, puis applique tous les changements depuis lors. C'est probablement mieux, sinon un script de migration cassé ne cassera pas seulement la construction de cette nuit, mais toutes les suivantes.

MarkR
la source
1

Consultez le dbdeploy , il existe déjà des outils Java et .net, vous pouvez suivre leurs normes pour les mises en page de fichiers SQL et la table des versions de schéma et écrire votre version python.

Dave Marshall
la source
1

Nous utilisons la ligne de commande mysql-diff : il génère une différence entre deux schémas de base de données (de la base de données en direct ou du script) en tant que script ALTER. mysql-diff est exécuté au démarrage de l'application, et si le schéma est modifié, il en rend compte au développeur. Les développeurs n'ont donc pas besoin d'écrire les ALTER manuellement, les mises à jour de schéma se font de manière semi-automatique.

stepancheg
la source
0

J'ai écrit un outil qui (en se connectant à Open DBDiff ) compare les schémas de base de données et vous suggérera des scripts de migration. Si vous effectuez un changement qui supprime ou modifie des données, il lancera une erreur, mais fournira une suggestion pour le script (par exemple, lorsqu'une colonne manque dans le nouveau schéma, il vérifiera si la colonne a été renommée et créera xx - généré script.sql.suggestion contenant une instruction de changement de nom).

http://code.google.com/p/migrationscriptgenerator/ SQL Server uniquement j'ai peur :( C'est aussi assez alpha, mais c'est TRÈS faible friction (surtout si vous le combinez avec Tarantino ou http://code.google .com / p / simplescriptrunner / )

La façon dont je l'utilise est d'avoir un projet de scripts SQL dans votre .sln. Vous avez également une base de données db_next localement dans laquelle vous apportez vos modifications (en utilisant Management Studio ou NHibernate Schema Export ou LinqToSql CreateDatabase ou quelque chose). Ensuite, vous exécutez migrationscriptgenerator avec les bases de données _dev et _next, ce qui crée. les scripts de mise à jour SQL pour la migration à travers.

mcintyre321
la source
0

Pour la base de données oracle, nous utilisons les outils oracle-ddl2svn .

Cet outil automatise le processus suivant

  1. pour chaque schéma de base de données, obtenir le schéma ddls
  2. le mettre sous contrôle de version

changements entre les instances résolus manuellement

popalka
la source