Comment mettre une base de données sous git (contrôle de version)?

274

Je fais une application web, et j'ai besoin de créer une branche pour certains changements majeurs, le fait est que ces changements nécessitent des changements dans le schéma de la base de données, donc je voudrais également mettre toute la base de données sous git.

Comment je fais ça? y a-t-il un dossier spécifique que je peux conserver sous un référentiel git? Comment savoir lequel? Comment puis-je être sûr de mettre le bon dossier?

Je dois être sûr, car ces modifications ne sont pas rétrocompatibles; Je ne peux pas me permettre de bousiller.

La base de données dans mon cas est PostgreSQL

Éditer:

Quelqu'un a suggéré de prendre des sauvegardes et de placer le fichier de sauvegarde sous contrôle de version au lieu de la base de données. Pour être honnête, je trouve ça vraiment difficile à avaler.

Il doit y avoir une meilleure façon.

Mettre à jour:

OK, donc il n'y a pas de meilleur moyen, mais je ne suis toujours pas tout à fait convaincu, je vais donc changer un peu la question:

J'aimerais mettre toute la base de données sous contrôle de version, quel moteur de base de données puis-je utiliser pour pouvoir mettre la base de données réelle sous contrôle de version au lieu de son vidage?

Sqlite serait-il compatible avec git?

Comme ce n'est que l'environnement de développement, je peux choisir la base de données que je veux.

Edit2:

Ce que je veux vraiment, ce n'est pas de suivre mon historique de développement, mais de pouvoir passer de ma branche "nouveaux changements radicaux" à la "branche stable actuelle" et pouvoir par exemple corriger quelques bugs / problèmes, etc, avec le courant branche stable. De telle sorte que lorsque je change de branche, la base de données devient automatiquement compatible avec la branche sur laquelle je suis actuellement. Je ne me soucie pas vraiment des données réelles.

hasen
la source
5
Pour être honnête, je fais juste des copies de la base de données si j'introduis des modifications de schéma et que je dois gérer plusieurs branches de développement en même temps ... les bases de données de développement devraient être suffisamment petites pour cela. Je considérerais n'importe quel système qui a essayé d'être intelligent et d'effectuer des changements de base de données simplement parce que j'ai changé de branche source avec suspicion. Et j'aimerais également être sûr que les choses continueront à fonctionner si je clonais simplement mon espace de travail et que j'avais une branche à un endroit, et l'autre dans la nouvelle.
araqnid
Si vous considérez le script (et ses composants) pour initier votre base de données comme étant un artefact sous contrôle de version, alors les «sauvegardes» peuvent ne pas sembler une si mauvaise chose. Si vous modifiez votre schéma db dans une branche radicale, vous devez mettre à jour le script qui contient la base de données avec les données.
Fuhrmanator
1
Consultez ma réponse pour un logiciel qui fait exactement cela: stackoverflow.com/a/28123546/1662984
Kevin

Réponses:

140

Prenez un vidage de base de données et contrôlez la version à la place. De cette façon, c'est un fichier texte plat.

Personnellement, je vous suggère de conserver à la fois un vidage de données et un vidage de schéma. De cette façon, en utilisant diff, il devient assez facile de voir ce qui a changé dans le schéma d'une révision à l'autre.

Si vous effectuez des modifications importantes, vous devez disposer d'une base de données secondaire dans laquelle vous apportez les nouvelles modifications de schéma et ne pas toucher à l'ancienne car, comme vous l'avez dit, vous créez une branche.

X-Istence
la source
132
Quoi? Il doit y avoir un meilleur moyen.
hasen
18
Les fichiers de base de données PostGreSQL sont des fichiers binaires, n'hésitez pas à les placer dans votre référentiel git, vous ne pourrez tout simplement pas faire de différence avec eux, et tout changement modifiera très probablement toute la base de données et donc vous devez maintenant envoyer l'intégralité base de données sur le fil à votre dépôt git et le stocker. C'est inefficace, lent et il est extrêmement difficile de travailler avec. De plus, je ne suis pas sûr que les fichiers de base de données stockés sur le disque sans VIDE et arrêtant PostgreSQL pour en faire une copie soient "stables" car dans toutes les données, c'est toujours correct, ce qui peut vous laisser des données corrompues.
X-Istence
6
Hmm je vois! Eh bien, existe-t-il des systèmes db plus conviviaux pour git?
hasen
16
Ce type de solution est assez standard et le schéma est en fait du code source.
Dana the Sane
12
c'est 2017, des mises à jour sur cette question? n'y a-t-il en fait aucun contrôle de version DB prêt à l'emploi? vraiment ?
Stavm
48

Consultez Refactoring Databases ( http://databaserefactoring.com/ ) pour un tas de bonnes techniques pour maintenir votre base de données en tandem avec les changements de code.

Autant dire que vous posez les mauvaises questions. Au lieu de mettre votre base de données dans git, vous devriez décomposer vos modifications en petites étapes vérifiables afin de pouvoir migrer / restaurer les modifications de schéma en toute simplicité.

Si vous voulez avoir une récupérabilité complète, vous devriez envisager d'archiver vos journaux WAL postgres et utiliser le PITR (récupération ponctuelle) pour lire / transférer les transactions à des états spécifiques connus.

Paul Lindner
la source
2
Je n'ai pas trouvé d'informations pertinentes sur le site de refactoring de la base de données ... Il semble répertorier diverses techniques de refactoring pour le code DB (comme Fowler l'a fait pour le code normal)
Nickolay
26

Je commence à penser à une solution vraiment simple, je ne sais pas pourquoi je n'y avais pas pensé avant !!

  • Dupliquez la base de données (à la fois le schéma et les données).
  • Dans la branche pour les nouveaux changements majeurs, changez simplement la configuration du projet pour utiliser la nouvelle base de données en double.

De cette façon, je peux changer de branche sans me soucier des changements de schéma de base de données.

ÉDITER:

Par doublon, je veux dire créer une autre base de données avec un nom différent (comme my_db_2); ne pas faire de vidage ou quelque chose comme ça.

hasen
la source
3
Cela semble être la solution la plus simple et la plus efficace, mais ce serait bien s'il y avait un moyen d'automatiser cela ... Je suis surpris qu'il n'y ait pas encore quelque chose là-bas ...
JustMaier
git hook pour créer une base de données à partir du modèle basé sur le nom de la branche,
dalore
C'est ce que je fais, j'ajoute également une ligne de vérification IP au fichier d'inclusion pour les variables de base de données afin que si je télécharge accidentellement le "mauvais" fichier de la branche sur le serveur en direct, rien ne se casse.
liamvictor
donc à peu près chaque branche a sa propre base de données, hein? 🤔
olli
19

Utilisez quelque chose comme LiquiBase, cela vous permet de garder le contrôle des révisions de vos fichiers Liquibase. vous pouvez étiqueter les modifications pour la production uniquement et laisser lb maintenir votre base de données à jour pour la production ou le développement (ou selon le schéma que vous souhaitez).

zie
la source
3
Les meilleures pratiques de Liguibase recommandent de conserver les scripts de création de schéma comme un ensemble de scripts séquentiels à exécuter dans l'ordre. Bien que ce soit une bonne pratique, je ne vois pas comment cela fonctionnerait sans référentiel central, qui n'est pas GIT.
Frank Schwieterman
1
Eh bien, cela fonctionnerait très bien avec git si vous faites attention à vos balises id = et author =. En théorie, chaque utilisateur aurait sa propre entrée d'auteur (BON) et si vous faites quelque chose de raisonnable avec id =, dites YYYYMMDD_REV, alors vous êtes à peu près prêt. Même avec git, presque tout le monde a un 'repo central', pour un projet donné. 99% des gens n'ont pas quelque chose de «central». Encore une fois, les fichiers Liquibase ne sont que des fichiers de texte XML plan, avec une pile de commandes à exécuter sur une base de données (ou un ensemble de) donnée. Il y a de fortes chances que 99% de tous les projets aient 0 problème suite à cela dans la pratique, même avec DVCS.
zie
+1 Pour cette réponse. C'est ce que nous utilisons dans plusieurs projets. Les identifiants doivent être uniques dans un seul fichier xml. Si vous nommez les identifiants du cas d'utilisation en cours d'implémentation, ils sont suffisamment uniques. Vous devez faire attention à ne pas modifier les ensembles de modifications déjà appliqués, sinon vous obtiendrez des erreurs de somme de contrôle.
bernardn
7

Face à un besoin similaire et voici ce que ma recherche sur les systèmes de contrôle de version de base de données a révélé:

  1. Sqitch - open source basé sur perl; disponible pour toutes les principales bases de données, y compris PostgreSQL https://github.com/sqitchers/sqitch
  2. Mahout - uniquement pour PostgreSQL; contrôle de version de schéma de base de données open source. https://github.com/cbbrowne/mahout
  3. Liquibase - un autre contrôle de version db open source sw. version gratuite de Datical. http://www.liquibase.org/index.html
  4. Datical - version commerciale de Liquibase - https://www.datical.com/
  5. Flyway par BoxFuse - commercial sw. https://flywaydb.org/
  6. Un autre projet open source https://gitlab.com/depesz/Versioning Author fournit un guide ici: https://www.depesz.com/2010/08/22/versioning/
  7. Red Gate Change Automation - uniquement pour SQL Server. https://www.red-gate.com/products/sql-development/sql-change-automation/
Dharmendar Kumar «DK»
la source
Dans le passé, il y avait aussi quelque chose appelé ChronicDB: ChronicDB provides dynamic database upgrades with zero database downtime and inconsistencies. crunchbase.com/organization/chronicdb#section-overview Un gars nommé Kristis Makris était l'un des fondateurs, peut-être connu pour SCMBug: mkgnu.net/scmbug
Thorsten Schöning
6

Il y a un grand projet appelé Migrations under Doctrine qui a été construit à cet effet.

Son toujours en état alpha et construit pour php.

http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/index.html

Hakan Deryal
la source
ops! votre lien est rompu ... peut-être que vous voulez dire ceci: github.com/doctrine/migrations
Francesco Casula
ici les documents du bundle qui intègrent les migrations de doctrine dans Symfony2: symfony.com/doc/master/bundles/DoctrineMigrationsBundle/…
Francesco Casula
1
Merci pour l'astuce, les gars de Doctrine ont tendance à changer l'emplacement des documents, ce qui entraîne de nombreux liens rompus, ici et sur Google. Correction du lien.
Hakan Deryal
4

Je suis tombé sur cette question, car j'ai un problème similaire, où quelque chose se rapprochant d'une structure de répertoire basée sur une base de données, stocke des 'fichiers', et j'ai besoin de git pour le gérer. Il est distribué, à travers un cloud, en utilisant la réplication, donc son point d'accès se fera via MySQL.

L'essentiel des réponses ci-dessus semble suggérer de la même manière une solution alternative au problème posé, qui manque le point, d'utiliser Git pour gérer quelque chose dans une base de données, donc je vais essayer de répondre à cette question.

Git est un système qui, par essence, stocke une base de données de deltas (différences), qui peut être remontée, afin de reproduire un contexte. L'utilisation normale de git suppose que le contexte est un système de fichiers, et ces deltas sont des différences dans ce système de fichiers, mais vraiment tout git est, est une base de données hiérarchique de deltas (hiérarchique, car dans la plupart des cas, chaque delta est une validation avec au moins 1 parents, disposés dans un arbre).

Tant que vous pouvez générer un delta, en théorie, git peut le stocker. Le problème est normalement que git s'attend à ce que le contexte, sur lequel il génère des deltas, soit un système de fichiers, et de même, lorsque vous extrayez un point dans la hiérarchie git, il s'attend à générer un système de fichiers.

Si vous voulez gérer le changement, dans une base de données, vous avez 2 problèmes discrets, et je les aborderais séparément (si j'étais vous). Le premier est le schéma, le second les données (bien que dans votre question, vous déclarez que les données ne vous concernent pas). Un problème que j'ai eu dans le passé était une base de données Dev et Prod, où Dev pouvait apporter des modifications incrémentielles au schéma, et ces modifications devaient être documentées dans CVS, et propagées pour vivre, ainsi que des ajouts à l'un des nombreux `` statiques '' les tables. Nous l'avons fait en ayant une troisième base de données, appelée Cruise, qui ne contenait que les données statiques. À tout moment, le schéma de Dev et Cruise pouvait être comparé, et nous avions un script pour prendre la différence de ces 2 fichiers et produire un fichier SQL contenant des instructions ALTER, pour l'appliquer. De même, toute nouvelle donnée, pourrait être distillé dans un fichier SQL contenant des commandes INSERT. Tant que les champs et les tables sont uniquement ajoutés et jamais supprimés, le processus peut automatiser la génération des instructions SQL pour appliquer le delta.

Le mécanisme par lequel git génère des deltas est diffet le mécanisme par lequel il combine 1 ou plusieurs deltas avec un fichier, est appelé merge. Si vous pouvez trouver une méthode pour différer et fusionner à partir d'un contexte différent, git devrait fonctionner, mais comme cela a été discuté, vous préférerez peut-être un outil qui le fait pour vous. Ma première pensée pour résoudre ce problème est ce https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#External-Merge-and-Diff-Tools qui détaille comment remplacer le diff interne de git et outil de fusion. Je mettrai à jour cette réponse, car je trouverai une meilleure solution au problème, mais dans mon cas, je m'attends à ne devoir gérer que les modifications de données, dans la mesure où un magasin de fichiers basé sur une base de données peut changer, donc ma solution peut ne pas être exactement ce dont vous avez besoin.

sibaz
la source
3

Jetez un oeil à RedGate SQL Source Control.

http://www.red-gate.com/products/sql-development/sql-source-control/

Cet outil est un composant logiciel enfichable SQL Server Management Studio qui vous permettra de placer votre base de données sous contrôle de code source avec Git.

C'est un peu cher à 495 $ par utilisateur, mais un essai gratuit de 28 jours est disponible.

REMARQUE Je ne suis affilié à RedGate en aucune façon.

CShark
la source
3

Je veux faire quelque chose de similaire, ajouter mes modifications de base de données à mon système de contrôle de version.

Je vais suivre les idées de ce billet de Vladimir Khorikov " Bonnes pratiques de gestion des versions de base de données" . En résumé, je vais

  • stocker à la fois son schéma et les données de référence dans un système de contrôle de source.
  • pour chaque modification, nous créerons un script SQL séparé avec les modifications

Au cas où ça aide!

Ciges
la source
3
  • Irmin
  • Flur.ee
  • Crux DB

Je cherchais la même fonctionnalité pour Postgres (ou les bases de données SQL en général) depuis un certain temps, mais je n'ai trouvé aucun outil suffisamment adapté (simple et intuitif). Cela est probablement dû à la nature binaire de la façon dont les données sont stockées. Klonio semble idéal mais semble mort. Noms DB semble intéressant ( et vivant ). Jetez également un œil à Irmin (basé sur OCaml avec les propriétés Git).

Bien que cela ne réponde pas à la question dans la mesure où cela fonctionnerait avec Postgres, consultez la base de données Flur.ee. Il possède une fonction de "voyage dans le temps" qui vous permet d'interroger les données à partir d'un point arbitraire dans le temps. Je suppose qu'il devrait pouvoir fonctionner avec un modèle de "branchement".

Cette base de données était récemment en cours de développement à des fins de blockchain. En raison de la nature des chaînes de blocs, les données doivent être enregistrées par incréments, ce qui est exactement le fonctionnement de git. Ils visent une version open source au deuxième trimestre 2019 .

Étant donné que chaque base de données Fluree est une chaîne de blocs, elle stocke l'historique complet de chaque transaction effectuée. Cela fait partie de la façon dont une chaîne de blocs garantit que les informations sont immuables et sécurisées .

Mise à jour : consultez également la base de données Crux , qui peut interroger la dimension temporelle des insertions, que vous pourriez voir comme des «versions». Crux semble être une implémentation open-source du Datomic très apprécié.

Crux est une base de données bitemporelle qui stocke le temps de transaction et les historiques de temps valides. Alors qu'une base de données [uni] temporelle permet une requête de "voyage dans le temps" à travers la séquence transactionnelle des états de la base de données du moment de la création de la base de données à son état actuel, Crux fournit également une requête de "voyage dans le temps" pour un axe temporel valide discret sans complexité de conception inutile ou impact sur les performances. Cela signifie qu'un utilisateur Crux peut remplir la base de données avec des informations passées et futures, quel que soit l'ordre dans lequel les informations arrivent, et apporter des corrections aux enregistrements passés pour construire un modèle temporel en constante amélioration d'un domaine donné.

Queues
la source
2

Vous ne pouvez pas le faire sans atomicité, et vous ne pouvez pas obtenir l'atomicité sans utiliser pg_dump ou un système de fichiers instantané.

Mon instance postgres est sur zfs, que j'instantanés de temps en temps. C'est à peu près instantané et cohérent.

Dustin
la source
2

Ce que vous voulez, dans l'esprit, c'est peut-être quelque chose comme Post Facto , qui stocke les versions d'une base de données dans une base de données. Consultez cette présentation .

Le projet n'est apparemment jamais vraiment allé nulle part, il ne vous aidera probablement pas immédiatement, mais c'est un concept intéressant. Je crains que faire cela correctement soit très difficile, car même la version 1 devrait obtenir tous les détails pour que les gens lui fassent confiance.

Peter Eisentraut
la source
2

J'ai publié un outil pour sqlite qui fait ce que vous demandez. Il utilise un pilote de différenciation personnalisé exploitant l'outil de projets sqlite 'sqldiff', les UUID comme clés primaires, et laisse le sqlite rowid. Il est toujours en alpha, donc les commentaires sont appréciés.

Postgres et mysql sont plus délicats, car les données binaires sont conservées dans plusieurs fichiers et peuvent même ne pas être valides si vous pouviez les prendre en photo.

https://github.com/cannadayr/git-sqlite

cannadayr
la source
On dirait que vous laissez git stocker les données binaires telles quelles. Au lieu de cela, on pourrait utiliser des filtres de nettoyage / maculage pour stocker les vidages. Il y a quelques scripts qui le font.
max630
1
Approche décente, sauf lorsque vous différez deux états de base de données, vous effectuez un diff textuel du vidage. En utilisant sqldiff comme pilote de diff personnalisé, vous obtenez les commandes réelles pour faire passer votre base de données à l'état suivant.
cannadayr
1

Je pense que X-Istence est sur la bonne voie, mais vous pouvez apporter quelques améliorations supplémentaires à cette stratégie. Première utilisation:

$pg_dump --schema ... 

pour vider les tables, séquences, etc. et placer ce fichier sous contrôle de version. Vous l'utiliserez pour séparer les modifications de compatibilité entre vos branches.

Ensuite, effectuez un vidage de données pour l'ensemble des tables qui contiennent la configuration requise pour que votre application fonctionne (devrait probablement ignorer les données utilisateur, etc.), comme les valeurs par défaut du formulaire et d'autres données non modifiables par l'utilisateur. Vous pouvez le faire de manière sélective en utilisant:

$pg_dump --table=.. <or> --exclude-table=..

C'est une bonne idée, car le dépôt peut devenir très maladroit lorsque votre base de données atteint 100 Mo + lors d'un vidage de données complet. Une meilleure idée est de sauvegarder un ensemble de données plus minimal dont vous avez besoin pour tester votre application. Si vos données par défaut sont très volumineuses, cela peut néanmoins causer des problèmes.

Si vous devez absolument placer des sauvegardes complètes dans le référentiel, envisagez de le faire dans une branche en dehors de votre arborescence source. Un système de sauvegarde externe avec une référence au svn rev correspondant est probablement le meilleur pour cela.

En outre, je suggère d'utiliser des vidages de format texte sur binaire à des fins de révision (pour le schéma au moins) car ils sont plus faciles à différencier. Vous pouvez toujours les compresser pour économiser de l'espace avant de vous enregistrer.

Enfin, jetez un œil à la documentation de sauvegarde postgres si vous ne l'avez pas déjà fait. La façon dont vous commentez la sauvegarde de la base de données plutôt qu'un vidage me fait me demander si vous pensez aux sauvegardes basées sur le système de fichiers (voir la section 23.2 pour les mises en garde).

Dana la saine
la source
le vidage n'est-il pas juste une sauvegarde?
hasen
Oui, mais vous pouvez le restaurer dans une autre base de données et y apporter vos modifications.
Dana the Sane
1

Cette question est à peu près répondue, mais je voudrais compléter la réponse de X-Istence et Dana the Sane par une petite suggestion.

Si vous avez besoin d'un contrôle de révision avec un certain degré de granularité, disons quotidiennement, vous pouvez coupler le vidage de texte des tables et du schéma avec un outil comme rdiff-backup qui effectue des sauvegardes incrémentielles. L'avantage est qu'au lieu de stocker des instantanés de sauvegardes quotidiennes, vous stockez simplement les différences par rapport à la veille.

Avec cela, vous avez à la fois l'avantage du contrôle des révisions et vous ne perdez pas trop d'espace.

Dans tous les cas, utiliser git directement sur de gros fichiers plats qui changent très fréquemment n'est pas une bonne solution. Si votre base de données devient trop grande, git commencera à avoir des problèmes pour gérer les fichiers.

unode
la source
1

Voici ce que j'essaie de faire dans mes projets:

  • données et schéma séparés et données par défaut.

La configuration de la base de données est stockée dans un fichier de configuration qui n'est pas sous contrôle de version (.gitignore)

Les valeurs par défaut de la base de données (pour la configuration de nouveaux projets) sont un simple fichier SQL sous contrôle de version.

Pour le schéma de base de données, créez un vidage de schéma de base de données sous le contrôle de version.

La manière la plus courante consiste à disposer de scripts de mise à jour contenant des instructions SQL (ALTER Table .. ou UPDATE). Vous devez également avoir un endroit dans votre base de données où vous enregistrez la version actuelle de votre schéma)

Jetez un œil à d'autres grands projets de bases de données open source (piwik ou votre système cms préféré), ils utilisent tous des scripts de mise à jour (1.sql, 2.sql, 3.sh, 4.php.5.sql)

Mais ce travail demande beaucoup de temps, vous devez créer et tester les scripts de mise à jour et vous devez exécuter un script de mise à jour commun qui compare la version et exécuter tous les scripts de mise à jour nécessaires.

Donc, théoriquement (et c'est ce que je recherche), vous pouvez vider le schéma de la base de données après chaque modification (manuellement, conjob, git hooks (peut-être avant commit)) (et seulement dans certains cas très spéciaux, créer des scripts de mise à jour)

Après cela, dans votre script de mise à jour commun (exécutez les scripts de mise à jour normaux, pour les cas spéciaux), puis comparez les schémas (le vidage et la base de données actuelle), puis générez automatiquement les instructions ALTER nessaires. Il existe déjà quelques outils qui peuvent le faire, mais n'en ont pas encore trouvé un bon.

clé_
la source
1

Je recommanderais neXtep pour la version contrôlant la base de données, il a un bon ensemble de documentation et de forums qui explique comment installer et les erreurs rencontrées. Je l'ai testé pour postgreSQL 9.1 et 9.3, j'ai pu le faire fonctionner pour 9.1 mais pour 9.3 cela ne semble pas fonctionner.

Jerry M Sunny
la source
@Nickolay Oui, il semble avoir cessé. Comme alternative, pourquoi ne pas essayer Skitch, vous le trouverez ici sqitch.org
Jerry M Sunny
Merci, allez le vérifier!
Nickolay
1

Ce que je fais dans mes projets personnels, c'est que je stocke l'intégralité de ma base de données dans Dropbox, puis je pointe MAMP, le flux de travail WAMP pour l'utiliser directement à partir de là. Mais c'est juste pour le dev! Les sites en direct utilisent leur propre serveur pour cela, bien sûr! :)

Marko
la source
1

Le stockage de chaque niveau de modifications de la base de données sous le contrôle de version de git revient à pousser votre base de données entière à chaque validation et à restaurer votre base de données entière à chaque extraction. Si votre base de données est si sujette à des changements cruciaux et que vous ne pouvez pas vous permettre de les perdre, vous pouvez simplement mettre à jour vos hooks pre_commit et post_merge . J'ai fait de même avec l'un de mes projets et vous pouvez trouver les directions ici .

AkiShankar
la source
1

Voilà comment je le fais:

Puisque vous avez le choix libre sur le type de base de données, utilisez une base de données basée sur des fichiers comme par exemple Firebird.

Créez un modèle de base de données dont le schéma correspond à votre branche actuelle et stockez-le dans votre référentiel.

Lorsque vous exécutez votre application par programme, créez une copie de votre base de données de modèles, stockez-la ailleurs et travaillez simplement avec cette copie.

De cette façon, vous pouvez placer votre schéma de base de données sous contrôle de version sans les données. Et si vous changez votre schéma, il vous suffit de changer le DB de modèle

RomCoo
la source
1

Nous avions l'habitude d'exécuter un site Web social, sur une configuration LAMP standard. Nous avions un serveur Live, un serveur Test et un serveur de développement, ainsi que les machines des développeurs locaux. Tous ont été gérés à l'aide de GIT.

Sur chaque machine, nous avions les fichiers PHP, mais aussi le service MySQL, et un dossier avec des images que les utilisateurs téléchargeraient. Le serveur Live a grandi pour avoir environ 100K (!) Utilisateurs récurrents, le vidage était d'environ 2 Go (!), Le dossier Image était d'environ 50 Go (!). Au moment où je suis parti, notre serveur atteignait la limite de son processeur, Ram, et surtout, les limites de connexion nette simultanées (nous avons même compilé notre propre version du pilote de carte réseau pour maximiser le serveur 'lol'). Nous ne pouvions pas ( et vous ne devriez pas supposer avec votre site Web ) mettre 2 Go de données et 50 Go d'images dans GIT.

Pour gérer tout cela sous GIT facilement, nous ignorerions les dossiers binaires (les dossiers contenant les Images) en insérant ces chemins de dossier dans .gitignore. Nous avions également un dossier appelé SQL en dehors du chemin racine de document Apache. Dans ce dossier SQL, nous plaçons nos fichiers SQL des développeurs dans des numérotations incrémentielles (001.florianm.sql, 001.johns.sql, 002.florianm.sql, etc.). Ces fichiers SQL ont également été gérés par GIT. Le premier fichier sql contiendrait en effet un large ensemble de schémas DB. Nous n'ajoutons pas de données utilisateur dans GIT (par exemple, les enregistrements de la table des utilisateurs ou de la table des commentaires), mais des données comme les configurations ou la topologie ou d'autres données spécifiques au site ont été conservées dans les fichiers sql (et donc par GIT). Ce sont principalement les développeurs (qui connaissent le mieux le code) qui déterminent ce qui n'est pas maintenu par GIT en ce qui concerne le schéma et les données SQL.

Lorsqu'il est arrivé à une version, l'administrateur se connecte au serveur de développement, fusionne la branche en direct avec tous les développeurs et les branches nécessaires sur la machine de développement à une branche de mise à jour, et la pousse vers le serveur de test. Sur le serveur de test, il vérifie si le processus de mise à jour pour le serveur Live est toujours valide et, en succession rapide, pointe tout le trafic dans Apache vers un site d'espace réservé, crée un vidage de base de données, pointe le répertoire de travail de 'live' à 'update ', exécute tous les nouveaux fichiers sql dans mysql et redirige le trafic vers le site correct. Lorsque toutes les parties prenantes ont convenu après avoir examiné le serveur de test, l'administrateur a fait la même chose du serveur de test au serveur en direct. Par la suite, il fusionne la branche en direct sur le serveur de production, à la branche principale sur tous les serveurs, et rebasé toutes les branches en direct.

S'il y avait des problèmes sur le serveur de test, par exemple. les fusions ont eu trop de conflits, puis le code a été rétabli (pointant la branche de travail vers «live») et les fichiers sql n'ont jamais été exécutés. Au moment où les fichiers sql ont été exécutés, cela a été considéré comme une action non réversible à l'époque. Si les fichiers SQL ne fonctionnaient pas correctement, la base de données a été restaurée à l'aide du vidage (et les développeurs l'ont dit, pour avoir fourni des fichiers SQL mal testés).

Aujourd'hui, nous maintenons un dossier sql-up et sql-down, avec des noms de fichiers équivalents, où les développeurs doivent tester que les deux fichiers sql de mise à niveau peuvent être également rétrogradés. Cela pourrait finalement être exécuté avec un script bash, mais c'est une bonne idée si les yeux humains continuaient de surveiller le processus de mise à niveau.

Ce n'est pas génial, mais c'est gérable. J'espère que cela vous donnera un aperçu d'un site réel, pratique et relativement à haute disponibilité. Que ce soit un peu dépassé, mais toujours suivi.

Florian Mertens
la source
0

Utilisez un outil comme iBatis Migrations ( manuel , courte vidéo de didacticiel ) qui vous permet de contrôler la version des modifications que vous apportez à une base de données tout au long du cycle de vie d'un projet, plutôt que la base de données elle-même.

Cela vous permet d'appliquer de manière sélective des modifications individuelles à différents environnements, de conserver un journal des modifications contenant les changements dans quels environnements, de créer des scripts pour appliquer les modifications de A à N, des modifications de restauration, etc.

mat b
la source
0

J'aimerais mettre toute la base de données sous contrôle de version, quel moteur de base de données puis-je utiliser pour pouvoir mettre la base de données réelle sous contrôle de version au lieu de son vidage?

Cela ne dépend pas du moteur de base de données. Par Microsoft SQL Server, il existe de nombreux programmes de contrôle de version. Je ne pense pas que ce problème puisse être résolu avec git, vous devez utiliser un système de contrôle de version de schéma spécifique à pgsql. Je ne sais pas si une telle chose existe ou non ...

inf3rno
la source
2
Vous devriez vraiment jeter un coup d'œil à klonio, il est fait sur mesure pour les versions de bases de données (prend actuellement en charge Mongo et MySQL). Toujours en version bêta, mais semble assez prometteur.
farthVader