use*_*891 9 mysql ruby-on-rails alter
我有一个包含不到 5000 万行的表。它达到了 INT 的限制 (2147483647)。目前该表尚未被写入。
我计划将 ID 列从 INT 更改为 BIGINT。我正在使用 Rails 迁移通过以下迁移来执行此操作:
def up
execute('ALTER TABLE table_name MODIFY COLUMN id BIGINT(8) NOT NULL AUTO_INCREMENT')
end
Run Code Online (Sandbox Code Playgroud)
我已经在 2000 行的数据集上进行了本地测试,效果很好。在 5000 万条上运行ALTER TABLE命令应该没问题,因为目前该表没有被使用?
我想在运行迁移之前进行检查。任何意见将不胜感激,谢谢!
我们有完全相同的场景,但是使用 postgresql,我知道 50M 如何填充 int 的整个范围,它在 ids 中的间隙,随着时间的推移删除行或涉及不完整事务的其他因素产生的间隙等。
我将解释我们最终做了什么,但首先,严肃地说,在 2k 行上测试 50M 行的数据迁移并不是一个好的测试。
这个问题可以有多种解决方案,具体取决于您使用哪个数据库提供商等因素?我们使用的是 mazon RDS,它对运行时以及他们所说的 IOPS(输入/输出操作)有限制,如果我们在具有此类限制的数据库上运行如此密集的查询,它将在中途耗尽其 IOPS 配额,并且当 IOPS 配额达到时耗尽了,数据库最终变得太慢而且毫无用处。我们必须取消查询,让 IOPS 赶上,这大约需要 30 分钟到 1 小时。
如果您可以承受停机时间并且数据库上没有 IOPS 类型限制,您可以直接运行此查询,这将花费大量时间(可能半小时左右,取决于很多因素),同时
就我而言,当我们意识到表中还剩下大约 40M 个 id 时,我们希望避免停机。因此我们采取了多步骤的方法:
new_id从id列中回填列。我们每晚回填大约 4-5M 行,周末回填更多(因为我们的应用程序在周末没有流量)。nextval的 new_id 列。上面是我们所做的最小的记录,你可以在谷歌上搜索一些关于它的好文章,其中之一就是这个。这种方法并不新鲜,而且很常见,所以我相信你也会找到 mysql 特定的方法,或者你可以在上面的文章中调整一些东西,你应该可以开始了。