Rails,如何迁移大量数据?

时间:2012-07-20 23:48:15

标签: ruby ruby-on-rails-3 database-migration

我有一个运行较旧版本的spree(一个开源购物车)的rails 3应用程序。我正在将其更新到最新版本。这要求我在数据库上运行大量迁移以与最新版本兼容。然而,应用程序当前数据库大约为300mb,并且在我的本地计算机上运行迁移(mac os x 10.7,4gb ram,2.4GHz Core 2 Duo)需要3天才能完成。

我能够使用amazon ec2实例(高I / O按需实例,四倍超大)将此时间减少到仅16小时。但是16个小时仍然很长,因为我将不得不取下网站来执行此更新。

有没有人有其他建议可以降低这段时间?或者提高迁移性能的任何提示?

仅供参考:在亚马逊实例上使用ruby 1.9.2和ubuntu。

5 个答案:

答案 0 :(得分:3)

  • 预先删除索引并在之后再次添加它们是一个好主意。

  • 如上所述,同样用.find_each替换.where(...)。也许添加交易可能有所帮助。

  • 替换.save!使用.save(:validate => false),因为在迁移期间您没有从用户那里获得随机输入,您应该进行已知良好的更新,并且验证会占用大部分执行时间。或者使用.update_attribute也会跳过只更新一个字段的验证。

  • 尽可能在循环中使用较少的AR对象。实例化和以后的垃圾收集会占用CPU时间并占用更多内存。

答案 1 :(得分:0)

也许你已经考虑过这个:

  1. 告诉数据库不要费心确保一切都在磁盘上(没有WAL,没有fsync等),你现在有一个内存数据库应该会产生很大的不同。 (由于您已使数据库脱机,因此您可以在不太可能发生的断电或类似情况下从备份恢复)。完成后打开fsync / WAL。

  2. 在将数据库脱机之前,您可能可以执行一些迁移。当然,在暂存环境中测试这个。那个大的用户迁移很可能是现场直播。确保您不在事务中执行此操作,可能需要稍微修改它们。

  3. 我不熟悉你的具体情况,但我确信除非这还不够,否则你还可以做更多事情。

答案 2 :(得分:0)

这个答案更多的是关于方法而不是特定的技术解决方案。如果您的主要标准是最小停机时间(当然还有数据完整性),那么最好的策略是不使用rails!

相反,您可以预先完成所有繁重的工作,只留下关键的“实时”数据迁移(我在非轨道意义上使用“迁移”)作为切换期间的一个步骤。

因此,您拥有其当前应用程序及其数据库架构和生产数据。你也(大概)有一个应用程序的开发版本,它基于升级后的spree gems和新的db模式但没有数据。您所要做的就是找出一种在两者之间转换数据的方法。这可以通过多种方式完成,例如在必要时使用纯SQL和临时表,或使用SQL和ruby生成插入语句。这些步骤可以拆分,以便相当“静态”的数据(参考表,产品等)可以提前加载到数据库中,更频繁地更改的数据(用户,sesssions,订单等)可以是在迁移步骤中完成。

您应该能够编写此export-transform-import过程的脚本,以使其可重复并在完成后进行测试/检查以确保数据完整性。如果您可以在切换期间安排对新生产数据库的访问,那么应该很容易针对它运行脚本。如果您被限制在发布过程中(例如webistrano),那么您可能需要将其转换为rails迁移,但您可以使用execute运行原始SQL。

答案 3 :(得分:0)

看看这个宝石。 https://github.com/zdennis/activerecord-import/

data = []
data << Order.new(:order_info => 'test order')
Order.import data

答案 4 :(得分:0)

不幸的是,降级的解决方案是唯一的解决方案。 rails中真正慢的是activerecord模型。这不适合这样的任务。

如果您想要快速迁移,则必须在sql中执行此操作。

还有另一种方法。但是你总是要重写大部分的迁移......