改变巨大的MySQL表,可用磁盘空间很小

时间:2017-06-27 12:23:54

标签: mysql alter

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

是否有任何解决方案不需要原始表的完整复制(而是将数据移动到新表或类似的东西)?
我不在乎在更换桌子时无法访问桌子,桌子可以完全锁定几个小时而没有任何问题(我现在无法使用它)

2 个答案:

答案 0 :(得分:2)

由于你有271Gb的可用磁盘空间,如果几小时内没有访问表,你就可以了,请按照以下步骤操作:

  1. 创建一个新表格,然后tbl_temp ID BIGINTtbl_temp,保持剩余的表格结构完全相同。
  2. 创建一个简单的过程(您使用的任何服务器端脚本语言),它将从原始表中选择一行并将其插入tbl_temp
  3. 删除从原始表中插入的行。
  4. 插入所有行后,原始表格将为空。删除原始表
  5. $(document).ready(function () { var variante = $('.produs_varianta'); var produs_varianta = []; variante.each(function (index) { produs_varianta.push( { 'produs': $(this).find('.product_name').val(), 'cod': $(this).find('.product_code').val() } ); }); // NOW READ THE PRODUCTS AND ITS CODES. $.each(produs_varianta, function (key) { alert(produs_varianta[key].produs + ': ' + produs_varianta[key].cod); }); }); 重命名为原始表格。
  6. 这样您就可以使用现有磁盘空间迁移整个数据。

答案 1 :(得分:0)

我接受this answer from Samir,因为这是我意见的最佳解决方案,但我以稍微不同的方式解决了问题。我一开始没想到的是我们拥有对S3的AWS账户和(CLI)访问权限。所以,我做了以下几点:

  1. 对(原始)表中的所有数据进行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. 将原始表的create语句复制到记事本(我使用notepad ++)
  3. DROP原始表格(是的,完全是为了换新的表格)
  4. CREATE新表,完全与原始表名相同,使用更新的CREATE语句(实现我需要的新BIGINT定义)
  5. 使用之前创建的转储中的所有数据填充新表:
    aws s3 cp s3://bucket-name/mysqldump.sql.gz - | gzip -d | mysql db_name
  6. 这种方法优于Samir's answer的优势在于它不易出错,因为没有可编写脚本来使其工作。
    缺点是(我认为)由于额外的压缩,解压缩和网络传输,完成整个过程需要更长的时间。在我的情况下完成整个过程大约需要5天,而我认为Samir的解决方案应该更快,这就是我接受它的原因。