상세 컨텐츠

본문 제목

경력 0개월차 개발자의 고래 해체 작업 썰 - 2 [Postgre 데이터 Dump]

소프트웨어/인프라

by moonionn 2021. 9. 8. 03:58

본문

지난 이야기

 

TODO

EC2 위의 PostgreSQL 컨테이너 데이터를 RDS로 이관하기

 

 


도커 컨테이너의 데이터베이스에서 호스트 서버로 데이터 덤프하기

이 문제는 포트 바인딩으로 해결할 수 있습니다. 포트 바인딩이란 컨테이너 내부 프로그램을 외부로 노출시킬 때 사용되는데요, 호스트의 특정 포트를 컨테이너의 특정 포트로 연결시켜주면 작동합니다.

docker run --name postgres -d -p 5432:5432 postgres:9.6-alpine

 

 

여기서 -p 뒤에 오는 포트 두 가지가 바인딩될 호스트포트:컨테이너포트입니다. 이제 호스트 서버의 5432 포트로 들어가면 PostgreSQL이 깔려있는 컨테이너로 접속됩니다.

 

한 가지 더 다른 옵션을 줍시다. 제가 작업한 redash의 경우 호스트 서버 위에 데이터 보관용 폴더 /opt/redash/postgres-data가 존재했습니다. 이 폴더가 PostgreSQL 컨테이너 내부의 /var/lib/postgresql/data 폴더에 마운트 된 형태로 작동했습니다. 따라서 docker로 실행할 때 -v (volume의 약자)라는 옵션을 사용해 이런 환경을 적용시켜줍니다. -v 뒤에 마운트할 폴더:마운트 대상 폴더를 적어주면 됩니다.

docker run --rm --name postgres -d -p 5432:5432 -v /opt/redash/postgres-data:/var/lib/postgresql/data postgres:9.6-alpine

 

자 이제 필요한 서버는 다 구동되었습니다. 이제 호스트 서버에 postgresql-client 패키지를 설치해주면 PostgreSQL cli 명령어를 사용할 수 있습니다.

ubuntu@ip-000-00-0-000:/$ sudo apt-get install postgresql-client

 

포트를 바인딩해주었으니 localhost의 5432 포트로 접근하면 PostgreSQL 컨테이너로 연결됩니다.

ubuntu@ip-000-00-0-000:/$ psql -U postgres -p 5432 -h localhost
Password for user postgres:
psql (10.18 (Ubuntu 10.18-0ubuntu0.18.04.1), server 9.6.20)
Type "help" for help.

postgres=#

 

의도한 대로 잘 동작하는 걸 확인했으니, 호스트 서버에서 덤프 명령어인 pg_dump를 사용할 차례입니다.

여기서 조금의 삽질이 있었는데,

처음에는 압축파일로 데이터를 백업하려 했습니다. 

sudo pg_dump -U postgres -h localhost -p 5432 postgres | gzip > ~/db_backup.gz

 

하지만 이렇게 압축된 백업 데이터를 까 보면 sql 확장자가 아닌 평문 데이터임을 확인할 수 있습니다. sql 확장자가 아닌 파일로 데이터를 복원하기 위해서는 pg_restore라는 명령어를 사용해야 하는데, 또 이 pg_restore 명령어는 PostreSQL(RDS) 서버와 명령어를 실행 주체인(좀 전에 다운로드하였던) postgresql-client 패키지의 버전이 일치해야만 작동하는 뭣 같은 상황이 발생해 버립니다. 운이 좋아서 이미 같은 버전이 깔려 있다면 좋겠지만, 개발자들은 매번 그렇듯 운이 더럽게도 없으니 웬만해서는 압축하지 말고 덤프를 뜨시는 걸 추천드립니다. (*버전 맞춰주는 게 여간 귀찮은 일이 아닌지라...)

 

* postgresql-client 패키지를 리눅스에서 설치하면 default로 9.x 버전을 설치해줍니다. 하지만 PostgreSQL이 13 버전까지 나온 마당에 그보다 상위 버전을 쓰고 있는 분들이 더 많을 것 같습니다. (AWS에서 애초에 내년이면 9.x 버전은 지원도 안 해준다.)

 

무튼 postgresql-client 12~13 버전을 설치하기 위해서는 험난한 삽질이 기다리고 있기에... 내 백업 데이터 너무 커서 호스트 서버에 용량이 부족한데 어떡하죠?라는 상황이 아닌 이상 sql 확장자 파일로 덤프를 만들어줍니다. (이런 상황도 사실 후딱 EBS 올리는 게 편할 듯)

# 여기서 DB 자리에 덤프 대상이 될 데이터베이스 이름을 적어주면 된다. redash의 경우 postgres
pg_dump DB > backup_data.sql

 


RDS에 데이터 적용해주기

해당 파일이 잘 생성되었으면, RDS로 데이터를 이관해줍니다. 만약 이미 RDS 안에 데이터가 존재한다면, 내부 데이터를 한 번 드랍해준 다음 덤프를 올려줘야 합니다. PostgreSQL에서 모든 테이블을 드랍하는 방법은 여기를 참고하세요. 드랍하고 난 다음 제대로 잘 비워졌는지 확인하는 것도 필수입니다.

 

이제 RDS에 데이터를 옮겨줄 차례입니다. 

psql -U postgres -h myinstance.123456789012.ap-northeast-2.rds.amazonaws.com -p 5432 --set ON_ERROR_STOP=1 --single-transaction < backup_data.sql

 

데이터가 잘 생성되었으면 금이야 옥이야 서둘러 s3에 저장해줍니다.

ubuntu@ip-000-00-0-000:~$ aws s3 cp backup_data.sql s3://bucket.url.co.kr/name

 


기존 PostgreSQL 컨테이너 서버 내리기

이제 redash 서버가 해당 RDS를 바라보게 설정만 해주면 됩니다. 우선 호스트 서버에서, /opt/redash/env 파일부터 바꿔줍니다.

그중 REDASH_DATABASE_URL 변수만 바꿔주면 됩니다.

#예시
REDASH_DATABASE_URL=postgresql://postgres:password@rds-name.123456789012.ap-northeast-2.rds.amazonaws.com/postgres

 

docker-compose 파일도 수정해줍시다. postgres와 연관된 줄은 모두 삭제하거나 주석 처리해주면 됩니다.

version: "2"
x-redash-service: &redash-service
  image: redash/redash:latest
  depends_on:
    # - postgres
    - redis

#생략...

services:
  
  #생략...
  
  redis:
    image: redis:5.0-alpine
    restart: always
  # postgres:
    # image: postgres:9.6-alpine
    # env_file: /opt/redash/env
    # volumes:
      # - /opt/redash/postgres-data:/var/lib/postgresql/data
    # restart: always

 

컨테이너를 재실행해줍니다.

$ docker-compose restart

 

혹은

$ docker stop $(docker ps -a -q)
$ docker-compose up -d

 

EC2 엔드포인트로 접속해보면 잘 동작하는지 확인해볼 수 있습니다.

기존에 쓰고 있던 redash였으니까, 로그인화면이 나와야 정상입니다.

 

RDS에서 문제가 없는걸 확인했으니, 이제 ECS Fargate로 redash app을 이관할 차례입니다. 해당 작업은 다음 포스트에서 다뤄보도록 하겠습니다.

관련글 더보기

댓글 영역