C 레벨의 경이로운 결정과 어이없고 화나는 장애

C 레벨의 경이로운 결정과 어이없고 화나는 장애

속풀이

C 레벨의 경이로운 결정

우리 회사에 와서 느낀 가장 큰 문제는 시리즈 B에 도달하기까지 6년의 시간동안 회사는 엄청난 기술부채를 축적했다는 것이다.

그래서, 일년동안 기술부채 청산에 대해 노래를 부르고 다니고, 여기저기 많은 설득을 시도했었다. 일개 팀원이지만 리드 미팅까지 쳐들어가서 우리 회사는 기술부채를 청산하는 게 가장 시급하다는 주장을 펼치기도 했었다.

그러고 있던 와중 최근에 C 레벨에서 믿기 힘든 결정이 내려졌다. 이게 정말 될지는 몰랐는데, 이제부터는 비즈니스를 모두 접고 내실을 다지는 데 총력을 다한다고 한다. 🥺

그동안은 우리 플랫폼 개발팀의 개발자들은 기술부채를 청산하는 데 주력하고 다른 팀의 개발자들은 비즈니스를 진행했는데, 이렇다 보니 많은 혼란이 있었다. 우리는 하위호환성 문제로 구조를 시원시원하게 갈아엎지 못하고 찔끔찔끔 개선작업을 진행했으며, 다른 팀은 더러운 시스템에 새로운 비즈니스를 진행하면서 기술부채를 계속 늘려갔다. 시스템이 더러우니 아주 당연한 결과다. 그들의 잘못은 절대 없다. 이제는 수십 명의 개발자를 모두 개발부채 청산에 몰빵한다고 한다. 우리도 이제 기술부채 청산에 온전히 몰두할 수 있는 환경이 조성됐다.

기술부채 청산이 가장 시급하다고 노래를 부르고 다닌 이유는 다름 아니다. 이제는 개발자들조차 우리 코드를 이해하는 게 불가능에 가까워졌기 때문이다. 개발 일정을 전혀 예상할 수 없으며, 시도때도없이 발생하는 버그들 탓에 원인을 분석하고, 데이터베이스에 쿼리를 수동으로 입력하느라 우리가 해야 할 일을 아예 못하고 있다. 새로운 개발을 진행하고 나면 다음 개발은 배 이상 느려진다. 기회는 준비된 자가 잡을 수 있는 법인데, 우리는 준비가 전혀 되지 않은 상태였다. 이 상태로 미래는 꿈조차 꾸기 어렵다고 생각했다.

그럼에도 불구하고, 사업이란 굉장히 현실적인 문제들이 많이 얽혀있기 때문에 나는 C 레벨에서 이런 결정이 내려질 거라고는 정말 상상도 하지 못했다. C 레벨이 이런 결정을 내린다는 것은 그들이 투자자와 주주들의 비판과 비난을 온몸으로 감내해가며 방패막이가 되어주겠다는 결정이라고 생각했기 때문이다. 나는 C 레벨이 이런 결정을 내린 상황에 대해 굉장히 열렬한 지지를 보낸다. 아주 옳은 결정이고, 어떻게 보면 생존을 위한 어쩔 수 없는 선택이라고 볼 수도 있겠지만, 엄청난 고난이 예상되는 결정이기 때문에 엄청나게 어려운 선택이었음을 아주 잘 알고 있고, 그 용기가 존경스럽기마저 하다.

어이없고 화나는 장애

데이터베이스가 워낙에 막장이다 보니, 주로 데이터 무결성이 보장되지 않음으로 인한 장애들이 하루에도 수십번씩 발생한다.

고객의 주소와 좌표를 핵심으로 다루는 테이블이 있는데, 주소는 있지만, 좌표가 없는 사례가 아주 많았다. 그래서 8월 초에 애플리케이션 코드에서 주소는 있는데 좌표가 없다면 좌표를 계산해 데이터베이스에 채워넣는 코드를 작성했었다. 아주 단순한 코드였고, 메인이 되는 쿼리도 대략 다음과 같이 아주 간단했다.

update address set lat = ?, lng = ? where address_guid = ?

이게 한 달여가 지난 후인 최근에 굉장히 어이없는 장애를 일으켰는데, 약 34만여 개의 고객 좌표가 엉뚱한 좌표로 변경된 것이다. 아무리 봐도 딱히 문제가 될게 없어 보여 원인을 알아내는데 약 2시간 정도가 걸렸는데, 알고 보니 이유는 아주 간단했다.

address_guid가 고유한 값이 아니었던 것이다. address_guid 컬럼에 "home"이라는 문자열이 저장된 데이터가 30만 개 이상 존재했고, 그동안은 위 쿼리의 where 절에 guid가 바인딩 되어 문제가 없다가 어느 날 "home"이 바인딩 되며 30만 개 이상의 데이터가 모두 변경된 것이다.

한참동안 코드를 보며 원인을 찾던 중 설마? 하며 address_guid를 기준으로 group by 쿼리를 입력해본 후 나는 뒤통수를 세게 맞은 느낌과 함께 곧바로 좌절할 수밖에 없었다.

30만개의 데이터를 복구하는데 약 7시간이 소요되었는데, 이 시간 동안 회사의 핵심 시스템이 중단될 수밖에 없었다.

그동안 코드의 함수명이 get~인데, 동작이 이상해 구현을 모조리 까 뒤집어 보니, 실제로 데이터베이스에 update 쿼리를 보낸다거나 하는 식의 함정 카드가 많아 코드의 모든 이름을 믿지 못하고 모든 코드를 DFS하는 상황에 와 있었는데, 이제는 테이블의 스키마조차 믿기 힘든 상황이 되었다.

정말 쉽지 않다.


© 2022. All rights reserved.