ALTER coluna de chave primária de INT para BIGINT em produção (MySQL 5.6.19a)

20

Algumas tabelas INNODB em nosso banco de dados de produção estão prestes a atingir o limite INT AUTO_INCREMENT de 2147483647 e precisamos alterá-las para BIGINT, caso contrário, as gravações começarão a falhar.

As tabelas estão em um banco de dados MySQL 5.6.19a de produção em execução no Amazon RDS.

Como podemos fazer um ALTER assim sem interromper as leituras e inserções da produção que estão acontecendo o tempo todo?

ALTER TABLE MYTABLECHANGE id idBIGINT NÃO NULL AUTO_INCREMENT;

Aqui está DDL para a tabela:

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
Mark Hansen
fonte

Respostas:

22

Se você tiver espaço suficiente, poderá criar uma cópia da tabela real e fazer o trabalho com isso:

CREATE TABLE new_tbl [AS] SELECT * FROM orig_tbl;

Em seguida, você pode alterar a coluna conforme desejado:

ALTER TABLE tbl_name MODIFY COLUMN col_name BIGINT AUTO_INCREMENT;

Depois que o processo estiver concluído, você poderá renomear as tabelas:

RENAME TABLE tbl_name TO new_tbl_name, tbl_name2 TO new_tbl_name2;

Largue a tabela original e você deverá obter o resultado esperado.

kriegu
fonte
Eu usei essa abordagem porque consegui desativar as gravações (que são todas em modo de lote) na tabela enquanto fazia a cópia. Demorou cerca de 36 horas.
Mark Hansen
e você deseja manter esses três em uma transação. (bloqueio / desbloqueio)
Sławomir Lenart
4

O kit de ferramentas percona é o caminho a percorrer, pelo menos se você não tiver um tempo super curto. A conversão tomou em nossa mesa (500Gb, configuração mestre-escravo) quando a testamos um pouco mais de 24h, na produção demorou (com hardware melhor) quase 1 mês (nota de rodapé engraçada que tínhamos cerca de 30 dias antes de ficarmos sem ids, portanto, já começamos a planejar os planos B e C, trabalhando com backups offline, removendo escravos, ...). O atraso ocorreu principalmente devido à espera da replicação em direção aos escravos (permitimos um atraso máximo de 50 segundos). Certifique-se também de limitar o número de threads simultâneos. Temos mais de 2 milhões de inserções / dia e muitos milhões de leituras.

Esteja ciente de que, uma vez iniciada a cobertura, você não poderá detê-la (ou pelo menos não encontramos nenhuma maneira de reiniciá-la) :-(

Labirinto
fonte
1

Bem....

KEY TOP_QUERIES_LAST_30DAYS_fk (siteId) é redundante com a PRIMARY KEY, então você também pode soltá-la.

INT UNSIGNED você chegaria a 4 bilhões, isso é suficiente?

Considere mudar filterpara um ENUM.

Você tem 1,75 bilhão de linhas? Ou você "queimou" muitos IDs? Se sim, talvez possamos consertar isso? Por exemplo, REPLACEe alguns sabores de INSERTIDs de lançamentos. INSERT...ON DUPLICATE KEYgeralmente pode substituir REPLACE. Um processo em duas etapas pode evitar INSERT IGNOREa queima de IDs.

Voltar à pergunta ...

Veja se pt-online-schema-change fará o truque: http://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html

Rick James
fonte
Posso usar o percona com o Amazon RDS? Sim, "queimamos" muitas IDs, a tabela na verdade tem cerca de 330 milhões de linhas.
Mark-Hansen #
Eu não sei sobre pt & RDS. Se você pudesse eliminar a queima, você teria outros ~ 330M ids antes de ficar sem espaço.
21715 Rick Rick