본문 바로가기
👨‍💻 프로그래밍/Spring Data, JPA, DB

무중단, 카나리 배포 환경에서 DB Schema 수정하기

by 개발자 진개미 2024. 2. 25.
반응형

문제 상황

  • 자주 있는 상황은 아니지만 DB의 Column을 수정해야 할 일이 있습니다.
  • 굳이 왜 수정해야 하나? 어차피 이름만 다른거 아니야? 하실 수 있지만 이름과 사용 용도가 다르면 장기적으로는 인지 비용이 높아져 팀 전체의 자원이 더 많이 들게 됩니다.
  • 무중단의 핵심은 이 작업으로 인해 에러를 만나는 유저가 1명도 없어야 한다는 것입니다.
  • 그럼 가장 먼저 떠올리는게 DB Column 변경과 배포를 딸깍딸깍 동시에 진행하면 되지 않을까 생각할 수 있습니다. 솔직히, 팀 리소스가 부족한 상황에서는 좋은 해결책이라 생각합니다. 새벽 시간 트레픽이 없을 때를 틈타 작업하면 큰 문제가 없을 수도 있습니다.
  • 하지만 서비스의 중요도가 높거나 카나리 배포를 하고 있는 환경에서는 이것도 어렵습니다. 
  • 이 상황에서 정말 무중단으로 DB Column을 수정하려면 어떻게 해야 할까요?

무중단하기 위한 방법

🐜 DB에 새 Column 추가하기

우선, DB Column을 수정하는게 최종 목적이라고 해서 거기에 매몰되면 안 됩니다. 하위 호환성을 보장하는 유일한 방법은 원래 Column을 변경하지 않는 겁니다. 원래 Column은 유지할 수 밖에 없습니다. 그럼 자연스럽게 새 Column을 만들어야 한다는 결론에 도달합니다. 새 Column을 만들고, 이 Column을 최종적으로 바꾸고자 하는 Column으로 만든 뒤 기존 Column은 삭제하는 식으로 진행해야 모든 과정에 문제가 없습니다.

 

🐜 Application에서 새 Column에 데이터에 데이터 똑같이 쌓도록 배포하기

새 Column을 만들었다고 사실 되는건 아무것도 없습니다. 데이터가 쌓이고 있지 않기 때문입니다. Application을 수정해서 기존 Column과 새로운 Column에 똑같이 데이터를 쌓도록 수정해야 합니다. 이때 카나리 배포 환경이라면 이 사이에는 새 Column에 데이터가 쌓인 경우와 쌓이지 않은 경우가 섞이게 되는데 이 부분을 다음 단계인 Batch로 기존 데이터 쌓기에서 고려해야 합니다. 또, 새로운 Column에 과거 데이터가 없더라도 Application은 새로운 Column에 데이터를 쌓고 있을 뿐이지 아직 새로운 Column을 사용하고 있지는 않기 때문에 문제 없습니다.

 

🐜 Batch로 기존 데이터 쌓기

Application을 수정해서 배포를 완료하면 이제 기존 Column과 새 Column에 똑같은 데이터가 쌓이고 있습니다. 이제 과거 Column에도 똑같은 데이터를 적재해야 합니다. 여기서 아래와 같은 Query를 날리고 싶을 수 있습니다. 하지만 이런 무거운 작업을 운영중인 DB에 날리면 모든 Thread를 점유해 장애로 이어질 수 있습니다.

update example set new_column = old_column where 1=1;

 

Batch를 작성해 되도록이면 트래픽이 적을 때 점진적으로 진행해야 합니다.


기술적으로 더 고려해야 할 것들

🐜 기존 Column이 활발하게 업데이트 된다면?

만약에 기존 Column이 계속 활발하게 업데이트 된다면 Batch를 돌리는 순간에도 기존 Column이 달라지는거 아닐까 생각할 수 있습니다. 하지만 Application에서 기존 Column과 새 Column 모두 업데이트 하도록 수정했기 때문에 문제는 없습니다. 

 

🐜 기존 Column을 바라보는 서비스가 정말 없는지 확인하기

조심하고 조심해서 이 모든 과정을 완벽하게 진행했어도 수정하려는 Column을 바라보는 서비스가 1개라도 있었으면 그 서비스는 장애로 이어졌을겁니다. 정말 기존 Column을 바라보는 서비스가 없는지 확인하고 확인해야 합니다. (슬프게도 경험담입니다... 🥲)


반응형