2.6.0b2 升级非常慢

顺便提一下,大家不要在业务高峰期尝试这次升级。

2.6.0b2 版本的升级在我们的服务器上已经运行了超过 40 分钟,而正常情况下只需要几分钟,通常在你回来查看之前就已经完成了。我担心它是否出错了,但登录到 PostgreSQL 后,我看到一个巨大的更新正在运行,看起来是在更新私信的帖子搜索数据。

希望它并没有出错。我想我很快就会知道结果了。真的不想在升级过程中杀掉它或重启容器。

正在运行的查询:

postgres=# SELECT pid, age(clock_timestamp(), query_start), usename, query 
FROM pg_stat_activity 
WHERE query != '<IDLE>' AND query NOT ILIKE '%pg_stat_activity%' 
ORDER BY query_start desc;
  pid  |       age       |  usename  |                                            query                          
                   
-------+-----------------+-----------+---------------------------------------------------------------------------
-------------------
   698 |                 |           | 
   701 |                 | postgres  | 
   699 |                 |           | 
   697 |                 |           | 
   696 |                 |           | 
 14572 | 00:10:31.484201 | discourse | UPDATE post_search_data                                                   
                  +
       |                 |           | SET private_message = X.private_message                                   
                  +
       |                 |           | FROM                                                                      
                  +
       |                 |           | (                                                                         
                  +
       |                 |           |   SELECT post_id,                                                         
                  +
       |                 |           |     CASE WHEN t.archetype = 'private_message' THEN TRUE ELSE FALSE END pri
vate_message      +
       |                 |           |   FROM posts p                                                            
                  +
       |                 |           |   JOIN post_search_data pd ON pd.post_id = p.id                           
                  +
       |                 |           |   JOIN topics t ON t.id = p.topic_id                                      
                  +
       |                 |           |   WHERE pd.private_message IS NULL OR                                     
                  +
       |                 |           |     pd.private_message <> CASE WHEN t.archetype = 'private_message' THEN T
RUE ELSE FALSE END+
       |                 |           |   LIMIT 3000000                                                           
                  +
       |                 |           | ) X                                                                       
                  +
       |                 |           | WHERE X.post_id = post_search_data.post_id                                
                  +
       |                 |           | 
 14573 | 00:47:02.814489 | discourse | SELECT pg_try_advisory_lock(2859260972035668690)
(7 rows)

升级刚刚成功完成,而我的恐慌也达到了顶峰。真是“好时光”,真是“好时光”。

即使在快速托管的硬件上,升级对我来说也相当缓慢。我不完全确定原因,但这确实是一个需要注意的问题。

没错,我建议在更新日志中加一条提示,提醒用户这次更新可能比大多数更新耗时更长,请勿强行终止或采取任何极端操作,因为这是正常现象。

@Wingtip 我可以查看您论坛上的帖子数量吗?不幸的是,在帖子数量较多的网站上,这可能会比较慢。

是的,我们有超过 500 万。

我的本地站点帖子数量并不多,但运行速度仍然相当缓慢。并非慢了 40 分钟,而是比之前的升级明显慢了大约 3 到 4 倍?

仅供参考:

刚刚重新构建,现在运行的是 2.6.0.beta2 版本(2aa1482421)。

在我们的服务器上,构建过程并没有明显变慢。

谢谢 @Wingtip,我还以为只有我们遇到这个问题!

实际上,我不得不取消重建并重启应用,因为我以为它卡在了你提到的那个查询上。我们有 600 万篇帖子,大约 45 分钟后仍未完成,所以我想我得做好至少需要一小时重建时间的准备,并提前告知我们的用户。

发布说明中已添加关于通过 SSH 延长 Docker 管理器运行时间和/或重建时间的注释。

刚拿出秒表测试了一次重建(仅包含约 100 万条帖子的站点),从 2.6.0b1 升级到 b2;从开始到结束共耗时 170 秒。

这是我今天进行的第二次重建,从 b1 升级到 b2,过程非常顺利,构建速度没有明显变化。

注意:我们总是通过命令行进行升级,不使用图形界面。

我也不使用 Docker 管理器,更倾向于通过命令行进行重建。这样在出现问题时能更好地查看日志。我也认为这样更快。

是的,看来这主要是在帖子很多的论坛上出现的问题。

我(愚蠢地)通过网页控制台进行了升级,因此整个过程都没有最新的日志。下次绝不会再犯同样的错误。

我有一个大型站点反复无法启动。这是一个双容器安装,因此在引导迁移期间,旧容器继续运行。我最终通过为引导过程设置 SKIP_POST_DEPLOYMENT_MIGRATIONS=1,然后在新容器启动后运行迁移来解决这个问题。在 ENV 部分设置 SKIP_POST_DEPLOYMENT_MIGRATIONS=1 后,迁移非常快,站点随后能够正常运行(尽管可能稍慢一些),而迁移过程耗时超过 20 分钟,我记得是这样。

我认为(但尚未测试),使用同样的技巧也可以最小化单容器安装期间的停机时间。如果我的推测正确,你可以这样做:

  • app.yml 中添加 SKIP_POST_DEPLOYMENT_MIGRATIONS=1
  • 运行 ./launcher rebuild app
  • 运行 ./launcher enter app
  • 运行 SKIP_POST_DEPLOYMENT_MIGRATIONS=0 rake db:migrate
  • 撤销 app.yml 中的修改,除非你打算在每次升级后记得手动执行迁移
  • 也许再次重建,以确保在你还记得可能导致站点问题的原因时(比如四个月后你再次尝试时,你可能完全想不起来,别人也很难猜测问题出在哪里)不会出现任何问题

如果有一种方法能让 ./launcher 在不修改 app.yml 的情况下传递 SKIP_POST_DEPLOYMENT_MIGRATIONS=1,那对于不擅长编辑配置文件的用户来说会方便很多。

如果我确实完成了这项工作,我会创建一个新主题来报告我的发现。不过,由于烟雾弥漫,我被困在一个没有大显示器的房间里。(疫情还不够吗?我们还得忍受烟雾?而且我离那场大火其实并不近。)

好主意,我已经实现了这个功能:

这真是个好消息!(今天另外两个项目插了进来,不知怎么的,我的多站点实例不再正常运行,和 S3 也不配合了。:crying_cat_face:) 非常感谢。

升级后数据库变更默认需要阻塞,是否有技术原因?是否有办法更改此行为,使未来的升级能快速恢复站点运行,然后在后台执行升级后的操作?

在我看来,对于升级后应用程序正常运行至关重要的操作(如 DDL),应直接作为升级过程的一部分,而不是放在升级后的脚本中。

我们七小时前从命令行开始重建,至今仍在进行中……它仍然卡在这里:

有什么建议吗?

编辑:与此同时,我已终止该进程,以便让网站重新对用户开放。但肯定有更好的方法来完成这次更新。

您有大型数据库吗?