이 페이지에서는 논리적 장애 조치 슬롯을 사용하여 PostgreSQL용 Cloud SQL의 논리적 복제가 고급 재해 복구(DR) 작업(특히 Cloud SQL Enterprise Plus 버전이 있는 인스턴스의 전환 및 복제본 장애 조치)과 원활하게 작동하도록 구성하는 방법을 설명합니다.
Cloud SQL의 고급 재해 복구 (DR) 기능을 사용하면 강력한 재해 복구 기능을 사용할 수 있습니다. PostgreSQL의 논리 복제와 결합할 때는 전환 또는 복제본 장애 조치 후 복제 스트림이 중단되지 않는 것이 중요합니다.
PostgreSQL의 논리적 복제를 사용하여 고급 재해 복구 (DR)를 사용하면 논리적 구독자에게 데이터 손실이 발생하지 않으며 재해 복구 이벤트 후 새 기본 인스턴스에 자동으로 다시 연결되어 비즈니스 연속성을 보장할 수 있습니다.
다음 구성이 있는 Cloud SQL 인스턴스에서 이 기능을 사용할 수 있습니다.
- PostgreSQL 버전 17 이상
- Cloud SQL Enterprise Plus 버전
비공개 서비스 액세스
자동 논리적 구독자 재연결을 사용 설정하려면 비공개 서비스 액세스 도메인 이름 서비스 (DNS) 쓰기 엔드포인트를 사용하는 것이 좋습니다.
시작하기 전에
gcloud CLI를 설치 합니다.
버전 502.0.0 이상을 사용해야 합니다. Google Cloud SDK 버전을 확인하려면
gcloud --version을 실행합니다. Google Cloud SDK를 업데이트하려면gcloud components update를 실행합니다.Google Cloud 프로젝트를 만들거나 기존 프로젝트를 선택합니다.
필요한 Identity and Access Management (IAM) 역할 및 권한을 부여합니다.
프로젝트 만들기: 프로젝트 생성자 (
roles/resourcemanager.projectCreator)Cloud SQL 인스턴스를 만들고 관리하려면 Cloud SQL 관리자 (
roles/cloudsql.admin) 권한이 필요합니다.Compute Engine VM을 만들고 관리하려면 Compute 인스턴스 관리자 (v1) (
roles/compute.instanceAdmin.v1) 및 Compute 뷰어 (roles/compute.networkViewer)가 필요합니다.VPC 네트워크를 만들려면 네트워크 관리자 (
roles/compute.networkAdmin)가 필요합니다.
자세한 내용은 역할 및 권한을 참조하세요.
IAM 역할 및 권한을 부여하는 방법을 알아보려면 프로젝트, 폴더, 조직에 대한 액세스 관리를 참고하세요.
논리적 복제를 사용하여 고급 재해 복구 (DR) 설정
PostgreSQL의 논리적 복제를 사용하여 고급 재해 복구 (DR)를 설정하는 프로세스는 다음과 같은 대략적인 단계로 구성됩니다.
- 환경 변수 및 배스천 VM 설정
- 기본 인스턴스 만들기 및 설정
- DR 복제본을 만들고 지정합니다.
- 논리적 구독자 인스턴스를 만들고 설정합니다.
- 논리 복제 구독 만들기
- 전환 또는 복제본 장애 조치 수행
- 복제를 검사합니다.
- 새 복제본에서 고아 복제 슬롯 정리
- 선택사항: 스위치백 실행
환경 변수 및 배스천 VM 설정
다음 환경 변수를 설정합니다.
# Project export PROJECT="PROJECT_ID" # Instance names export PRIMARY_INSTANCE_NAME="PRIMARY_INSTANCE" export DR_REPLICA_NAME="DR_REPLICA" export SUBSCRIBER_INSTANCE_NAME="SUBSCRIBER_INSTANCE" export BASTION_VM_NAME="BASTION_VM" # Regions and zones export PRIMARY_REGION="PRIMARY_REGION" export REPLICA_REGION="REPLICA_REGION" export SUBSCRIBER_REGION="SUBSCRIBER_REGION" export VM_ZONE="VM_ZONE" # Network export NETWORK_NAME="NETWORK" # Credentials export POSTGRES_PASSWORD="PASSWORD" # Set gcloud project gcloud config set project PROJECT_ID다음을 바꿉니다.
- PROJECT_ID: 프로젝트의 ID입니다.
- PRIMARY_INSTANCE: 기본 Cloud SQL 인스턴스의 이름입니다.
- DR_REPLICA: 복제본의 이름입니다.
- SUBSCRIBER_INSTANCE: 구독자 인스턴스의 이름입니다.
- BASTION_VM: 배스천 VM의 이름입니다.
- PRIMARY_REGION: 기본 인스턴스가 있는 리전입니다.
- REPLICA_REGION: 복제본이 있는 리전입니다. 복제본은 기본 인스턴스와 다른 리전에 있어야 합니다.
- SUBSCRIBER_REGION: 구독자가 있는 리전입니다.
- VM_ZONE: 배스천 VM이 있는 영역입니다.
- NETWORK: VPC 네트워크의 이름입니다.
- PASSWORD:
postgres사용자의 비밀번호
Compute Engine 배스천 VM을 만듭니다.
Cloud SQL 인스턴스는 비공개 IP를 사용합니다. 따라서 VPC 네트워크에 Compute Engine 배스천 호스트 VM을 만듭니다.
gcloud compute instances create $BASTION_VM_NAME \ --zone=$VM_ZONE \ --machine-type=e2-small \ --network=projects/$PROJECT_ID/global/networks/$NETWORK_NAME \ --image-project=debian-cloud \ --image-family=debian-11 \ --project=$PROJECT배스천 VM에 연결합니다.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECT배스천 VM에서 PostgreSQL 클라이언트를 설치합니다.
sudo apt-get update sudo apt-get install -y postgresql-client exit
후속 단계의 PostgreSQL 명령어는 배스천 VM에서 실행해야 합니다.
기본 인스턴스 만들기 및 설정
기본 Cloud SQL 인스턴스를 만듭니다.
gcloud sql instances create $PRIMARY_INSTANCE_NAME \ --database-version=POSTGRES_17 \ --edition=ENTERPRISE_PLUS \ --region=$PRIMARY_REGION \ --tier=db-perf-optimized-N-2 \ --no-assign-ip \ --network=projects/$PROJECT/global/networks/$NETWORK_NAME \ --project=$PROJECT논리 디코딩을 사용 설정합니다.
gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --database-flags=cloudsql.logical_decoding=on \ --project=$PROJECT기본에서
postgres사용자의 비밀번호를 설정합니다.gcloud sql users set-password postgres \ --instance=$PRIMARY_INSTANCE_NAME \ --password="$POSTGRES_PASSWORD" \ --project=$PROJECT배스천 VM에서 기본 인스턴스에 연결합니다.
기본 인스턴스의 비공개 IP 주소를 가져옵니다.
gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECT기본 인스턴스의 비공개 IP 주소를 복사하여 보관합니다.
배스천 VM에 SSH로 연결합니다.
gcloud compute ssh $BASTION_VM_NAME --zone=$VM_ZONE --project=$PROJECT배스천 VM에서 기본 인스턴스에 연결합니다.
psql -h PRIMARY_PRIVATE_IP -U postgresPRIMARY_PRIVATE_IP를 이 절차의 4.a단계에서 가져온 기본 인스턴스의 비공개 IP로 바꿉니다.
비밀번호를 입력하라는 메시지가 표시되면 변수
$POSTGRES_PASSWORD를 입력합니다.이제 PostgreSQL을 통해 배스천 VM이 기본 인스턴스에 연결됩니다.
권한을 부여하고 게시를 만듭니다.
postgres사용자에게REPLICATION권한을 부여합니다.ALTER USER postgres WITH REPLICATION;공개 스키마와 테이블에 필요한 권한을 부여합니다.
GRANT SELECT ON ALL TABLES IN SCHEMA public TO postgres;모든 테이블에 대한 게시를 만듭니다.
CREATE PUBLICATION my_publication FOR ALL TABLES;exit를 입력하여 PostgreSQL을 종료한 다음exit를 다시 입력하여 베스천 VM의 SSH 세션을 닫습니다.
재해 복구 복제본 (DR 복제본) 만들기 및 지정
DR 복제본을 만듭니다.
gcloud sql instances create $DR_REPLICA_NAME \ --master-instance-name=$PRIMARY_INSTANCE_NAME \ --edition=ENTERPRISE_PLUS \ --tier=db-perf-optimized-N-2 \ --region=$REPLICA_REGION \ --no-assign-ip \ --network=projects/$PROJECT/global/networks/$NETWORK_NAME \ --project=$PROJECT이 복제본을 DR 복제본으로 지정합니다.
gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --failover-dr-replica-name=$DR_REPLICA_NAME \ --project=$PROJECT논리 슬롯 동기화를 위해 DR 복제본을 구성합니다.
gcloud sql instances patch $DR_REPLICA_NAME \ --database-flags="^:^cloudsql.logical_decoding=on:hot_standby_feedback=on:sync_replication_slots=on:cloudsql.logical_slot_sync_dbname=postgres" \ --project=$PROJECT기본 인스턴스와 DR 복제본 간에 동기 복제를 구성합니다.
기본 인스턴스가 갑자기 중단되고 후속 복제본 장애 조치가 발생하는 경우 논리적 구독자에서 발생할 수 있는 데이터 손실을 방지하려면 기본 인스턴스와 DR 복제본 간에 동기 복제를 구성하는 것이 좋습니다.
기본 인스턴스에서
cloudsql.synchronized_standby_replicas를 설정하면 기본 인스턴스의 논리적 복제 미리 쓰기 로그 (WAL) 전송자가 DR 복제본이 특정 트랜잭션의 WAL을 수신하고 플러시할 때까지 기다린 후 해당 트랜잭션을 논리적 구독자에게 전송합니다. 이렇게 하면 DR 복제본의 상태가 항상 논리적 구독자의 상태보다 앞서거나 같아집니다.gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --database-flags="^:^cloudsql.logical_decoding=on:cloudsql.synchronized_standby_replicas=$DR_REPLICA_NAME" \ --project=$PROJECT
논리적 구독자 인스턴스 만들기 및 설정
구독자 인스턴스를 만듭니다.
gcloud sql instances create $SUBSCRIBER_INSTANCE_NAME \ --database-version=POSTGRES_17 \ --tier=db-perf-optimized-N-2 \ --region=$SUBSCRIBER_REGION \ --no-assign-ip \ --network=projects/$PROJECT/global/networks/$NETWORK_NAME \ --project=$PROJECT구독자에서 논리적 디코딩을 사용 설정합니다.
gcloud sql instances patch $SUBSCRIBER_INSTANCE_NAME \ --database-flags=cloudsql.logical_decoding=on \ --project=$PROJECT
논리적 복제 구독 만들기
기본 인스턴스의 비공개 서비스 액세스 쓰기 엔드포인트를 가져옵니다.
gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --format="value(replicationCluster.psaWriteEndpoint)" \ --project=$PROJECT쓰기 엔드포인트를 복사하여 보관합니다.
구독자 인스턴스에 연결합니다.
구독자 인스턴스의
postgres사용자의 비밀번호를 업데이트합니다.gcloud sql users set-password postgres \ --instance=$SUBSCRIBER_INSTANCE_NAME \ --password="$POSTGRES_PASSWORD" \ --project=$PROJECT구독자 인스턴스의 비공개 IP 주소를 가져옵니다.
gcloud sql instances describe $SUBSCRIBER_INSTANCE_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECT비공개 IP 주소를 복사하여 보관합니다.
배스천 VM에 SSH로 연결합니다.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECT배스천 VM에서 PostgreSQL을 통해 구독자 인스턴스에 연결합니다.
psql -h SUBSCRIBER_PRIVATE_IP -U postgresSUBSCRIBER_PRIVATE_IP를 이 절차의 2.b단계에서 복사한 구독자 인스턴스의 비공개 IP로 바꿉니다.
비밀번호를 입력하라는 메시지가 표시되면 변수
$POSTGRES_PASSWORD를 입력합니다.
구독을 만드세요.
CREATE SUBSCRIPTION my_subscription CONNECTION 'host=DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT port=5432 dbname=postgres user=postgres password=PASSWORD' PUBLICATION my_publication WITH (failover = true);다음을 바꿉니다.
- DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT: 이 절차의 1단계에서 복사한 비공개 서비스 액세스 쓰기 엔드포인트입니다.
- PASSWORD: 변수
${POSTGRES_PASSWORD}의 값입니다.
PostgreSQL 및 배스천 VM SSH 세션을 종료합니다.
선택사항입니다. DR 복제본에서 슬롯 지속성을 확인합니다.
이 영구 (
temporary = false)로의 전환은 일반적으로 빠르게 발생하며, 기본 활동이 적은 경우 몇 초 이내에 발생합니다. 기본 항목에 쓰기 부하가 심한 경우 이 프로세스가 더 오래 걸릴 수 있으며 일반적으로 1분 정도 걸립니다. 이러한 수동 명령어를 완료한 후에는 슬롯이 지속되어야 합니다.DR 복제본의 비공개 IP 주소를 가져옵니다.
gcloud sql instances describe $DR_REPLICA_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECTDR 복제본의 비공개 IP 주소를 복사하여 보관합니다.
배스천 VM에 SSH로 연결합니다.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECT배스천 VM에서 DR 복제본에 연결합니다.
psql -h DR_REPLICA_PRIVATE_IP -U postgresDR_REPLICA_PRIVATE_IP를 이 절차의 5.a단계에서 가져온 DR 복제본의 비공개 IP 주소로 바꿉니다.
비밀번호를 입력하라는 메시지가 표시되면 변수
$POSTGRES_PASSWORD를 입력합니다.슬롯 상태를 확인합니다.
SELECT slot_name, slot_type, temporary, failover, synced FROM pg_replication_slots WHERE slot_type = 'logical' AND failover = true;temporary열이f이 될 때까지 기다립니다. 이 작업은 보통 1분 이내에 완료됩니다.PostgreSQL 및 배스천 VM SSH 세션을 종료합니다.
전환 또는 복제본 장애 조치 수행
시나리오에 따라 수행할 작업을 선택합니다.
전환 (계획된 역할 반전): 계획된 유지보수, 재해 복구 테스트 또는 기본 인스턴스가 온라인 상태이고 정상일 때 역할을 전환하려면 이 옵션을 선택합니다. 이 작업은 실제 복제에 대해 데이터 손실이 없도록 합니다.
gcloud sql instances switchover $DR_REPLICA_NAME \ --project=$PROJECT복제본 장애 조치 (재해 복구): 기본 인스턴스를 사용할 수 없거나 응답하지 않는 경우 선택합니다. 이 작업은 DR 복제본을 기본으로 승격합니다. 논리적 구독자의 데이터 손실 위험을 최소화하려면 재해 복구 복제본 (DR 복제본) 만들기 및 지정에 권장된 대로 기본 인스턴스에
cloudsql.synchronized_standby_replicas가 설정되어 있는지 확인하세요.gcloud sql instances promote-replica $DR_REPLICA_NAME \ --failover \ --project=$PROJECT$DR_REPLICA_NAME승격은 빠르게 진행됩니다. 하지만 원래 기본 인스턴스 ($PRIMARY_INSTANCE_NAME)는 다시 온라인 상태가 된 후에만 새 기본 인스턴스의 복제본으로 재구성됩니다. 작업 로그에서$PRIMARY_INSTANCE_NAME에 대한RECONFIGURE_OLD_PRIMARY작업이 완료되었는지 확인하여 이를 추적할 수 있습니다. 다음 명령어를 실행합니다.gcloud sql operations list --instance=$PRIMARY_INSTANCE_NAME --project=$PROJECT --limit=10`이 단계가 완료된 후에만 재해 복구 설정이 완전히 복원됩니다.
두 작업 중 하나를 수행한 후에는 구독자가 비공개 서비스 액세스 쓰기 엔드포인트를 통해 새 기본 $DR_REPLICA_NAME에 자동으로 다시 연결됩니다.
플래그 관리
Cloud SQL의 워크플로는 전환 및 복제본 장애 조치 작업 중과 후에 재해 복구 클러스터 내 두 인스턴스에서 필요한 데이터베이스 플래그를 자동으로 관리합니다.
- 논리 슬롯 동기화 플래그 (
cloudsql.logical_decoding,hot_standby_feedback,sync_replication_slots,cloudsql.logical_slot_sync_dbname)는 새 복제본이 되는 인스턴스에서 올바른 것으로 보장됩니다. - 새 기본이 되는 인스턴스의
cloudsql.synchronized_standby_replicas플래그가 새 DR 복제본의 이름을 가리키도록 자동으로 업데이트됩니다.
스위치오버 또는 복제본 장애 조치 작업 후 이러한 플래그를 수동으로 다시 적용하거나 변경할 필요가 없습니다. Cloud SQL은 기본 역할과 복제본 역할에 대해 올바른 구성을 유지합니다.
복제 검사
구독자의 상태를 확인합니다.
배스천 VM에서 다음 명령어를 실행합니다.
psql -h SUBSCRIBER_PRIVATE_IP -U postgresSUBSCRIBER_PRIVATE_IP를 구독자 인스턴스의 비공개 IP 주소로 바꿉니다.
구독자 인스턴스에서 다음 명령어를 실행합니다.
SELECT subname, pid IS NOT NULL AS is_active FROM pg_stat_subscription;상태는
streaming이어야 합니다.
새 기본의 복제 슬롯 상태를 확인합니다. 새 기본은 이전 DR 복제본 (
$DR_REPLICA_NAME)입니다.새 기본의 비공개 IP 주소를 가져옵니다.
gcloud sql instances describe $DR_REPLICA_NAME \ --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"새 기본의 비공개 IP 주소를 복사하여 보관합니다.
배스천 VM에 SSH로 연결합니다.
psql -h NEW_PRIMARY_PRIVATE_IP -U postgresNEW_PRIMARY_PRIVATE_IP를 이전 단계에서 복사한 새 기본의 비공개 IP 주소로 바꿉니다.
새 기본 인스턴스에서 다음 명령어를 실행합니다.
SELECT slot_name, slot_type, active, synced, active_pid, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS replication_lag FROM pg_replication_slots WHERE slot_type = 'logical';슬롯 (예:
my_subscription)은active = t여야 합니다.SELECT application_name, state FROM pg_stat_replication;pg_stat_replication에 연결된 구독자가 표시됩니다.
새 복제본에서 고아 복제 슬롯 정리
전환 및 장애 조치 작업이 완료되면 원래 기본 인스턴스 ($PRIMARY_INSTANCE_NAME)가 이제 복제본이 됩니다. 이 새 복제본 인스턴스는 디스크에 my_subscription라는 원래 논리적 복제 슬롯을 계속 유지합니다. 이제 이 my_subscription 슬롯은 구독자가 비공개 서비스 액세스 쓰기 엔드포인트를 통해 새 기본 ($DR_REPLICA_NAME)에 연결해야 하므로 고아가 되었습니다.
Cloud SQL은 새 복제본에서 이 고아 슬롯을 자동으로 삭제하지 않습니다. 이는 Cloud SQL에서 구독자가 비공개 서비스 액세스 쓰기 엔드포인트 대신 인스턴스의 IP 주소를 사용하도록 구성되었는지 확인할 수 없기 때문입니다. 정기 결제가 수동으로 변경될 때까지 구독자가 새 복제본의 이 이전 슬롯에 연결하려고 시도할 수 있습니다. 슬롯이 자동으로 삭제되면 이러한 구성이 중단될 수 있습니다.
새 복제본 ($PRIMARY_INSTANCE_NAME)에 이 고아 슬롯이 있으면 이 인스턴스의 slotsync 작업자 프로세스가 로그에 오류를 생성합니다. 새 복제본의 postgres.log에 다음과 같은 오류 메시지가 표시될 수 있습니다. slotsync 작업자가 계속 시도하므로 이 오류가 계속 반복됩니다.
ERROR: exiting from slot synchronization because same name slot "my_subscription" already exists on the standby
이러한 오류를 방지하고 slotsync 작업자가 이 복제본에서 동기화된 새 버전의 my_subscription 슬롯을 올바르게 설정하도록 하려면 고아 슬롯을 수동으로 삭제해야 합니다. 이렇게 하면 향후 다시 전환하려는 경우 이 인스턴스가 적절하게 준비됩니다.
새 복제본 (
$PRIMARY_INSTANCE_NAME)의 비공개 IP 주소를 가져옵니다.gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"새 복제본의 비공개 IP 주소를 복사하여 보관합니다.
배스천 VM에 SSH로 연결합니다.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECT배스천 VM에서 새 복제본에 연결합니다.
psql -h NEW_REPLICA_IP -U postgresNEW_REPLICA_IP를 이 절차의 1단계에서 복사한 새 복제본의 IP 주소로 바꿉니다.
비밀번호를 입력하라는 메시지가 표시되면 변수
$POSTGRES_PASSWORD를 입력합니다.새 복제본 (
$PRIMARY_INSTANCE_NAME)에서 고아 슬롯을 삭제합니다.SELECT slot_name, slot_type, temporary, failover, synced, active FROM pg_replication_slots WHERE slot_name = 'my_subscription';슬롯이
synced = false및active = false와 함께 존재하는지 확인한 후 삭제합니다.SELECT pg_drop_replication_slot('my_subscription');고아 슬롯이 삭제됩니다.
자동 슬롯 재동기화
고아 슬롯이 삭제되면 새 복제본($PRIMARY_INSTANCE_NAME)의 slotsync 작업자가 다음 주기에서 새 기본($DR_REPLICA_NAME)에 자동으로 연결됩니다. 새 기본의 활성 슬롯과 동기화된 새 로컬 my_subscription 슬롯을 만듭니다.
새 복제본의 postgres.log에 다음과 유사한 성공 메시지가 표시됩니다.
LOG: newly created slot "my_subscription" is sync-ready now
새로 동기화된 슬롯에는 failover=true이 있으며 결국 영구(temporary=false)가 되므로 나중에 다시 전환하는 경우 이 인스턴스가 준비됩니다.
선택사항: 롤백 실행
이제 다시 전환하여
$PRIMARY_INSTANCE_NAME을 기본 인스턴스로 다시 만듭니다.gcloud sql instances switchover $PRIMARY_INSTANCE_NAME \ --project=$PROJECT롤백 후 확인을 실행합니다.
게시자 인스턴스의 상태를 확인합니다.
SELECT subname, pid IS NOT NULL AS is_active FROM pg_stat_subscription;구독이 여전히 활성 상태여야 합니다(
is_active = t).새 기본 슬롯 (
$PRIMARY_INSTANCE_NAME)의 상태를 확인합니다.SELECT slot_name, active FROM pg_replication_slots WHERE slot_type = 'logical'; SELECT * FROM pg_stat_replication;슬롯이 활성 상태이고 구독자가 연결되어 있어야 합니다.
문제 해결
| 문제 | 문제 해결 |
|---|---|
전환 후 새 복제본 (이전 기본 인스턴스)의 오류:
|
새 복제본에서 고아 복제 슬롯 정리의 단계를 따릅니다. |