Modification des colonnes de très grandes tables mysql avec peu ou pas de temps d'arrêt

18

Je dois périodiquement apporter des modifications aux tables dans mysql 5.1, principalement en ajoutant des colonnes. Très simple avec la commande alter table. Mais mes tables ont maintenant jusqu'à 40 millions de lignes et elles se développent rapidement ... Donc, ces commandes de modification de table prennent plusieurs heures. Dans quelques mois, cela prendra des jours, je suppose.

Étant donné que j'utilise amazon RDS, je ne peux pas avoir de serveurs esclaves avec lesquels jouer, puis promouvoir en tant que maître. Donc, ma question est de savoir s'il existe un moyen de le faire avec un temps d'arrêt minimal? Cela ne me dérange pas qu'une opération prenne des heures voire des jours si les utilisateurs peuvent toujours utiliser la base de données bien sûr ... Peuvent-ils au moins lire pendant l'ajout de colonnes? Que se passe-t-il si mon application essaie d'écrire? Insérer ou mettre à jour? S'il échoue immédiatement, ce n'est pas si grave, s'il se bloque et cause des problèmes au serveur de base de données, c'est un gros problème.

Cela doit être un problème de mise à l'échelle assez courant, tout le monde doit ajouter des colonnes. Que fait généralement une base de données de production? Esclave -> migration maître?

Mise à jour - J'ai oublié de mentionner que j'utilise le moteur de stockage innodb

apptree
la source
1
Au cas où quelqu'un chercherait toujours une réponse. Blog.staginginstance.com/… ^^
anonyme

Réponses:

10

Je dois périodiquement apporter des modifications aux tables dans mysql 5.1, principalement en ajoutant des colonnes.

Non. Pas vraiment. Mais ne le fais pas. Il devrait être une occasion très rare lorsque cela est toujours nécessaire.

En supposant que vos données soient normalisées au départ, la bonne façon de résoudre le problème consiste à ajouter une nouvelle table avec une relation 1: 1 à la table de base (non obligatoire sur la nouvelle table).

Devoir ajouter des colonnes régulièrement est généralement un indicateur d'une base de données qui n'est pas normalisée - si votre schéma n'est pas normalisé, c'est le problème que vous devez résoudre.

Enfin, si votre schéma est vraiment, vraiment normalisé et que vous devez vraiment, vraiment continuer à ajouter des colonnes alors:

  1. Assurez-vous que la base de données contient une colonne d'horodatage ou qu'elle génère des journaux de réplication
  2. Créez une copie (B) du tableau (A)
  3. ajouter les nouvelles colonnes à B (cela bloquera toujours avec myisam)
  4. désactiver les transactions
  5. renommer la table d'origine (A) en quelque chose d'autre (sauvegarde)
  6. renommer la nouvelle table (B) avec le nom de la table d'origine (A)
  7. relire les transactions depuis le début de l'opération à partir du journal de réplication ou de la table de sauvegarde
  8. activer les transactions.
symcbean
la source
2
Merci pour votre approche pas à pas. Est-il vraiment rare de modifier des tables? Je comprends que je peux à la place ajouter une autre table avec la nouvelle colonne (dans le cas où vous devez ajouter une colonne) et la faire référencer la grande table d'origine dans une relation 1: 1. Mais il ne semble pas juste d'avoir 15 très grandes tables 1: 1 alors qu'elles devraient toutes être dans une seule table ... Les performances d'interrogation souffrent alors également, sans parler des problèmes d'indexation. Je ne suis pas un expert, mais ma base de données est assez bien normalisée et il semble naturel que je
doive
2
"Est-il vraiment rare de modifier des tables?" - Oui.
symcbean
1
Non, mais on peut affirmer que si cela se produit RÉGULIÈREMENT - pas dans le cadre d'une mise à niveau logicielle majeure - alors quelqu'un doit être licencié pour ne pas avoir réalisé que toutes les tables devraient être là en premier lieu. Le problème / astuce ici est le "régulièrement", pas "une fois tous les deux mois".
TomTom
22
En tant que développeur, en particulier celui qui travaille dans les start-ups et les jeunes entreprises, je ne pourrais pas être moins d'accord avec symcbean et @TomTom. Les choses changent, les produits changent, les objectifs commerciaux changent et la structure de la base de données doit changer avec eux. Fournir un bon service DBA signifie dire «oui» à ces changements, puis trouver comment les mettre en œuvre efficacement. Les bases de données fortement normalisées sont un concept qui est mort il y a longtemps. Ils entraînent de mauvaises performances et des cycles de développement lents.
pents90
4
Peu fréquent de changer de table ??? Peut-être dans les grandes entreprises, mais dans une équipe agile qui arrive assez souvent, les exigences changent ...
tibo
12

Je devais juste le faire récemment. Ce qu'Amazon recommandait était d'utiliser le Percona Toolkit. Je l'ai téléchargé et j'ai pu exécuter quelque chose comme:

./pt-online-schema-change h=databasenameHostName,D=databasename,t=tablename --recursion-method=none --execute --user username --password password --alter "MODIFY someColumn newDataType"

et ça marche très bien. Il vous indique le temps restant dans le processus.

Il crée en fait une nouvelle table avec la nouvelle colonne, puis copie les données existantes. En outre, il crée un déclencheur afin que les nouvelles données soient également transférées vers la nouvelle table. Il renomme ensuite les tables automatiquement, supprime l'ancienne table et vous êtes opérationnel avec la nouvelle colonne et aucun temps d'arrêt pendant que vous attendez les mises à jour.

liberté
la source
L'équipe Percona a une courte description de l'activation de la fonctionnalité log_bin_trust_function_creators, via les groupes de paramètres RDS (car SET GLOBAL log_bin_trust_function_creators = 1 ne fonctionne pas sur RDS), requis par l'outil pt-online-schema-change. Plus de détails: percona.com/blog/2016/07/01/pt-online-schema-change-amazon-rds
user1652110
ça a marché pour moi
Adiii
4

symcbean fournit des recommandations solides .

Pour répondre à votre question, le moyen le plus simple et le meilleur d'atténuer l'impact consiste à répliquer plusieurs bases de données. Double maître avec une procédure de basculement appropriée arrêtant la réplication sur l'actif, ce qui permet une modification sur l'inactif sans impact sur l'actif.

Vous pouvez potentiellement le faire sur une seule base de données en direct et minimiser l'impact en utilisant une procédure similaire à celle que j'ai détaillée dans cette réponse . Certes, cela est similaire à ce que symcbean a décrit mais inclut des détails techniques. Vous pouvez également utiliser un champ auto_increment et pas seulement un horodatage.

En fin de compte, si votre ensemble de données devient si volumineux, vous devez également envisager l'archivage entre les bases de données OLTP et OLAP . Votre ensemble de données de transaction ne devrait pas avoir besoin d'être si grand, si vous le concevez de manière appropriée.

Warner
la source
2

Depuis le manuel: http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

Dans la plupart des cas, ALTER TABLE crée une copie temporaire de la table d'origine. MySQL incorpore l'altération dans la copie, puis supprime la table d'origine et renomme la nouvelle. Pendant l'exécution d'ALTER TABLE, la table d'origine est lisible par les autres sessions. Les mises à jour et les écritures dans la table sont bloquées jusqu'à ce que la nouvelle table soit prête, puis sont automatiquement redirigées vers la nouvelle table sans aucune mise à jour ayant échoué.

La lecture fonctionnera donc bien. Les écritures seront bloquées, mais exécutées par la suite. Si vous voulez éviter cela, vous devrez modifier votre logiciel.


la source
J'ai donc fait cela et désactivé les parties de mon site qui écrivent dans le tableau que je modifie en ce moment. Jusqu'à présent, j'ai reçu plusieurs exceptions «Délai d'attente de verrouillage dépassé; essayez de redémarrer la transaction», ce n'est pas trop mal. Cependant, ils étaient en opérations de lecture
PURE
0

Je suis dans une situation similaire où je dois modifier 1 de ma table de transactions qui fait presque 65 Go. J'entends 2 solutions

  1. Utilisez ALTER directement et laissez-le fonctionner (X heures ou jour)
  2. Assurez-vous que la base de données contient une colonne d'horodatage ou qu'elle génère des journaux de réplication
    • Créez une copie (B) du tableau (A)
    • ajouter les nouvelles colonnes à B (cela bloquera toujours avec myisam)
    • désactiver les transactions
    • renommer la table d'origine (A) en quelque chose d'autre (sauvegarde)
    • renommer la nouvelle table (B) avec le nom de la table d'origine (A)
user144107
la source