피드로 돌아가기
PostgreSQL 데이터베이스 마이그레이션 가이드 - 썸네일
37 reads
·
2025/08/23 02:31

PostgreSQL 데이터베이스 마이그레이션 가이드

우분투 도커 환경에서 PostgreSQL 데이터베이스 간 데이터 마이그레이션을 수행하는 방법을 안내합니다.

환경 정보

  • 운영체제: 우분투
  • 컨테이너: Docker
  • 데이터베이스: PostgreSQL
  • 소스 DB: source_database
  • 대상 DB: target_database
  • 사용자: your_username
  • 컨테이너 ID: your_container_id

마이그레이션 단계

1. 데이터베이스 및 테이블 확인

데이터베이스 목록 확인

sudo docker exec -it <container_id> psql -U <username> -l

소스 데이터베이스 테이블 확인

sudo docker exec -it <container_id> psql -U <username> -d <source_database> -c "SELECT schemaname,tablename FROM pg_tables WHERE schemaname = 'public';"

테이블별 데이터 건수 확인

sudo docker exec -it <container_id> psql -U <username> -d <source_database> -c "
SELECT 
    'table1' as table_name, COUNT(*) as row_count FROM table1
UNION ALL
SELECT 
    'table2' as table_name, COUNT(*) as row_count FROM table2
UNION ALL
SELECT 
    'table3' as table_name, COUNT(*) as row_count FROM table3;
-- 필요한 테이블 추가
"

2. 데이터 백업 및 덤프

대상 데이터베이스 백업 (안전을 위해)

sudo docker exec -t <container_id> pg_dump -U <username> -d <target_database> > target_database_backup.sql

소스 데이터베이스에서 데이터만 덤프

sudo docker exec -t <container_id> pg_dump -U <username> -d <source_database> --data-only --inserts --disable-triggers > source_data_only.sql

덤프 파일 크기 확인

ls -lh source_data_only.sql

3. 대상 데이터베이스 데이터 정리

외래키 제약조건을 고려한 데이터 삭제

sudo docker exec -it <container_id> psql -U <username> -d <target_database> -c "
-- 외래키 체크 비활성화
SET session_replication_role = replica;

-- 모든 테이블 데이터 삭제 (의존성 순서대로)
-- 참조되는 테이블부터 삭제
TRUNCATE TABLE child_table1, child_table2 RESTART IDENTITY CASCADE;
TRUNCATE TABLE parent_table1 RESTART IDENTITY CASCADE;
TRUNCATE TABLE parent_table2 RESTART IDENTITY CASCADE;

-- 외래키 체크 재활성화
SET session_replication_role = DEFAULT;
"

4. 데이터 마이그레이션 실행

덤프된 데이터를 대상 데이터베이스에 삽입

sudo docker exec -i <container_id> psql -U <username> -d <target_database> < source_data_only.sql

5. 마이그레이션 결과 확인

대상 데이터베이스 데이터 건수 확인

sudo docker exec -it <container_id> psql -U <username> -d <target_database> -c "
SELECT 
    'table1' as table_name, COUNT(*) as row_count FROM table1
UNION ALL
SELECT 
    'table2' as table_name, COUNT(*) as row_count FROM table2
UNION ALL
SELECT 
    'table3' as table_name, COUNT(*) as row_count FROM table3;
-- 필요한 테이블 추가
"

주의사항

1. 백업의 중요성

  • 마이그레이션 작업 전 반드시 대상 데이터베이스를 백업하세요
  • 원본 데이터도 안전한 곳에 보관하세요

2. 외래키 제약조건

  • 테이블 간 참조 관계를 고려하여 순서대로 데이터를 삭제/삽입하세요
  • RESTART IDENTITY CASCADE 옵션으로 시퀀스도 함께 초기화하세요

3. 권한 확인

  • 데이터베이스 사용자에게 충분한 권한이 있는지 확인하세요
  • 필요시 SUPERUSER 권한이 필요할 수 있습니다

4. 데이터 무결성 검증

  • 마이그레이션 후 데이터 건수뿐만 아니라 실제 데이터 내용도 샘플링하여 확인하세요
  • 애플리케이션 레벨에서도 정상 동작하는지 테스트하세요

트러블슈팅

덤프 파일이 0바이트인 경우

  • 데이터베이스 이름을 다시 확인하세요
  • 사용자 권한을 확인하세요
  • 에러 메시지를 확인하기 위해 2>&1을 추가하세요

외래키 제약조건 에러

  • 데이터 삽입 순서를 조정하세요
  • --disable-triggers 옵션을 사용하세요
  • 필요시 SET session_replication_role = replica;로 제약조건을 일시적으로 비활성화하세요

스키마 관련 에러

  • --data-only 옵션을 사용하여 스키마는 제외하고 데이터만 마이그레이션하세요
  • 테이블 구조가 동일한지 미리 확인하세요

고급 옵션

특정 테이블만 마이그레이션

# 특정 테이블만 덤프
sudo docker exec -t <container_id> pg_dump -U <username> -d <source_database> -t <table_name> --data-only --inserts > specific_table_data.sql

# 특정 테이블에만 삽입
sudo docker exec -i <container_id> psql -U <username> -d <target_database> < specific_table_data.sql

압축된 덤프 파일 사용

# 압축된 덤프 생성
sudo docker exec -t <container_id> pg_dump -U <username> -d <source_database> --data-only | gzip > source_data.sql.gz

# 압축된 덤프 복원
gunzip -c source_data.sql.gz | sudo docker exec -i <container_id> psql -U <username> -d <target_database>

병렬 처리 (대용량 데이터)

# 병렬 덤프 (디렉토리 형식)
sudo docker exec -t <container_id> pg_dump -U <username> -d <source_database> --data-only -j <num_jobs> -f dump_directory -F d

# 병렬 복원
sudo docker exec -t <container_id> pg_restore -U <username> -d <target_database> -j <num_jobs> dump_directory

사용 시 주의사항

  1. <container_id>, <username>, <source_database>, <target_database> 등의 플레이스홀더를 실제 환경에 맞게 변경하세요
  2. 테이블 이름은 실제 스키마에 맞게 수정하세요
  3. 외래키 관계를 파악하여 올바른 순서로 데이터를 처리하세요
  4. 운영 환경에서는 반드시 사전 테스트를 진행하세요

댓글 관련 문의: dev.goraebap @gmail.com