J'ai été un peu surpris de découvrir que les instructions DDL ( alter table
, create index
etc.) engagent implicitement la transaction actuelle dans MySQL. Venant de MS SQL Server, la possibilité de faire des modifications de base de données dans une transaction localement (qui a ensuite été annulée) était une partie importante de mon flux de travail. Pour une intégration continue, la restauration a été utilisée si la migration a eu un hoquet pour une raison quelconque, de sorte qu'au moins nous n'avons pas laissé la base de données dans un état semi-migré.
Comment les gens résolvent-ils ces deux problèmes lorsqu'ils utilisent MySQL avec des migrations et une intégration continue?
mysql
transaction
ddl
rollback
sennett
la source
la source
Réponses:
Pour de nombreuses personnes, le talon d'Achille MySQL est une validation implicite.
Selon la page 418, paragraphe 3, du livre
les commandes suivantes peuvent et vont interrompre une transaction
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP INDEX
DROP TABLE
RENAME TABLE
TRUNCATE TABLE
LOCK TABLES
UNLOCK TABLES
SET AUTOCOMMIT = 1
START TRANSACTION
SUGGESTION
En ce qui concerne MySQL, tous les travaux ContinuousIntegration (CI) / SelfService que vous construisez doivent toujours rendre les travaux transactionnels et les scripts DDL mutuellement exclusifs.
Cela vous donne la possibilité de créer des paradigmes qui
START TRANSACTION/COMMIT
blocsAVERTISSEMENT: si vous utilisez MyISAM pour tout cela, vous pouvez (dé) gentiment ajouter MyISAM à la liste des choses qui peuvent interrompre une transaction, peut-être pas en termes de validation implicite, mais certainement en termes de cohérence des données si un retour en arrière devait jamais être nécessaire.
POURQUOI PAS LVM?
Les instantanés LVM sont excellents et la restauration d'instances entières de bases de données sans avoir à effectuer un traitement SQL lourd est idéale. Cependant, en ce qui concerne MySQL, vous devez tenir compte de deux moteurs de stockage: InnoDB et MyISAM.
Base de données All-InnoDB
Regardez l'architecture d'InnoDB (avec l'aimable autorisation de Percona CTO Vadim Tkachenko)
InnoDB a de nombreuses pièces mobiles
Prendre un instantané LVM d'une base de données entièrement InnoDB avec des modifications non validées flottant dans le pool de tampons et les caches de mémoire produirait un ensemble de données qui nécessiterait une récupération après incident InnoDB une fois le LUN restauré et mysqld démarré.
SUGGESTION POUR TOUS-InnoDB
Si vous pouvez arrêter MySQL avant de prendre un instantané
SET GLOBAL innodb_fast_shutdown = 0;
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
service mysql stop
service mysql stop
Si vous ne pouvez pas arrêter mais prendre un instantané avec MySQL Live
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
SET GLOBAL innodb_max_dirty_pages_pct = 75;
Base de données All-MyISAM ou Mix InnoDB / MyISAM
MyISAM, lorsqu'il est consulté, conserve un nombre de descripteurs de fichiers ouverts par rapport à celui-ci. Si MySQL plante, toute table MyISAM avec un nombre de descripteurs de fichiers ouverts> 0 sera marquée comme crash et nécessitant une réparation (même si rien ne va pas avec les données).
Prendre un instantané LVM d'une base de données qui utilise des tables MyISAM aura une ou plusieurs tables MyISAM à réparer lorsque l'instantané est restauré et mysqld démarré.
SUGGESTION POUR All-MyISAM ou InnoDB / MyISAM Mix
Si vous pouvez arrêter MySQL avant de prendre un instantané
SET GLOBAL innodb_fast_shutdown = 0;
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
service mysql stop
service mysql stop
Si vous ne pouvez pas arrêter mais prendre un instantané avec MySQL Live
Vous pouvez appliquer un vidage de certaines tables InnoDB
SET GLOBAL innodb_max_dirty_pages_pct = 0;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
sur des tables critiques InnoDBFLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
SET GLOBAL innodb_max_dirty_pages_pct = 75;
La réplication MySQL pourrait-elle aider?
Bien que vous puissiez restaurer un instantané LVM sur deux serveurs et configurer la réplication maître / esclave MySQL, cela devient une source supplémentaire de nettoyage lors de la restauration des instantanés.
Si vous exécutez des travaux CI sur un maître et que ces travaux sont petits, la réplication peut être un gain de temps dans certaines circonstances. Vous pouvez simplement exécuter
STOP SLAVE;
sur l'esclave, lancer les travaux CI sur le maître et exécuterSTART SLAVE;
sur l'esclave lorsque les données du maître sont certifiées.Si les travaux CI alertent trop de données, vous pouvez restaurer un instantané LVM et configurer la réplication à partir de zéro. Si vous faites cela souvent, vous pourriez probablement le faire avec la configuration de la réplication MySQL.
DERNIÈRES PENSÉES
la source
Si vous parlez d'intégration continue, je suppose que c'est un environnement de développement. Dans ce cas, je dirais que la personne qui effectue des changements structurels doit les tester pour s'assurer de ne pas casser les choses pour les autres, de la même manière que quelqu'un qui met à jour une bibliothèque commune: testez dans votre propre bac à sable avant de valider de telles modifications.
Dans un processus de déploiement en production, vous passez généralement par des environnements de développement, d'assurance qualité ou même de pré-production pour tester vos modifications, de la même manière que pour toute modification de code.
Notez que ce n'est pas spécifique à MySQL: les bases de données Oracle feraient aussi implicitement COMMIT lors de l'émission de 'alter table' etc.
Maintenant, si vous voulez vous protéger, vous pouvez bien sûr faire une sauvegarde au préalable, ou un instantané LVM ou système de fichiers si votre système peut le faire. Vous pouvez également avoir un esclave que vous pourriez retarder / arrêter comme sécurité avant les opérations sensibles.
la source