改变巨大的 MySQL table 和很少的可用磁盘 space

Alter huge MySQL table with little free disk space

我在 ALTER 一个巨大的 (InnoDB) MySQL table 中遇到了一些麻烦。 table(主键)的 ID 列被定义为 UNSIGNED INT 但达到了最大值 (4294967295)。
为了能够向此 table 添加更多行,我需要将此列的类型调整为 BIGINT。但是,标准的 MySQL ALTER 命令(以及我目前发现的任何其他解决方案)将尝试使用新定义生成新的 table,然后将所有数据复制到其中.对于本例中的 table,这需要 942.0Gb 的可用磁盘 space,而我只有 271Gb 可用(并且没有其他分区确实具有所需的可用磁盘 space) .

是否有不需要完整复制原始 table 的解决方案(而是将数据移动到新的 table 或类似的东西)?
我不在乎table在被修改时无法访问,table可以完全锁定几个小时没有问题(反正我现在不能使用它) .

由于您有 271Gb 的可用磁盘 space,如果 table 几个小时内没有被访问也没关系,请按照以下步骤操作:

  1. 创建一个新的 table 让我们说 tbl_tempID 作为 BIGINT 保持剩余的 table 结构完全相同。
  2. 创建一个简单的进程(您使用的任何服务器端脚本语言),它将 select 来自原始 table 的一行并将其插入 tbl_temp.
  3. 删除从原来插入的行table。
  4. 插入所有行后,您的原始 table 将为空。删除原来的table
  5. tbl_temp 重命名为原来的 table。

这样您就可以使用现有磁盘迁移整个数据 space。

我接受了 ,因为它是我认为的最佳解决方案,但我以稍微不同的方式解决了这个问题。一开始我没有想到的是,我们有一个 AWS 帐户和 (CLI) 访问 S3。所以,我做了以下事情:

  1. 对(原始)table 中的所有数据进行 mysqldump 并将其直接流式传输到 S3(因为我没有太多磁盘空间来存储本地转储)。
    mysqldump -f --no-create-info --lock-tables db_name table_name | gzip -c | aws s3 cp - s3://bucket-name/mysqldump.sql.gz --expected-size 130608821125
  2. 将原来table的create语句复制到记事本中(我用的是notepad++)
  3. DROP原来的table(是的,完全是为了给新的腾出地方)
  4. CREATE 新的 table, 与原来的名称完全相同,使用更新的 CREATE 语句(实现新的 BIGINT 我需要的定义)
  5. 用之前创建的转储中的所有数据填充新 table:
    aws s3 cp s3://bucket-name/mysqldump.sql.gz - | gzip -d | mysql db_name

相比,此方法的优势在于不易出错,因为无需编写脚本即可完成此操作。
缺点是(我认为)完成整个过程需要更长的时间,因为需要额外的压缩、解压和网络传输。就我而言,完成整个过程大约需要 5 天,而我认为 Samir 的解决方案应该更快,这就是我接受它的原因。