在多个节点上运行db:migrate时如何避免计时问题?

时间:2015-01-15 17:33:45

标签: ruby-on-rails deployment capistrano database-migration rails-migrations

我目前正在学习如何使用Capistrano首次部署Rails应用。我看到capistrano / rails的默认流程包括在主机之前运行db:migrate"发布"新的符号链接。但是,在同时跨多个Web节点运行部署时,会出现一些时序问题。

  1. 如果您在旧版本的应用程序仍在运行时迁移数据库,那么您将使用旧代码与更改的数据库进行通信,从而导致未定义的行为。
  2. 如果在运行迁移之前关闭应用程序,但部署的速度低于每个节点上相同的速度,则一个节点仍可以运行旧应用程序,而另一个节点已在运行迁移。
  3. 如果两个节点同时调用db:migrate,则不会因为他们认为新的迁移尚未运行(通过咨询)而遇到竞争条件表),然后两个都尝试同时运行迁移?
  4. 在我看来,唯一合理的解决方案是尝试将默认流程返回到以下三个阶段:

    1. 每个节点上的正常部署流程,但不包括db:migrate任务 - 所以现在安装了新版本,运行了捆绑程序,编译了资产,建立了链接,一切准备就绪(但尚未通过当前符号链接发布)。最后的附加步骤:停止旧的应用程序。
    2. 在所有主机完成第1阶段之后,然后仅在一个节点上运行db:migrate(可能是随机选择,或者只是在列表中首先选择)。
    3. 完成此操作后,在所有主机上恢复正常流程的后半部分,并在部署:已发布任务后再添加一个用于启动应用程序的任务。
    4. 我现在对自己的推理有点缺乏信心,因为虽然我搜索了文档并搜索了帖子,但我还没有真正看到有人在谈论这些多节点问题,即使我不得不认为它影响了几乎每个人......

1 个答案:

答案 0 :(得分:0)

您不能在多个节点上运行rake db:migrate。您只在1个节点上运行它。请记住,db migrate迁移数据库,该数据库由应用程序中的所有节点共享,因此同时在不同节点上运行它绝对是个坏主意。

我从数据迁移中拆分数据库迁移以获得更快的部署,然后我执行两种不同的部署: 1)使用db迁移和整个应用程序的一些停机时间 2)没有数据库迁移,没有停机时间(旧dynos正在运行时新的dynos旋转,启动后路由器将新流量切换到新dynos,然后关闭旧dynos)

(当然我在Heroku的背景下做的是不同但基本相同的想法)

还要记住,在运行db:migrate之后,必须重新启动所有节点的Rails,因此您的管理脚本应该考虑到这一点。