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
- prendre en charge les transactions correctement isolées avec des
START TRANSACTION/COMMIT
blocs
- contrôle de DDL en écrivant vous-même le script DDL, en exécutant ce DDL en tant que constructeur ou destructeur
- Constructeur: DDL pour créer des tableaux avec un nouveau design
- Destructor: DDL pour faire revenir les tableaux à la conception précédente
- ne combinez jamais ces opérations sous un même emploi
AVERTISSEMENT: 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
- Espace disque logique du système
- Dictionnaire de données
- Double tampon d'écriture (prise en charge de la cohérence des données; utilisé pour la récupération après incident)
- Insérer un tampon (modifications des tampons vers des index secondaires non uniques)
- Segments de restauration
- Annuler l'espace (où la croissance la plus incontrôlée peut se produire)
- Piscine tampon InnoDB
- Pages de données sales
- Pages d'index sales
- Modifications des index non uniques
- Autres caches de mémoire importants
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é
- Courir
SET GLOBAL innodb_fast_shutdown = 0;
- Courir
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Courir
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Répétez l'étape 3 jusqu'à ce que Innodb_buffer_pool_pages_dirty soit 0 ou aussi proche de 0 que possible
service mysql stop
- Prendre un instantané LVM
service mysql stop
Si vous ne pouvez pas arrêter mais prendre un instantané avec MySQL Live
- Courir
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Courir
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Répétez l'étape 2 jusqu'à ce que Innodb_buffer_pool_pages_dirty soit 0 ou aussi proche de 0 que possible
- Prendre un instantané LVM
- Courir
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é
- Courir
SET GLOBAL innodb_fast_shutdown = 0;
- Courir
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Courir
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Répétez l'étape 3 jusqu'à ce que Innodb_buffer_pool_pages_dirty soit 0 ou aussi proche de 0 que possible
service mysql stop
- Prendre un instantané LVM
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
- Courir
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Courir
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Répétez l'étape 2 jusqu'à ce que Innodb_buffer_pool_pages_dirty soit 0 ou aussi proche de 0 que possible
- Exécuter
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
sur des tables critiques InnoDB
- Courir
FLUSH TABLES WITH READ LOCK;
- Prendre un instantané LVM
- Courir
UNLOCK TABLES;
- Courir
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écuter START 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
- Il est préférable d'utiliser plusieurs serveurs DB (3 ou plus) pour effectuer des restaurations et des tests de régression.
- Convertissez les tables MyISAM restantes en InnoDB si ces tables n'ont pas besoin de rester MyISAM.
- Si le contenu de vos données est sensible, vous devez exécuter un travail CI pour nettoyer les données après avoir restauré un instantané avant de lancer des tests. Vous pouvez également prendre des instantanés de MySQL avec les données déjà nettoyées.