PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Gambaran Umum Replikasi Logis di PostgreSQL

PostgreSQL adalah salah satu database open source tercanggih di dunia dengan banyak fitur hebat. Salah satunya adalah Streaming Replication (Physical Replication) yang diperkenalkan di PostgreSQL 9.0. Ini didasarkan pada catatan XLOG yang ditransfer ke server tujuan dan diterapkan di sana. Namun, ini berbasis cluster dan kami tidak dapat melakukan replikasi database tunggal atau objek tunggal (replikasi selektif). Selama bertahun-tahun, kami bergantung pada alat eksternal seperti Slony, Bucardo, BDR, dll untuk replikasi selektif atau sebagian karena tidak ada fitur di tingkat inti hingga PostgreSQL 9.6. Namun, PostgreSQL 10 hadir dengan fitur yang disebut Replikasi Logis, yang melaluinya kita dapat melakukan replikasi tingkat basis data/objek.

Replikasi Logis mereplikasi perubahan objek berdasarkan identitas replikasinya, yang biasanya merupakan kunci utama. Ini berbeda dengan replikasi fisik, di mana replikasi didasarkan pada blok dan replikasi byte demi byte. Replikasi Logis tidak memerlukan salinan biner yang tepat di sisi server tujuan, dan kami memiliki kemampuan untuk menulis di server tujuan tidak seperti Replikasi Fisik. Fitur ini berasal dari modul pglogical.

Dalam posting blog ini, kita akan membahas:

  • Cara kerjanya - Arsitektur
  • Fitur
  • Kasus penggunaan - jika berguna
  • Batasan
  • Cara mencapainya

Cara Kerjanya - Arsitektur Replikasi Logis

Replikasi Logis menerapkan konsep publish and subscribe (Publikasi &Berlangganan). Di bawah ini adalah diagram arsitektur tingkat yang lebih tinggi tentang cara kerjanya.

Arsitektur Replikasi Logika Dasar

Publikasi dapat ditentukan di server master dan simpul yang menetapkannya disebut sebagai "penerbit". Publikasi adalah sekumpulan perubahan dari satu tabel atau sekelompok tabel. Itu ada di tingkat basis data dan setiap publikasi ada dalam satu basis data. Beberapa tabel bisa ditambahkan ke satu publikasi dan tabel bisa di beberapa publikasi. Anda harus menambahkan objek secara eksplisit ke publikasi kecuali jika Anda memilih opsi "SEMUA TABEL" yang memerlukan hak pengguna super.

Anda dapat membatasi perubahan objek (INSERT, UPDATE, dan DELETE) untuk direplikasi. Secara default, semua jenis operasi direplikasi. Anda harus memiliki identitas replikasi yang dikonfigurasi untuk objek yang ingin Anda tambahkan ke publikasi. Ini untuk mereplikasi operasi UPDATE dan DELETE. Identitas replikasi dapat berupa kunci utama atau indeks unik. Jika tabel tidak memiliki kunci utama atau indeks unik, maka tabel tersebut dapat diatur ke identitas replika "penuh" di mana ia mengambil semua kolom sebagai kunci (seluruh baris menjadi kunci).

Anda dapat membuat publikasi menggunakan CREATE PUBLICATION. Beberapa perintah praktis dibahas di bagian "Cara mencapainya".

Langganan dapat ditentukan di server tujuan dan node yang menetapkannya disebut sebagai "pelanggan". Koneksi ke database sumber ditentukan dalam langganan. Node pelanggan sama dengan basis data postgres lain yang berdiri sendiri, dan Anda juga dapat menggunakannya sebagai publikasi untuk langganan lebih lanjut.

Langganan ditambahkan menggunakan CREATE SUBSCRIPTION dan dapat dihentikan/dilanjutkan kapan saja menggunakan perintah ALTER SUBSCRIPTION dan dihapus menggunakan DROP SUBSCRIPTION.

Setelah langganan dibuat, Replikasi logis menyalin snapshot data di database penerbit. Setelah selesai, ia menunggu perubahan delta dan mengirimkannya ke node langganan segera setelah terjadi.

Namun, bagaimana perubahan dikumpulkan? Siapa yang mengirim mereka ke target? Dan siapa yang menerapkannya pada target? Replikasi logis juga didasarkan pada arsitektur yang sama dengan replikasi fisik. Ini diimplementasikan oleh proses "walsender" dan "terapkan". Karena didasarkan pada decoding WAL, siapa yang memulai decoding? Proses walsender bertanggung jawab untuk memulai decoding logis dari WAL, dan memuat plugin decoding logis standar (pgoutput). Plugin mengubah perubahan yang dibaca dari WAL ke protokol replikasi logis, dan memfilter data sesuai dengan spesifikasi publikasi. Data kemudian terus ditransfer menggunakan protokol replikasi streaming ke pekerja yang menerapkan, yang memetakan data ke tabel lokal dan menerapkan perubahan individual saat diterima, dalam urutan transaksional yang benar.

Ini mencatat semua langkah ini dalam file log saat mengaturnya. Kita dapat melihat pesan di bagian "Cara mencapainya" nanti di postingan.

Fitur Replikasi Logika

  • Replikasi Logis mereplikasi objek data berdasarkan identitas replikasinya (umumnya
  • kunci utama atau indeks unik).
  • Server tujuan dapat digunakan untuk menulis. Anda dapat memiliki indeks dan definisi keamanan yang berbeda.
  • Replikasi Logis memiliki dukungan lintas versi. Tidak seperti Replikasi Streaming, Replikasi Logis dapat diatur di antara berbagai versi PostgreSQL (> 9.4, meskipun)
  • Replikasi Logis melakukan pemfilteran berbasis Peristiwa
  • Jika dibandingkan, Replikasi Logis memiliki amplifikasi tulis yang lebih sedikit daripada Replikasi Streaming
  • Publikasi dapat memiliki beberapa langganan
  • Replikasi Logis memberikan fleksibilitas penyimpanan melalui replikasi set yang lebih kecil (bahkan tabel yang dipartisi)
  • Pemuatan server minimum dibandingkan dengan solusi berbasis pemicu
  • Memungkinkan streaming paralel di seluruh penerbit
  • Replikasi Logis dapat digunakan untuk migrasi dan peningkatan versi
  • Transformasi data dapat dilakukan saat menyiapkan.

Use Cases - Kapan Replikasi Logika Berguna?

Sangat penting untuk mengetahui kapan harus menggunakan Replikasi Logis. Jika tidak, Anda tidak akan mendapatkan banyak manfaat jika use case Anda tidak cocok. Jadi, berikut adalah beberapa kasus penggunaan kapan harus menggunakan Replikasi Logis:

  • Jika Anda ingin menggabungkan beberapa database menjadi satu database untuk tujuan analitis.
  • Jika kebutuhan Anda adalah untuk mereplikasi data antara berbagai versi utama PostgreSQL.
  • Jika Anda ingin mengirim perubahan tambahan dalam satu database atau subset database ke database lain.
  • Jika memberikan akses ke data yang direplikasi ke grup pengguna yang berbeda.
  • Jika berbagi subset database di antara beberapa database.

Batasan Replikasi Logika

Replikasi Logis memiliki beberapa keterbatasan yang terus diupayakan untuk diatasi oleh komunitas:

  • Tabel harus memiliki nama lengkap yang sama antara publikasi dan langganan.
  • Tabel harus memiliki kunci utama atau kunci unik
  • Replikasi timbal balik (dua arah) tidak didukung
  • Tidak meniru skema/DDL
  • Tidak meniru urutan
  • Tidak meniru TRUNCATE
  • Tidak mereplikasi Objek Besar
  • Langganan dapat memiliki lebih banyak kolom atau urutan kolom yang berbeda, tetapi jenis dan nama kolom harus cocok antara Publikasi dan Langganan.
  • Hak istimewa pengguna super untuk menambahkan semua tabel
  • Anda tidak dapat melakukan streaming ke host yang sama (langganan akan dikunci).
Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh Whitepaper

Cara Mencapai Replikasi Logis

Berikut adalah langkah-langkah untuk mencapai Replikasi Logis dasar. Kita bisa mendiskusikan skenario yang lebih kompleks nanti.

  1. Inisialisasi dua instance berbeda untuk publikasi dan langganan, lalu mulai.

    C1MQV0FZDTY3:bin bajishaik$ export PATH=$PWD:$PATH
    C1MQV0FZDTY3:bin bajishaik$ which psql
    /Users/bajishaik/pg_software/10.2/bin/psql
    C1MQV0FZDTY3:bin bajishaik$ ./initdb -D /tmp/publication_db
    
    C1MQV0FZDTY3:bin bajishaik$ ./initdb -D /tmp/subscription_db
  2. Parameter yang akan diubah sebelum Anda memulai instance (untuk instance publikasi dan langganan).

    C1MQV0FZDTY3:bin bajishaik$ tail -3 /tmp/publication_db/postgresql.conf
    listen_addresses='*'
    port = 5555
    wal_level= logical
    
    
    C1MQV0FZDTY3:bin bajishaik$ pg_ctl -D /tmp/publication_db/ start
    waiting for server to start....2018-03-21 16:03:30.394 IST [24344] LOG:  listening on IPv4 address "0.0.0.0", port 5555
    2018-03-21 16:03:30.395 IST [24344] LOG:  listening on IPv6 address "::", port 5555
    2018-03-21 16:03:30.544 IST [24344] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5555"
    2018-03-21 16:03:30.662 IST [24345] LOG:  database system was shut down at 2018-03-21 16:03:27 IST
    2018-03-21 16:03:30.677 IST [24344] LOG:  database system is ready to accept connections
     done
    server started
    
    C1MQV0FZDTY3:bin bajishaik$ tail -3 /tmp/subscription_db/postgresql.conf
    listen_addresses='*'
    port=5556
    wal_level=logical
    
    C1MQV0FZDTY3:bin bajishaik$ pg_ctl -D /tmp/subscription_db/ start
    waiting for server to start....2018-03-21 16:05:28.408 IST [24387] LOG:  listening on IPv4 address "0.0.0.0", port 5556
    2018-03-21 16:05:28.408 IST [24387] LOG:  listening on IPv6 address "::", port 5556
    2018-03-21 16:05:28.410 IST [24387] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5556"
    2018-03-21 16:05:28.460 IST [24388] LOG:  database system was shut down at 2018-03-21 15:59:32 IST
    2018-03-21 16:05:28.512 IST [24387] LOG:  database system is ready to accept connections
     done
    server started

    Parameter lain dapat diatur secara default untuk pengaturan dasar.

  3. Ubah file pg_hba.conf untuk memungkinkan replikasi. Perhatikan bahwa nilai ini bergantung pada lingkungan Anda, namun, ini hanyalah contoh dasar (untuk instance publikasi dan langganan).

    C1MQV0FZDTY3:bin bajishaik$ tail -1 /tmp/publication_db/pg_hba.conf
     host     all     repuser     0.0.0.0/0     md5
    C1MQV0FZDTY3:bin bajishaik$ tail -1 /tmp/subscription_db/pg_hba.conf
     host     all     repuser     0.0.0.0/0     md5
    
    C1MQV0FZDTY3:bin bajishaik$ psql -p 5555 -U bajishaik -c "select pg_reload_conf()"
    Timing is on.
    Pager usage is off.
    2018-03-21 16:08:19.271 IST [24344] LOG:  received SIGHUP, reloading configuration files
     pg_reload_conf
    ----------------
     t
    (1 row)
    
    Time: 16.103 ms
    C1MQV0FZDTY3:bin bajishaik$ psql -p 5556 -U bajishaik -c "select pg_reload_conf()"
    Timing is on.
    Pager usage is off.
    2018-03-21 16:08:29.929 IST [24387] LOG:  received SIGHUP, reloading configuration files
     pg_reload_conf
    ----------------
     t
    (1 row)
    
    Time: 53.542 ms
    C1MQV0FZDTY3:bin bajishaik$
  4. Buat beberapa tabel pengujian untuk mereplikasi dan menyisipkan beberapa data pada instance Publikasi.

    postgres=# create database source_rep;
    CREATE DATABASE
    Time: 662.342 ms
    postgres=# \c source_rep
    You are now connected to database "source_rep" as user "bajishaik".
    source_rep=# create table test_rep(id int primary key, name varchar);
    CREATE TABLE
    Time: 63.706 ms
    source_rep=# create table test_rep_other(id int primary key, name varchar);
    CREATE TABLE
    Time: 65.187 ms
    source_rep=# insert into test_rep values(generate_series(1,100),'data'||generate_series(1,100));
    INSERT 0 100
    Time: 2.679 ms
    source_rep=# insert into test_rep_other  values(generate_series(1,100),'data'||generate_series(1,100));
    INSERT 0 100
    Time: 1.848 ms
    source_rep=# select count(1) from test_rep;
     count
    -------
       100
    (1 row)
    
    Time: 0.513 ms
    source_rep=# select count(1) from test_rep_other ;
     count
    -------
       100
    (1 row)
    
    Time: 0.488 ms
    source_rep=#
  5. Buat struktur tabel pada instance Langganan karena Replikasi Logis tidak mereplikasi struktur.

    postgres=# create database target_rep;
    CREATE DATABASE
    Time: 514.308 ms
    postgres=# \c target_rep
    You are now connected to database "target_rep" as user "bajishaik".
    target_rep=# create table test_rep_other(id int primary key, name varchar);
    CREATE TABLE
    Time: 9.684 ms
    target_rep=# create table test_rep(id int primary key, name varchar);
    CREATE TABLE
    Time: 5.374 ms
    target_rep=#
  6. Buat publikasi pada instance Publikasi (port 5555).

    source_rep=# CREATE PUBLICATION mypub FOR TABLE test_rep, test_rep_other;
    CREATE PUBLICATION
    Time: 3.840 ms
    source_rep=#
  7. Buat langganan pada instance Langganan (port 5556) ke publikasi yang dibuat pada langkah 6.

    target_rep=# CREATE SUBSCRIPTION mysub CONNECTION 'dbname=source_rep host=localhost user=bajishaik port=5555' PUBLICATION mypub;
    NOTICE:  created replication slot "mysub" on publisher
    CREATE SUBSCRIPTION
    Time: 81.729 ms

    Dari log:

    2018-03-21 16:16:42.200 IST [24617] LOG:  logical decoding found consistent point at 0/1616D80
    2018-03-21 16:16:42.200 IST [24617] DETAIL:  There are no running transactions.
    target_rep=# 2018-03-21 16:16:42.207 IST [24618] LOG:  logical replication apply worker for subscription "mysub" has started
    2018-03-21 16:16:42.217 IST [24619] LOG:  starting logical decoding for slot "mysub"
    2018-03-21 16:16:42.217 IST [24619] DETAIL:  streaming transactions committing after 0/1616DB8, reading WAL from 0/1616D80
    2018-03-21 16:16:42.217 IST [24619] LOG:  logical decoding found consistent point at 0/1616D80
    2018-03-21 16:16:42.217 IST [24619] DETAIL:  There are no running transactions.
    2018-03-21 16:16:42.219 IST [24620] LOG:  logical replication table synchronization worker for subscription "mysub", table "test_rep" has started
    2018-03-21 16:16:42.231 IST [24622] LOG:  logical replication table synchronization worker for subscription "mysub", table "test_rep_other" has started
    2018-03-21 16:16:42.260 IST [24621] LOG:  logical decoding found consistent point at 0/1616DB8
    2018-03-21 16:16:42.260 IST [24621] DETAIL:  There are no running transactions.
    2018-03-21 16:16:42.267 IST [24623] LOG:  logical decoding found consistent point at 0/1616DF0
    2018-03-21 16:16:42.267 IST [24623] DETAIL:  There are no running transactions.
    2018-03-21 16:16:42.304 IST [24621] LOG:  starting logical decoding for slot "mysub_16403_sync_16393"
    2018-03-21 16:16:42.304 IST [24621] DETAIL:  streaming transactions committing after 0/1616DF0, reading WAL from 0/1616DB8
    2018-03-21 16:16:42.304 IST [24621] LOG:  logical decoding found consistent point at 0/1616DB8
    2018-03-21 16:16:42.304 IST [24621] DETAIL:  There are no running transactions.
    2018-03-21 16:16:42.306 IST [24620] LOG:  logical replication table synchronization worker for subscription "mysub", table "test_rep" has finished
    2018-03-21 16:16:42.308 IST [24622] LOG:  logical replication table synchronization worker for subscription "mysub", table "test_rep_other" has finished

    Seperti yang Anda lihat di pesan PEMBERITAHUAN, itu membuat slot replikasi yang memastikan pembersihan WAL tidak boleh dilakukan sampai snapshot awal atau perubahan delta ditransfer ke database target. Kemudian pengirim WAL mulai mendekode perubahan, dan penerapan replikasi logis berfungsi saat pub dan sub dimulai. Kemudian sinkronisasi tabel dimulai.

  8. Verifikasi data pada instance Berlangganan.

    target_rep=# select count(1) from test_rep;
     count
    -------
       100
    (1 row)
    
    Time: 0.927 ms
    target_rep=# select count(1) from test_rep_other ;
     count
    -------
       100
    (1 row)
    
    Time: 0.767 ms
    target_rep=#

    Seperti yang Anda lihat, data telah direplikasi melalui snapshot awal.

  9. Verifikasi perubahan delta.

    C1MQV0FZDTY3:bin bajishaik$ psql -d postgres -p 5555 -d source_rep -c "insert into test_rep values(generate_series(101,200), 'data'||generate_series(101,200))"
    INSERT 0 100
    Time: 3.869 ms
    C1MQV0FZDTY3:bin bajishaik$ psql -d postgres -p 5555 -d source_rep -c "insert into test_rep_other values(generate_series(101,200), 'data'||generate_series(101,200))"
    INSERT 0 100
    Time: 3.211 ms
    C1MQV0FZDTY3:bin bajishaik$ psql -d postgres -p 5556 -d target_rep -c "select count(1) from test_rep"
     count
    -------
       200
    (1 row)
    
    Time: 1.742 ms
    C1MQV0FZDTY3:bin bajishaik$ psql -d postgres -p 5556 -d target_rep -c "select count(1) from test_rep_other"
     count
    -------
       200
    (1 row)
    
    Time: 1.480 ms
    C1MQV0FZDTY3:bin bajishaik$

Ini adalah langkah-langkah untuk setup dasar Replikasi Logis.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Grup SQL berdasarkan Rentang Tanggal

  2. SQL LIKE kondisi untuk memeriksa integer?

  3. Cara Meningkatkan PostgreSQL 11 ke PostgreSQL 12 dengan Zero Downtime

  4. Dapatkan nilai dari baris pertama dan terakhir per grup

  5. Alat ETL Terbaik untuk Bermigrasi ke PostgreSQL