web-dev-qa-db-fra.com

Colonne de clé primaire ALTER de INT à BIGINT en production (MySQL 5.6.19a)

Certaines tables INNODB dans notre base de données de production sont sur le point d'atteindre la limite INT AUTO_INCREMENT de 2147483647 et nous devons les modifier en BIGINT sinon les écritures commenceront à échouer.

Les tables sont dans une base de données de production MySQL 5.6.19a fonctionnant sur Amazon RDS.

Comment pouvons-nous faire un ALTER comme celui-ci sans perturber les lectures et les insertions de production qui se produisent tout le temps?

ALTER TABLE MYTABLE CHANGE idid BIGINT NOT NULL AUTO_INCREMENT;

Voici DDL pour le tableau:

CREATE TABLE `MYTABLE` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `siteId` int(11) NOT NULL,
  `filter` varchar(10) NOT NULL DEFAULT 'ALL',
  `date` varchar(10) NOT NULL,
  `cards` varchar(250) NOT NULL,
  `apples` varchar(45) NOT NULL,
  `carrots` varchar(45) NOT NULL,
  `corn` varchar(45) NOT NULL,
  `peas` varchar(45) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique` (`siteId`,`filter`,`date`,`cards`),
  KEY `date_k` (`date`),
  KEY `cards_k` (`cards`),
  KEY `apples_k` (`apples`),
  KEY `siteId_k` (`siteId`)
) ENGINE=InnoDB AUTO_INCREMENT=1748961482 DEFAULT CHARSET=utf8
20
Mark Hansen

Si vous avez suffisamment d'espace, vous pouvez créer une copie de la table réelle et effectuer le travail à ce sujet:

CREATE TABLE new_tbl [AS] SELECT * FROM orig_tbl;

Ensuite, vous pouvez modifier la colonne comme vous le souhaitez:

ALTER TABLE tbl_name MODIFY COLUMN col_name BIGINT AUTO_INCREMENT;

Une fois le processus terminé, vous pouvez renommer les tables:

RENAME TABLE tbl_name TO new_tbl_name, tbl_name2 TO new_tbl_name2;

Déposez ensuite la table d'origine et vous devriez avoir le résultat espéré.

22
kriegu

percona toolkit est la voie à suivre, du moins si vous n'êtes pas très court dans le temps. La conversion a pris notre table (500 Go, configuration maître-esclave) lorsque nous l'avons testée un peu plus de 24h, en production, cela a pris (avec un meilleur matériel) près d'un mois (drôle de sidenote que nous avions environ 30 jours avant de manquer de ids, nous avons donc déjà commencé à planifier les plans B et C, en travaillant avec des sauvegardes hors ligne, en supprimant les esclaves, ...). Le retard était principalement dû à l'attente de la réplication se produisant vers les esclaves (nous avons autorisé un décalage de 50 secondes maximum). Assurez-vous également de limiter le nombre de threads simultanés. Nous avons plus de 2 millions d'inserts par jour et plusieurs millions de lectures.

Sachez également qu'une fois la conversion commencée, vous ne pouvez pas l'arrêter (ou du moins, nous n'avons trouvé aucun moyen de la redémarrer) :-(

4
Maze

Bien....

KEY TOP_QUERIES_LAST_30DAYS_fk (siteId) est redondant avec la PRIMARY KEY, vous pouvez donc aussi le supprimer.

INT UNSIGNED vous porterait à 4 milliards, cela suffira-t-il?

Pensez à remplacer filter par ENUM.

Avez-vous 1,75 milliard de lignes? Ou avez-vous "brûlé" beaucoup d'identifiants? Si oui, peut-être que nous pouvons résoudre ce problème? Par exemple, REPLACE et certaines versions de INSERT lanceront des identifiants. INSERT...ON DUPLICATE KEY peut généralement remplacer REPLACE. Un processus en deux étapes peut éviter INSERT IGNORE brûle des identifiants.

Retour à la question ...

Voyez si pt-online-schema-change fera l'affaire: http://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html

1
Rick James