6 votes

URGENCE ! La déclaration de mise à jour d'une base de données de production mysql critique fonctionne depuis 18 heures, besoin d'aide.

Nous avons une table avec 500 millions de lignes. Malheureusement, l'une des colonnes était int(11), qui est un int signé, et il s'agissait d'une valeur incrémentale qui venait de dépasser le nombre magique de 2,1 milliards. Cela a immédiatement provoqué une interruption de service pour environ 10 000 utilisateurs. Nous avons discuté de nombreuses solutions, et avons décidé que nous pouvions simplement réduire cette valeur en toute sécurité, par exemple d'un milliard. Mais nous devions le faire pour chaque ligne.

Voici ce que nous avons fait :

mettre à jour Table1 Set MessageId = case when MessageId < 1073741824 then 0 else MessageId - 1073741824 end ;

Je l'ai testé sur un tableau de 10 millions de lignes et cela a pris 11 minutes. J'ai donc supposé que la plus grande table prendrait 550 minutes, soit 9 heures. Cela allait être notre plus grand temps d'arrêt en 3 ans. (Nous sommes une startup). Cela fait maintenant 18 heures.

Que devons-nous faire ?

S'il vous plaît, ne dites pas ce que nous aurions dû faire. Je pense que nous aurions dû mettre à jour quelques millions de lignes à la fois.

Y a-t-il un moyen de voir les progrès réalisés ? Mysql aurait-il pu se bloquer ? J'utilise mysql 5.0.22.

Merci !

1voto

tst Points 2290

Essayez de regarder la sortie de SHOW PROCESSLIST ; cela devrait vous donner une brève idée de ce qui se passe dans ce thread ; dans le pire des cas, vous pourriez tuer ce thread (en utilisant KILL $threadID) et ensuite faire le ménage manuellement.

HTH.

0voto

Alexis Lê-Quôc Points 343

Voulez-vous dire : mettre à jour Table1 Set MessageId = case when MessageId < 1073741824 then MessageId else MessageId - 1073741824 end ;

Sinon, je peux voir un tas de messages avec le même identifiant.

Une autre façon qui peut être plus rapide, au niveau sql :

create table new_table as
select (all other fields),
       case msg id > xxx then msg_id - 1000000 else msg_id
  from old_table;

De cette façon, vous pouvez scanner une table et écrire l'autre en une seule fois, au lieu de faire beaucoup d'entrées/sorties aléatoires (ce que vous pouvez vérifier avec iostat).

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X