내가 겪은 에러 시리즈 1탄 (mysql synchronize)

양진영·2022년 8월 1일
0

상황설명

nestjs를 공부하며 crud를 만들던중 이상한 현상을 발견했다. 상품등록을 하게 만들어둔 로직이 실행되어 dbeaver를 통해 데이터가 잘들어간것을 확인한후 id를 인자로 받아 해당 상품객체를 받아오는 api를 작성했는데 자꾸 name, description등과 같이 문자열이 들어간 부분이 빈문자열을 리턴하는것이 아닌가(null 아님)? 그래서 dbeaver로 들어가보니 실제로 name, description과 같이 문자열이 입력되어있던 칼럼값이 비어있었다. 신기한건 price나 id, 생성 또는 업데이트 날짜 데이터는 하나도 날라가지 않았다. 아예 데이터가 다 날라갔다면 차라리 해결하기 쉬웠을텐대 부분 칼럼값만 날라가니 정말 어이가 없더라.

  • 상품등록후 제대로 들어간 모습

  • 서버 재시작후 name, description과 같은 문자타입 데이터 없어짐

진짜 왜 그런지 모르겠더라...

해결방법

  1. 로컬이 아닌 docker-compose로 이미지 빌드후 업시켜서 했음:
version: '3.3'

services:
  my_backend:
    platform: linux/amd64
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./src:/my_backend/src

    env_file:
      - ./.env

    ports:
      - 3000:3000

  my_database:
    platform: linux/x86_64
    image: mysql:latest
    environment:
      MYSQL_DATABASE: process.env.DB_NAME
      MYSQL_ROOT_PASSWORD: process.env.DB_PASSWORD
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --skip-character-set-client-handshake
    cap_add:
      - SYS_NICE
    ports:
      - 3306:3306

일단 이렇게 하고 띄우면 서버를 재시작해도 데이터가 날아가진 않는데 아니 도대체 데이터들이 어디있는지 찾을수가 없다. (데이터는 분명 어딘가 있지만 내가 못찾은거라 실력탓... ) 그래서 반쪽짜리 해결책이라 할수있다.

  1. 두번째는 사수와 머리를 맡대어 고민해본 부분인데, 설마했던 곳에서 문제가 있다는것을 발견할수있었다. 바로 synchronize를 true로 두었기때문에 문제가 발생했던것이다... 우리가 아는 synchronize기능은 현재 코드로 적어넣은 스키마를 db에 그대로 옮겨 두기 위해서 만드는 기능이다. 근데 이게 데이터 삭제랑 무슨상관이 있는거지...? 라고 생각은 했지만 어쨋든 synchronize를 false로 두었더니 데이터가 로컬에서도 서버재시작을 했지만 날라가지 않는것을 확인할수있었다.

syncrhonize에 대한 고찰

syncrhonize는 우리가 아는데로 코드로 적어놓은 스키마를 db로 옮겨주는 역할을 한다. 하지만 이 과정에서 synchonize는 새로운 업데이트 내용이 있다면 기존의 스키마가 적용된 db에서 새롭게 수정된 스키마를 덮어씌운다. 이 덮어씌운다 라는 단어가 중요한게 이렇게 되면 기존의 데이터가 없어질수있다는 뜻이기 때문이다.

이거는 나중에 해볼거지만 정석적인 synchronize사용법은 첫 배포시 true로 하여 스키마를 db와 동기화 시키고 동기화가 완료되면 false로 바꾸어 혹시나 데이터가 날아가는 일을 방지한다. 하지만 개발을 하다보면 기획에 맞추어 칼럼이 늘어나거나, 수정되거나 삭제되는 변화가 일어나고 이 변화를 db에 적용시켜야한다. 그러면 이상태에서 그냥 바로 synchronize를 true로 바꾸면..? 기존의 데이터가 싹 날아가 버릴수있기 있다. (synchronize... 알고보면 개무서운놈...) 아무튼 그렇기 때문에 기존의 데이터를 synchronize를 false로 바꾸어 놓고 migration하여 dump파일을 따놓는다. 이후 synchronize를 true로 바꾸고 새롭게 스키마를 적용 한다음 dump파일을 적용시키는 방향으로 해야햔다.

손이 많이 갈순있지만 이거 무조건 해줘야한다. 안그러면 데이터 날라간다. 그리고 dev환경에서야 데이터가 날라가도 별거 아니네 할수있지만 production에서 이렇게 되면 진짜 그건 재앙에 가까운 결과를 가져올수있다. 그렇기에 production은 우선 무조건 첫 배포가 끝나면 false로 바꾸고 스키마 환경을 변경하고 싶다면 위와같은 절차를 겪어야 한다. 이 과정에 대해서는 나중에 실제로 내가 구현해보고 블로그에 다시올리겠다.

profile
왜? 라는 질문을 중요시하는 서버 개발자입니다

0개의 댓글