2.6.0b2 업그레이드가 매우 느립니다

여러분께 알려드립니다. 피크 시간대에 이 업그레이드를 시도하지 마세요.

2.6.0b2 업그레이드가 보통 몇 분 만에 끝나는데(보통 다시 확인해 볼 때 이미 끝난 상태), 우리 서버에서는 40분 넘게 실행 중입니다. 고장 난 건 아닌지 걱정했는데, postgres에 로그인해서 보니 거대한 업데이트가 실행 중인 것을 볼 수 있습니다. 사설 메시지의 게시글 검색 데이터를 변경하는 것으로 보입니다.

다행히 고장 나지 않았으면 좋겠습니다. 알아볼 수 있을 거예요. 업그레이드 도중에 프로세스를 종료하거나 컨테이너를 재시작하는 건 정말 원치 않습니다.

실행 중인 쿼리:

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분 정도가 지나도 완료되지 않아서, 최소 1시간 이상 걸리는 리빌드에 대비해서 사용자들에게 미리 알려야 할 것 같습니다.

확장된 Docker Manager 및/또는 SSH를 통한 재빌드 시간이 릴리스 노트에 추가되었습니다.

스톱워치를 꺼내서 2.6.0b1에서 b2로 리빌드(게시글 약 100만 개인 사이트)를 테스트해 보았습니다. 시작부터 끝까지 170초가 걸렸습니다.

오늘 두 번째 리빌드(b1에서 b2로)인데, 빌드 속도에서 눈에 띄는 차이가 없어 아주 좋습니다.

참고: 우리는 항상 명령줄을 통해 업그레이드하며 UI를 사용하지 않습니다.

저도 도커 매니저를 사용하지 않고, 커맨드라인에서 재빌드하는 방식을 선호합니다. 문제가 발생할 경우 로그를 확인하는 데 이 방식이 더 좋기 때문입니다. 또한 더 빠르다고 생각합니다.

네, 게시글이 많은 포럼에서 주로 발생하는 문제인 것 같습니다.

내가 (바보처럼) 웹 콘솔로 업그레이드를 진행해서, 그 동안 최신 로그를 확보하지 못했습니다. 다음에는 이런 실수를 하지 않겠습니다.

부트스트랩이 반복적으로 실패하는 대형 사이트를 운영한 적이 있습니다. 2개 컨테이너 구성이었기 때문에 부트스트랩 마이그레이션이 진행되는 동안에도 기존 컨테이너는 계속 실행되었습니다. 결국 부트스트랩에 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의 수정 사항을 되돌립니다.
  • 4개월 후 다시 시도했을 때 무엇이 문제를 일으켰는지 아무도 알 수 없게 될 수 있으므로, 아직 무엇이 사이트를 망가뜨렸는지 기억나는 동안 다시 빌드하여 문제가 없는지 확인하는 것이 좋습니다.

app.yml을 수정하지 않고도 ./launcher가 SKIP_POST_DEPLOYMENT_MIGRATIONS=1을 전달할 수 있는 방법이 있다면, 편집에 익숙하지 않은 사용자에게 더 간편할 것입니다.

이 부분에 대한 작업을 실제로 수행하게 된다면, 발견한 내용을 보고하는 새로운 토픽을 만들겠습니다. 다만 연기 때문에 큰 모니터가 없는 방에 격리되어 있습니다. (팬데믹만으로도 부족해서 연기도 있어야 합니까? 게다가 저는 그 불길에서 특별히 가까운 편도 아닌데 말이죠.)

좋은 아이디어네요. 해당 기능을 구현했습니다:

정말 멋진 소식입니다! (오늘 다른 두 프로젝트 때문에 멀티사이트 인스턴스가 S3와 잘 작동하지 않는 문제가 생겼네요. :crying_cat_face:) 정말 감사합니다.

업그레이드 후 DB 변경 사항이 기본적으로 차단(blocking)되어야 하는 기술적인 이유가 있나요? 이 동작을 변경하여 향후 업그레이드 시 사이트를 빠르게 복구한 뒤, 업그레이드 후 작업을 백그라운드에서 실행할 수 있는 방법이 있을까요?

개인적인 의견으로는, 업그레이드된 애플리케이션이 기능하는 데 필수적인 DDL과 같은 작업은 업그레이드 후 스크립트가 아니라 업그레이드 자체의 일부가 되어야 한다고 생각합니다.

7시간 전부터 커맨드 라인에서 재구축을 시작했고, 아직 진행 중입니다… 여전히 이렇게 보입니다:

혹시 아이디어가 있으신가요?

수정: 그동안 사용자가 사이트를 다시 이용할 수 있도록 프로세스를 종료했습니다. 하지만 이 업데이트를 수행하는 더 나은 방법이 있어야 합니다.

큰 데이터베이스를 가지고 계신가요?