메인 콘텐츠로 건너뛰기
이 가이드는 PeerDB를 사용하여 PostgreSQL 데이터베이스를 ClickHouse Managed Postgres로 마이그레이션하는 방법을 단계별로 안내합니다.

사전 요구 사항

  • 원본 PostgreSQL 데이터베이스에 대한 접근 권한.
  • 데이터를 마이그레이션할 ClickHouse Managed Postgres 인스턴스.
  • 머신에 설치된 PeerDB. PeerDB GitHub 리포지토리의 설치 지침을 따르면 됩니다. 리포지토리를 클론한 후 docker-compose up만 실행하면 됩니다. 이 가이드에서는 PeerDB UI를 사용하며, PeerDB가 실행되면 http://localhost:3000에서 접속할 수 있습니다.

마이그레이션 전 고려 사항

마이그레이션을 시작하기 전에 다음 사항을 확인하십시오.
  • 데이터베이스 객체: PeerDB는 소스 스키마를 기준으로 대상 데이터베이스에 테이블을 자동으로 생성합니다. 하지만 인덱스, 제약 조건, 트리거와 같은 일부 데이터베이스 객체는 자동으로 마이그레이션되지 않습니다. 이러한 객체는 마이그레이션 후 대상 데이터베이스에서 수동으로 다시 생성해야 합니다.
  • DDL 변경: 지속적 복제를 활성화하면 PeerDB는 DML 작업(INSERT, UPDATE, DELETE)에 대해 대상 데이터베이스를 소스와 동기화된 상태로 유지하고, ADD COLUMN 작업도 전파합니다. 하지만 다른 DDL 변경(예: DROP COLUMN, ALTER COLUMN)은 자동으로 전파되지 않습니다. 스키마 변경 지원에 대한 자세한 내용은 여기를 참조하십시오.
  • 네트워크 연결: PeerDB가 실행되는 머신에서 소스 데이터베이스와 대상 데이터베이스 모두에 연결할 수 있어야 합니다. 연결을 허용하려면 방화벽 규칙이나 Security Group 설정을 구성해야 할 수 있습니다.

피어 생성

먼저 원본 데이터베이스와 대상 데이터베이스에 대한 피어를 각각 생성해야 합니다. 피어는 데이터베이스 연결을 나타냅니다. PeerDB UI의 사이드바에서 “Peers”를 클릭해 “Peers” 섹션으로 이동합니다. 새 피어를 생성하려면 + New peer 버튼을 클릭합니다.

원본 피어 생성

호스트, 포트, 데이터베이스 이름, 사용자 이름, 비밀번호 등의 연결 정보를 입력하여 원본 PostgreSQL 데이터베이스용 피어를 생성합니다. 정보를 모두 입력했으면 Create peer 버튼을 클릭하여 피어를 저장하세요.

대상 피어 생성

마찬가지로, 필요한 연결 정보를 입력하여 ClickHouse Managed Postgres 인스턴스용 피어를 생성합니다. 인스턴스의 연결 정보는 ClickHouse Cloud 콘솔에서 확인할 수 있습니다. 정보를 모두 입력한 후 Create peer 버튼을 클릭하여 대상 피어를 저장합니다. 이제 “Peers” 섹션에 소스 피어와 대상 피어가 모두 표시되는 것을 확인할 수 있습니다.

원본 스키마 덤프 확보하기

대상 데이터베이스를 원본 데이터베이스와 동일하게 구성하려면 원본 데이터베이스의 스키마 덤프를 확보해야 합니다. pg_dump를 사용하면 원본 PostgreSQL 데이터베이스의 스키마만 포함된 dump를 생성할 수 있습니다:
Ubuntu:패키지 목록을 업데이트합니다:
sudo apt update
PostgreSQL 클라이언트를 설치합니다:
sudo apt install postgresql-client
macOS:방법 1: Homebrew 사용(권장)아직 설치되어 있지 않다면 Homebrew를 설치합니다:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
PostgreSQL을 설치합니다:
brew install postgresql
설치를 확인합니다:
pg_dump --version
pg_dump -d 'postgresql://<user>:<password>@<host>:<port>/<database>'  -s > source_schema.sql

스키마 덤프에서 고유 제약 조건 및 인덱스 제거

이를 대상 DB에 적용하기 전에, 이러한 제약 조건으로 인해 PeerDB의 대상 테이블 수집이 차단되지 않도록 덤프 파일에서 UNIQUE 제약 조건과 인덱스를 제거해야 합니다. 다음을 사용하여 제거할 수 있습니다:
# 미리보기
grep -n "CONSTRAINT.*UNIQUE" <dump_file_path>
grep -n "CREATE UNIQUE INDEX" <dump_file_path>
grep -n -E "(CONSTRAINT.*UNIQUE|CREATE UNIQUE INDEX)" <dump_file_path>

# 제거
sed -i.bak -E '/CREATE UNIQUE INDEX/,/;/d; /(CONSTRAINT.*UNIQUE|ADD CONSTRAINT.*UNIQUE)/d' <dump_file_path>

스키마 덤프를 대상 데이터베이스에 적용

스키마 덤프 파일을 정리한 후 psql접속한 다음 스키마 덤프 파일을 실행하여 대상 ClickHouse Managed Postgres 데이터베이스에 적용할 수 있습니다.
psql -h <target_host> -p <target_port> -U <target_username> -d <target_database> -f source_schema.sql
대상 측에서는 외래 키 제약 조건으로 인해 PeerDB 수집이 차단되지 않도록 해야 합니다. 이를 위해 대상 Role(위에서 대상 피어에 사용한 Role)을 변경해 session_replication_rolereplica로 설정되도록 할 수 있습니다:
ALTER ROLE <target_role> SET session_replication_role = replica;

미러 생성

다음으로, 원본 피어와 대상 피어 간의 데이터 마이그레이션 프로세스를 정의할 미러를 생성해야 합니다. PeerDB UI에서 사이드바의 “Mirrors”를 클릭해 “Mirrors” 섹션으로 이동하십시오. 새 미러를 생성하려면 + New mirror 버튼을 클릭하십시오.
  1. 마이그레이션 내용을 설명하는 이름을 미러에 지정하십시오.
  2. 드롭다운 메뉴에서 앞서 생성한 원본 피어와 대상 피어를 선택하십시오.
  3. 다음 사항을 확인하십시오:
  • 소프트 삭제가 OFF로 설정되어 있어야 합니다.
  • Advanced settings를 펼치십시오. Postgres type system is enabled는 활성화되어 있고 PeerDB columns are disabled는 비활성화되어 있는지 확인하십시오.
  1. 마이그레이션할 테이블을 선택하십시오. 특정 테이블만 선택하거나 원본 DB의 모든 테이블을 선택할 수 있습니다.
테이블 선택앞선 단계에서 스키마를 그대로 마이그레이션했으므로, 대상 DB의 대상 테이블 이름이 원본 테이블 이름과 동일한지 확인하십시오.
  1. 미러 설정을 완료했으면 Create mirror 버튼을 클릭하십시오.
“Mirrors” 섹션에서 새로 생성한 미러를 확인할 수 있습니다.

초기 적재가 완료될 때까지 기다리기

미러를 생성하면 PeerDB가 소스 데이터베이스에서 대상 데이터베이스로 초기 데이터 적재를 시작합니다. 미러를 클릭한 다음 초기 적재 탭을 클릭하면 초기 데이터 마이그레이션의 진행 상황을 모니터링할 수 있습니다. 초기 적재가 완료되면 마이그레이션이 완료되었음을 나타내는 상태가 표시됩니다.

초기 적재 및 복제 모니터링

source 피어를 클릭하면 PeerDB에서 실행 중인 명령 목록을 확인할 수 있습니다. 예를 들면 다음과 같습니다.
  1. 먼저 각 테이블의 행 수를 추정하기 위해 COUNT 쿼리를 실행합니다.
  2. 그런 다음 NTILE을 사용하는 파티셔닝 쿼리를 실행하여 대용량 테이블을 더 작은 청크로 나눠 데이터 전송 효율을 높입니다.
  3. 이후 FETCH 명령을 실행해 소스 데이터베이스에서 데이터를 가져온 다음, PeerDB가 이를 대상 데이터베이스에 동기화합니다.

마이그레이션 후 작업

이러한 단계는 구체적인 사용 사례와 애플리케이션 요구 사항에 따라 달라질 수 있습니다. 중요한 점은 새 시스템으로 완전히 전환하기 전에 데이터 일관성을 보장하고, 다운타임을 최소화하며, 마이그레이션된 데이터의 무결성을 검증하는 것입니다.
마이그레이션이 완료된 후에는 다음을 수행하십시오:
  • 컷오버 전 검증 확인 실행
트래픽을 전환하기 전에 원본과 대상의 주요 테이블을 비교합니다:
-- 중요 테이블의 행 수 비교
SELECT 'public.orders' AS table_name, COUNT(*) AS row_count FROM public.orders;
SELECT 'public.customers' AS table_name, COUNT(*) AS row_count FROM public.customers;

-- 활동이 많은 테이블의 최신 레코드 점검
SELECT MAX(updated_at) FROM public.orders;
SELECT MAX(id) FROM public.orders;
  • 원본 시스템의 쓰기 작업 중지
먼저 애플리케이션의 쓰기 작업을 일시 중지하십시오. 추가적인 안전장치로, cutover 중에는 원본 데이터베이스를 읽기 전용으로 설정하십시오:
ALTER DATABASE <source_db> SET default_transaction_read_only = on;
롤백이 필요한 경우 쓰기를 다시 활성화할 수 있습니다:
ALTER DATABASE <source_db> SET default_transaction_read_only = off;
  • 복제가 완전히 동기화되었는지 확인하세요
쓰기량이 많은 하나 이상의 테이블에서 최신 행이 원본과 대상 간에 일치하는지 확인하세요:
-- 소스와 타겟 모두에서 실행하여 결과를 비교하세요
SELECT MAX(id) AS latest_id, MAX(updated_at) AS latest_ts FROM public.orders;
  • 제약 조건, 인덱스, 트리거를 다시 생성하고 활성화
수집을 위해 제약 조건이나 인덱스를 제거했거나 적용을 미뤘다면 지금 다시 적용하십시오. 또한 이전에 대상의 복제 역할을 replica로 설정했다면 이를 재설정하십시오:
ALTER ROLE <target_role> SET session_replication_role = origin;
# 예시: constraints/indexes/triggers가 포함된 SQL 파일 적용
psql -h <target_host> -p <target_port> -U <target_user> -d <target_db> -f post_migration_objects.sql
  • 대상 테이블의 시퀀스 재설정
데이터를 로드한 후 시퀀스를 현재 테이블 값에 맞춰 조정합니다:
-- 시스템 스키마를 제외한 모든 serial/identity 기반 컬럼의 시퀀스 일괄 초기화
DO $$
DECLARE r RECORD;
BEGIN
    FOR r IN
        SELECT
            n.nspname AS schema_name,
            c.relname AS table_name,
            a.attname AS column_name,
            pg_get_serial_sequence(format('%I.%I', n.nspname, c.relname), a.attname) AS seq_name
        FROM pg_class c
        JOIN pg_namespace n ON n.oid = c.relnamespace
        JOIN pg_attribute a ON a.attrelid = c.oid
        WHERE c.relkind = 'r'
            AND a.attnum > 0
            AND NOT a.attisdropped
            AND n.nspname NOT IN ('pg_catalog', 'information_schema')
    LOOP
        IF r.seq_name IS NOT NULL THEN
            EXECUTE format(
                'SELECT setval(%L, COALESCE((SELECT MAX(%I) FROM %I.%I), 0) + 1, false)',
                r.seq_name, r.column_name, r.schema_name, r.table_name
            );
        END IF;
    END LOOP;
END $$;
  • 애플리케이션 트래픽 전환
검증을 통과하고 시퀀스/제약 조건이 준비되면 다음을 수행하십시오:
  1. 읽기 트래픽을 ClickHouse Managed Postgres로 전환합니다.
  2. 쓰기 트래픽을 ClickHouse Managed Postgres로 전환합니다.
  3. 애플리케이션 오류, 제약 조건 위반, 데이터베이스 상태를 모니터링합니다.
  • 리소스 정리
마이그레이션 결과가 만족스럽고 애플리케이션을 ClickHouse Managed Postgres를 사용하도록 전환했다면, PeerDB에서 미러와 피어를 삭제할 수 있습니다.
Replication slots지속적 복제를 활성화한 경우 PeerDB는 원본 PostgreSQL 데이터베이스에 replication slot을 생성합니다. 불필요한 리소스 사용을 방지하려면 마이그레이션을 마친 후 원본 데이터베이스에서 replication slot을 수동으로 삭제하십시오.

참고 자료

다음 단계

축하합니다! pg_dumppg_restore를 사용해 PostgreSQL 데이터베이스를 ClickHouse Managed Postgres로 성공적으로 마이그레이션했습니다. 이제 Managed Postgres의 기능과 ClickHouse 통합을 살펴볼 준비가 되었습니다. 시작하는 데 도움이 되는 10분 분량의 퀵스타트 가이드는 다음과 같습니다.
마지막 수정일 2026년 6월 10일