在生产中将主键列从 INT 更改为 BIGINT (MySQL 5.6.19a)

Mar*_*sen 25 mysql innodb

我们生产数据库中的一些 INNODB 表即将达到 2147483647 的 INT AUTO_INCREMENT 限制,我们需要将它们更改为 BIGINT,否则写入将开始失败。

这些表位于在 Amazon RDS 上运行的生产 MySQL 5.6.19a 数据库中。

我们如何在不中断一直发生的生产读取和插入的情况下执行这样的 ALTER 操作?

ALTER TABLE MYTABLECHANGE id idBIGINT NOT NULL AUTO_INCREMENT;

这是表的 DDL:

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
Run Code Online (Sandbox Code Playgroud)

kri*_*egu 24

如果您有足够的空间,您可以创建实际表的副本并对其进行处理:

CREATE TABLE new_tbl [AS] SELECT * FROM orig_tbl;
Run Code Online (Sandbox Code Playgroud)

然后您可以根据需要更改列:

ALTER TABLE tbl_name MODIFY COLUMN col_name BIGINT AUTO_INCREMENT;
Run Code Online (Sandbox Code Playgroud)

完成此过程后,您可以重命名表:

RENAME TABLE tbl_name TO new_tbl_name, tbl_name2 TO new_tbl_name2;
Run Code Online (Sandbox Code Playgroud)

然后删除原始表,您应该得到预期的结果。


小智 5

percona 工具包是要走的路,至少如果您的时间不是很短。当我们测试超过 24 小时时,转换在我们的桌子上进行(500Gb,主从设置),在生产中(使用更好的硬件)花了将近 1 个月(有趣的旁注,我们有大约 30 天的时间才能用完) ids,因此我们已经开始计划计划 B 和 C,使用离线备份,删除从属,......)。延迟主要是由于等待复制发生在从服务器上(我们允许最大 50 秒的时间延迟)。还要确保限制并发线程的数量。我们每天有超过 200 万次插入和数百万次读取。

另请注意,一旦开始覆盖,您就无法停止它(或者至少我们没有找到任何重新启动它的方法):-(