Disaster recovery (DR) tingkat lanjut dengan slot failover logis

Halaman ini menjelaskan cara menggunakan slot failover logis untuk mengonfigurasi replikasi logis Cloud SQL untuk PostgreSQL agar berfungsi dengan lancar dengan operasi pemulihan dari bencana (DR) lanjutan, khususnya pengalihan dan failover replika pada instance dengan edisi Cloud SQL Enterprise Plus.

Fitur pemulihan dari bencana (DR) tingkat lanjut Cloud SQL memungkinkan kemampuan pemulihan dari bencana yang andal. Jika digabungkan dengan replikasi logis PostgreSQL, sangat penting agar aliran replikasi tetap utuh setelah pengalihan atau failover replika.

Dengan menggunakan disaster recovery (DR) tingkat lanjut dengan replikasi logis PostgreSQL, Anda dapat memastikan bahwa pelanggan logis Anda tidak mengalami kehilangan data dan dapat terhubung kembali secara otomatis ke instance utama baru setelah peristiwa disaster recovery, sehingga memastikan kelangsungan bisnis.

Anda dapat menggunakan fungsi ini di instance Cloud SQL yang memiliki konfigurasi berikut:

  • PostgreSQL versi 17 atau yang lebih baru
  • Edisi Cloud SQL Enterprise Plus
  • Akses layanan pribadi

    Sebaiknya gunakan endpoint tulis layanan nama domain (DNS) akses layanan pribadi untuk mengaktifkan koneksi ulang otomatis pelanggan logis.

Sebelum memulai

Menyiapkan disaster recovery (DR) lanjutan dengan replikasi logis

Proses penyiapan disaster recovery (DR) tingkat lanjut dengan replikasi logis PostgreSQL memiliki langkah-langkah tingkat tinggi berikut:

  1. Siapkan variabel lingkungan dan VM bastion.
  2. Buat dan siapkan instance utama.
  3. Buat dan tetapkan replika DR.
  4. Buat dan siapkan instance pelanggan logis.
  5. Buat langganan replikasi logis.
  6. Lakukan pengalihan atau failover replika.
  7. Memvalidasi replikasi.
  8. Hapus slot replikasi yang tidak digunakan pada replika baru.
  9. Opsional: Lakukan pengembalian.

Menyiapkan variabel lingkungan dan VM bastion

  1. Tetapkan variabel lingkungan berikut.

    # 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
    

    Ganti kode berikut:

    • PROJECT_ID: ID project Anda.
    • PRIMARY_INSTANCE: nama instance Cloud SQL utama.
    • DR_REPLICA: nama replika.
    • SUBSCRIBER_INSTANCE: nama instance pelanggan.
    • BASTION_VM: nama VM bastion.
    • PRIMARY_REGION: region tempat instance utama berada.
    • REPLICA_REGION: region tempat replika berada. Replika harus berada di region yang berbeda dengan instance utama.
    • SUBSCRIBER_REGION: region tempat pelanggan berada.
    • VM_ZONE: zona tempat VM bastion berada.
    • NETWORK: nama jaringan VPC Anda.
    • PASSWORD: sandi untuk pengguna postgres.
  2. Buat VM bastion Compute Engine.

    Instance Cloud SQL menggunakan IP pribadi. Oleh karena itu, buat VM bastion host Compute Engine di jaringan VPC Anda.

    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
    
  3. Hubungkan ke VM bastion.

    gcloud compute ssh $BASTION_VM_NAME \
      --zone=$VM_ZONE \
      --project=$PROJECT
    
  4. Di VM bastion, instal klien PostgreSQL.

    sudo apt-get update
    sudo apt-get install -y postgresql-client
    exit
    

Perintah PostgreSQL pada langkah-langkah berikutnya harus dijalankan dari VM bastion.

Membuat dan menyiapkan instance utama

  1. Buat instance Cloud SQL utama.

    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
    
  2. Aktifkan decoding logis.

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --database-flags=cloudsql.logical_decoding=on \
      --project=$PROJECT
    
  3. Setel sandi untuk pengguna postgres di server utama.

    gcloud sql users set-password postgres \
      --instance=$PRIMARY_INSTANCE_NAME \
      --password="$POSTGRES_PASSWORD" \
      --project=$PROJECT
    
  4. Hubungkan ke instance utama dari VM bastion.

    1. Ambil alamat IP pribadi instance utama.

      gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      Salin dan simpan alamat IP pribadi instance utama.

    2. SSH ke VM bastion Anda.

      gcloud compute ssh $BASTION_VM_NAME --zone=$VM_ZONE --project=$PROJECT
      
    3. Dari VM bastion, hubungkan ke instance utama.

      psql -h PRIMARY_PRIVATE_IP -U postgres
      

      Ganti PRIMARY_PRIVATE_IP dengan IP pribadi instance primer yang Anda ambil di Langkah 4.a dalam prosedur ini.

    4. Saat diminta memasukkan sandi, masukkan variabel $POSTGRES_PASSWORD.

      VM bastion Anda kini terhubung ke instance utama melalui PostgreSQL.

  5. Berikan izin dan buat publikasi.

    1. Berikan hak istimewa REPLICATION kepada pengguna postgres.

      ALTER USER postgres WITH REPLICATION;
      
    2. Berikan hak istimewa yang diperlukan pada skema dan tabel publik.

      GRANT SELECT ON ALL TABLES IN SCHEMA public TO postgres;
      
    3. Buat publikasi untuk semua tabel.

      CREATE PUBLICATION my_publication FOR ALL TABLES;
      
    4. Ketik exit untuk keluar dari PostgreSQL, lalu exit lagi untuk menutup sesi SSH VM bastion.

Membuat dan menetapkan replika disaster recovery (replika DR)

  1. Buat replika 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
    
  2. Tetapkan replika ini sebagai replika DR.

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --failover-dr-replica-name=$DR_REPLICA_NAME \
      --project=$PROJECT
    
  3. Mengonfigurasi replika DR untuk sinkronisasi slot logis.

    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
    
  4. Konfigurasi replikasi sinkron antara instance utama dan replika DR.

    Untuk mencegah potensi kehilangan data pada pelanggan logis jika terjadi gangguan instance utama secara tiba-tiba dan failover replika berikutnya, sebaiknya konfigurasi replikasi sinkron antara instance utama dan replika DR.

    Menyetel cloudsql.synchronized_standby_replicas pada instance utama akan memaksa pengirim Write-Ahead Log (WAL) replikasi logis instance utama untuk menunggu hingga replika DR telah menerima dan mengosongkan WAL untuk transaksi tertentu sebelum mengirimkan transaksi tersebut ke pelanggan logis. Hal ini memastikan bahwa status replika DR selalu lebih maju atau sama dengan status pelanggan logis.

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --database-flags="^:^cloudsql.logical_decoding=on:cloudsql.synchronized_standby_replicas=$DR_REPLICA_NAME" \
      --project=$PROJECT
    

Membuat dan menyiapkan instance pelanggan logis

  1. Buat instance pelanggan.

    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
    
  2. Aktifkan decoding logis di pelanggan.

    gcloud sql instances patch $SUBSCRIBER_INSTANCE_NAME \
      --database-flags=cloudsql.logical_decoding=on \
      --project=$PROJECT
    

Membuat langganan replikasi logis

  1. Ambil endpoint penulisan akses layanan pribadi instance utama.

    gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
      --format="value(replicationCluster.psaWriteEndpoint)" \
      --project=$PROJECT
    

    Salin dan simpan endpoint tulis.

  2. Hubungkan ke instance pelanggan.

    1. Perbarui sandi untuk pengguna postgres instance pelanggan.

      gcloud sql users set-password postgres \
        --instance=$SUBSCRIBER_INSTANCE_NAME \
        --password="$POSTGRES_PASSWORD" \
        --project=$PROJECT
      
    2. Ambil alamat IP pribadi instance pelanggan.

      gcloud sql instances describe $SUBSCRIBER_INSTANCE_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      Salin dan simpan alamat IP pribadi.

    3. SSH ke VM bastion.

      gcloud compute ssh $BASTION_VM_NAME \
        --zone=$VM_ZONE \
        --project=$PROJECT
      
    4. Dari VM bastion, hubungkan ke instance pelanggan melalui PostgreSQL.

      psql -h SUBSCRIBER_PRIVATE_IP -U postgres
      

      Ganti SUBSCRIBER_PRIVATE_IP dengan IP pribadi instance pelanggan yang Anda salin di Langkah 2.b prosedur ini.

    5. Saat diminta memasukkan sandi, masukkan variabel $POSTGRES_PASSWORD.

  3. Membuat langganan.

    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);
    

    Ganti kode berikut:

    • DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT: endpoint tulis akses layanan pribadi yang Anda salin di Langkah 1 prosedur ini.
    • PASSWORD: nilai variabel ${POSTGRES_PASSWORD}.
  4. Keluar dari PostgreSQL dan sesi SSH VM bastion.

  5. Opsional. Verifikasi persistensi slot pada replika DR.

    Transisi ke persisten (temporary = false) ini biasanya terjadi dengan cepat, sering kali dalam hitungan detik jika aktivitas utama rendah. Di bawah beban penulisan berat di server utama, proses ini mungkin memerlukan waktu lebih lama, biasanya sekitar satu menit. Slot harus tetap ada setelah menyelesaikan perintah manual ini.

    1. Dapatkan alamat IP pribadi replika DR.

      gcloud sql instances describe $DR_REPLICA_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      Salin dan simpan alamat IP pribadi replika DR.

    2. SSH ke VM bastion.

      gcloud compute ssh $BASTION_VM_NAME \
        --zone=$VM_ZONE \
        --project=$PROJECT
      
    3. Dari VM bastion, hubungkan ke replika DR.

      psql -h DR_REPLICA_PRIVATE_IP -U postgres
      

      Ganti DR_REPLICA_PRIVATE_IP dengan alamat IP pribadi replika DR yang Anda ambil di Langkah 5.a dari prosedur ini.

    4. Saat diminta memasukkan sandi, masukkan variabel $POSTGRES_PASSWORD.

    5. Periksa status slot.

      SELECT slot_name, slot_type, temporary, failover, synced
      FROM pg_replication_slots
      WHERE slot_type = 'logical' AND failover = true;
      

      Tunggu hingga kolom temporary menjadi f. Proses ini biasanya memerlukan waktu kurang dari satu menit.

    6. Keluar dari PostgreSQL dan sesi SSH VM bastion.

Melakukan failover replika atau switchover

Pilih operasi yang ingin Anda lakukan berdasarkan skenario Anda:

  • Switchover (pembalikan peran terencana): Pilih opsi ini untuk pemeliharaan terencana, pengujian pemulihan dari bencana, atau untuk mengganti peran saat instance utama sedang online dan berfungsi dengan baik. Operasi ini memastikan tidak ada kehilangan data untuk replikasi fisik.

    gcloud sql instances switchover $DR_REPLICA_NAME \
      --project=$PROJECT
    
  • Failover Replika (disaster recovery): Pilih opsi ini jika instance utama tidak tersedia atau tidak merespons. Operasi ini mempromosikan replika DR menjadi primer. Untuk meminimalkan risiko kehilangan data bagi pelanggan logis, pastikan cloudsql.synchronized_standby_replicas ditetapkan pada instance utama seperti yang direkomendasikan dalam Membuat dan menetapkan replika disaster recovery (replika DR).

    gcloud sql instances promote-replica $DR_REPLICA_NAME \
      --failover \
      --project=$PROJECT
    

    Promosi $DR_REPLICA_NAME terjadi dengan cepat. Namun, instance primer asli ($PRIMARY_INSTANCE_NAME) hanya dikonfigurasi ulang sebagai replika dari instance primer baru setelah kembali online. Anda dapat melacaknya dengan mencari operasi RECONFIGURE_OLD_PRIMARY yang selesai di $PRIMARY_INSTANCE_NAME dalam log operasi. Jalankan perintah berikut:

    gcloud sql operations list --instance=$PRIMARY_INSTANCE_NAME --project=$PROJECT --limit=10`
    

    Penyiapan pemulihan dari bencana dipulihkan sepenuhnya hanya setelah fase ini selesai.

Setelah salah satu operasi, pelanggan akan otomatis terhubung kembali ke $DR_REPLICA_NAME primer baru melalui endpoint tulis akses layanan pribadi.

Pengelolaan laporan

Alur kerja Cloud SQL secara otomatis mengelola tanda database yang diperlukan di kedua instance dalam cluster disaster recovery selama dan setelah operasi pengalihan dan failover replika, termasuk yang berikut:

  • Flag sinkronisasi slot logis (cloudsql.logical_decoding, hot_standby_feedback, sync_replication_slots, cloudsql.logical_slot_sync_dbname) dipastikan benar pada instance yang menjadi replika baru.
  • Flag cloudsql.synchronized_standby_replicas pada instance yang menjadi primer baru otomatis diperbarui untuk mengarah ke nama replika DR baru.

Anda tidak perlu menerapkan kembali atau mengubah tanda ini secara manual setelah operasi pengalihan atau failover replika. Cloud SQL mempertahankan konfigurasi yang benar untuk peran utama dan replika.

Memvalidasi replikasi

  1. Periksa status pelanggan.

    1. Dari VM bastion, jalankan perintah berikut.

      psql -h SUBSCRIBER_PRIVATE_IP -U postgres
      

      Ganti SUBSCRIBER_PRIVATE_IP dengan alamat IP pribadi instance pelanggan.

    2. Pada instance pelanggan, jalankan perintah berikut.

      SELECT subname, pid IS NOT NULL AS is_active
      FROM pg_stat_subscription;
      

      Statusnya harus streaming.

  2. Periksa status slot replikasi primer baru. Primer baru adalah replika DR sebelumnya ($DR_REPLICA_NAME).

    1. Dapatkan alamat IP pribadi dari primary baru.

      gcloud sql instances describe $DR_REPLICA_NAME \
        --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"
      

      Salin dan simpan alamat IP pribadi dari primary baru.

    2. SSH ke VM bastion.

      psql -h NEW_PRIMARY_PRIVATE_IP -U postgres
      

      Ganti NEW_PRIMARY_PRIVATE_IP dengan alamat IP pribadi primary baru yang Anda salin pada langkah sebelumnya.

    3. Pada instance utama yang baru, jalankan perintah berikut.

      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';
      

      Slot (misalnya, my_subscription) harus active = t.

      SELECT
          application_name,
          state
      FROM pg_stat_replication;
      

      pg_stat_replication akan menampilkan pelanggan yang terhubung.

Membersihkan slot replikasi yang tidak memiliki induk pada replika baru

Setelah operasi switchover dan failover selesai, instance primer asli ($PRIMARY_INSTANCE_NAME) kini menjadi replika. Instance replika baru ini masih mempertahankan slot replikasi logis asli bernama my_subscription di disknya. Slot my_subscription ini kini tidak memiliki induk karena pelanggan diharapkan terhubung ke primer baru ($DR_REPLICA_NAME) melalui endpoint penulisan akses layanan pribadi.

Cloud SQL tidak otomatis menghapus slot yang tidak digunakan ini dari replika baru. Hal ini karena Cloud SQL tidak dapat menentukan apakah pelanggan dikonfigurasi untuk menggunakan alamat IP instance, bukan endpoint tulis akses layanan pribadi. Pelanggan mungkin masih mencoba terhubung ke slot lama ini di replika baru hingga langganan diubah secara manual. Menjatuhkan slot secara otomatis dapat merusak konfigurasi tersebut.

Keberadaan slot yatim piatu ini di replika baru ($PRIMARY_INSTANCE_NAME) menyebabkan proses pekerja slotsync di instance ini menghasilkan error dalam log. Anda mungkin melihat pesan error seperti berikut di postgres.log replika baru. Error ini terus berulang saat pekerja slotsync terus mencoba.

ERROR: exiting from slot synchronization because same name slot "my_subscription" already exists on the standby

Untuk mencegah error tersebut dan agar pekerja slotsync dapat menetapkan versi baru yang disinkronkan dengan benar dari slot my_subscription pada replika ini, Anda perlu menghapus slot yang tidak memiliki induk secara manual. Hal ini memastikan instance ini disiapkan dengan benar jika Anda berencana untuk beralih kembali pada masa mendatang.

  1. Ambil alamat IP pribadi replika baru ($PRIMARY_INSTANCE_NAME).

    gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
      --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"
    

    Salin dan simpan alamat IP pribadi replika baru.

  2. SSH ke VM bastion.

    gcloud compute ssh $BASTION_VM_NAME \
      --zone=$VM_ZONE \
      --project=$PROJECT
    
  3. Dari VM bastion, hubungkan ke replika baru.

    psql -h NEW_REPLICA_IP -U postgres
    

    Ganti NEW_REPLICA_IP dengan alamat IP replika baru yang Anda salin di Langkah 1 prosedur ini.

  4. Saat diminta memasukkan sandi, masukkan variabel $POSTGRES_PASSWORD.

  5. Di replika baru ($PRIMARY_INSTANCE_NAME), hapus slot yang tidak digunakan.

    SELECT slot_name, slot_type, temporary, failover, synced, active
    FROM pg_replication_slots
    WHERE slot_name = 'my_subscription';
    

    Pastikan slot ada dengan synced = false dan active = false, lalu lepaskan.

    SELECT pg_drop_replication_slot('my_subscription');
    

    Slot yang tidak memiliki induk dihapus.

Sinkronisasi ulang otomatis slot

Setelah slot yang tidak memiliki induk dilepas, pekerja slotsync di replika baru ($PRIMARY_INSTANCE_NAME) akan otomatis terhubung ke primer baru ($DR_REPLICA_NAME) dalam siklus berikutnya. Tindakan ini akan membuat slot my_subscription lokal baru yang disinkronkan dengan slot aktif primer baru.

Anda dapat melihat pesan di replika baru postgres.log yang menunjukkan keberhasilan, mirip dengan berikut ini:

LOG: newly created slot "my_subscription" is sync-ready now

Slot yang disinkronkan baru memiliki failover=true dan pada akhirnya menjadi persisten (temporary=false), sehingga jika Anda beralih kembali nanti, instance ini sudah siap.

Opsional: Lakukan pengembalian

  1. Sekarang, alihkan kembali, jadikan $PRIMARY_INSTANCE_NAME sebagai instance utama lagi.

    gcloud sql instances switchover $PRIMARY_INSTANCE_NAME \
      --project=$PROJECT
    
  2. Lakukan verifikasi setelah beralih kembali.

    1. Periksa status instance pelanggan.

      SELECT subname, pid IS NOT NULL AS is_active
      FROM pg_stat_subscription;
      

      Langganan harus tetap aktif, yaitu is_active = t.

    2. Periksa status slot ($PRIMARY_INSTANCE_NAME) primary baru.

      SELECT slot_name, active FROM pg_replication_slots WHERE slot_type = 'logical';
      SELECT * FROM pg_stat_replication;
      

      Slot harus aktif dan pelanggan terhubung.

Memecahkan masalah

Masalah Pemecahan masalah

Error pada replika baru (yaitu, instance utama lama) setelah pengalihan:

"exiting from slot synchronization because same name slot already exists on the standby"

Ikuti langkah-langkah di Membersihkan slot replikasi yang tidak memiliki induk di replika baru.