Dalam entri blog ini kita akan berbicara tentang replikasi logis di PostgreSQL:kasus penggunaannya, informasi umum tentang status teknologi ini, dan kasus penggunaan khusus khususnya tentang cara mengatur node pelanggan (replika) dari server utama secara berurutan berfungsi sebagai server database untuk lingkungan pengujian, dan tantangannya terpenuhi.
Pengantar
Replikasi logis, yang secara resmi diperkenalkan di PostgreSQL 10, adalah teknologi replikasi terbaru yang ditawarkan oleh komunitas PostgreSQL. Replikasi logis adalah kelanjutan dari warisan replikasi fisik yang dengannya ia berbagi banyak ide dan kode. Replikasi logis bekerja seperti replikasi fisik menggunakan WAL untuk merekam perubahan logis independen dari versi atau arsitektur tertentu. Agar dapat memberikan replikasi logis ke penawaran inti, komunitas PostgreSQL telah berjalan jauh.
Jenis replikasi dan Sejarah replikasi PostgreSQL
Jenis-jenis replikasi dalam database dapat diklasifikasikan sebagai berikut:
- Replikasi fisik (biner AKA)
- Tingkat sistem operasi (replikasi vSphere)
- Tingkat sistem file (DRBD)
- Tingkat basis data (berbasis WAL)
- Replikasi logis (Tingkat basis data)
- Berbasis pemicu (DBMirror, Slony)
- Perangkat Tengah (pgpool)
- Berbasis WAL (pglogis, Replikasi Logis)
Peta jalan yang membawa ke replikasi logis berbasis WAL hari ini adalah:
- 2001:DBMirror (berbasis pemicu)
- 2004:Slony1 (berbasis pemicu), pgpool (middleware)
- 2005:PITR (berbasis WAL) diperkenalkan di PostgreSQL 8.0
- 2006:Siaga hangat di PostgreSQL 8.2
- 2010:Replikasi streaming fisik, hot standby di PostgreSQL 9.0
- 2011:Replikasi streaming sinkron di PostgreSQL 9.1
- 2012:Replikasi streaming bertingkat di PostgreSQL 9.2
- 2013:Pekerja latar belakang di PostgreSQL 9.3
- 2014:API decoding logis, slot replikasi. (Dasar untuk Replikasi Logis) di PostgreSQL 9.4
- 2015:2ndQuadrant memperkenalkan pglogical, ancestor atau Replikasi Logis
- 2017:Replikasi Logis di inti PostgreSQL 10!
Seperti yang kita lihat banyak teknologi yang berkolaborasi untuk membuat Replikasi Logis menjadi kenyataan:pengarsipan WAL, siaga hangat/panas, replikasi WAL fisik, pekerja latar belakang, decoding logis. Dengan asumsi pembaca sudah familiar dengan sebagian besar pengertian replikasi fisik, kita akan berbicara tentang komponen dasar dari Replikasi Logis.
Konsep dasar Replikasi Logis PostgreSQL
Beberapa terminologi:
- Publikasi: Satu set perubahan dari satu set tabel yang ditentukan dalam database tertentu pada server utama replikasi fisik. Sebuah Publikasi dapat menangani semua atau sebagian dari:INSERT, DELETE, UPDATE, TRUNCATE.
- Node penerbit: Server tempat publikasi berada.
- Identitas replika: Cara untuk mengidentifikasi baris di sisi pelanggan untuk UPDATE dan DELETE.
- Langganan: Koneksi ke node penerbit dan satu atau lebih publikasi di dalamnya. Langganan menggunakan slot replikasi khusus pada penerbit untuk replikasi. Slot replikasi tambahan dapat digunakan untuk langkah sinkronisasi awal.
- Node pelanggan: Server tempat langganan berada.
Replikasi logis mengikuti model terbitkan/berlangganan. Satu atau lebih pelanggan dapat berlangganan satu atau lebih publikasi di node penerbit. Pelanggan dapat memublikasikan ulang untuk memungkinkan replikasi berjenjang. Replikasi logis dari sebuah tabel terdiri dari dua tahap:
- Mengambil cuplikan tabel di penerbit dan menyalinnya ke pelanggan
- Menerapkan semua perubahan (sejak snapshot) dalam urutan yang sama
Replikasi logis bersifat transaksional dan menjamin bahwa urutan perubahan yang diterapkan pada pelanggan tetap sama seperti pada penerbit. Replikasi logis memberikan lebih banyak kebebasan daripada replikasi fisik (biner), oleh karena itu dapat digunakan dengan lebih banyak cara:
- Replikasi database atau tabel tunggal (tidak perlu mereplikasi seluruh cluster)
- Menyetel pemicu ke pelanggan untuk tugas tertentu (seperti menganonimkan, yang merupakan topik yang cukup hangat setelah GDPR berlaku)
- Memiliki node pelanggan mengumpulkan data dari banyak node penerbit, sehingga memungkinkan pemrosesan analitik terpusat
- Replikasi antara versi/arsitektur/platform yang berbeda (tanpa peningkatan waktu henti)
- Menggunakan node pelanggan sebagai server database untuk lingkungan pengujian/pengembangan. Mengapa kami menginginkan ini, karena pengujian terhadap data nyata adalah jenis pengujian yang paling realistis.
Peringatan dan Pembatasan
Ada hal-hal tertentu yang harus kita ingat saat menggunakan replikasi logis, beberapa di antaranya mungkin memengaruhi beberapa keputusan desain, tetapi yang lain dapat menyebabkan insiden kritis.
Pembatasan
- Hanya operasi DML yang didukung. Tidak ada DDL. Skema harus didefinisikan terlebih dahulu
- Urutan tidak direplikasi
- Objek Besar tidak direplikasi
- Hanya tabel dasar biasa yang didukung (tampilan terwujud, tabel root partisi, tabel asing tidak didukung)
Peringatan
Masalah mendasar yang cepat atau lambat harus kita hadapi saat menggunakan Replikasi Logis adalah konflik pada pelanggan. Pelanggan adalah server baca/tulis normal yang dapat bertindak sebagai utama dalam pengaturan replikasi fisik, atau bahkan sebagai penerbit dalam pengaturan replikasi logis bertingkat. Selama penulisan pada tabel langganan dilakukan, mungkin akan ada konflik . Konflik muncul ketika data yang direplikasi melanggar batasan pada tabel tempat mereka diterapkan. Biasanya, operasi yang menyebabkan ini adalah INSERT, DELETES atau UPDATES yang tidak berpengaruh karena baris yang hilang tidak akan menimbulkan konflik. Ketika konflik muncul, replikasi berhenti. Pekerja latar belakang logis akan dimulai ulang dalam interval yang ditentukan (wal_retrieve_retry_interval), namun, replikasi akan gagal lagi hingga penyebab konflik teratasi. Ini adalah kondisi kritis yang harus segera ditangani. Gagal melakukannya akan membuat slot replikasi macet pada posisinya saat ini, node penerbit akan mulai mengumpulkan WAL dan pasti node penerbit akan kehabisan ruang disk . Konflik adalah alasan paling umum mengapa replikasi mungkin berhenti tetapi kondisi salah lainnya akan memiliki efek yang sama:mis. kami menambahkan kolom NOT NULL baru pada tabel langganan tetapi lupa menentukan nilai default, atau menambahkan kolom pada tabel yang dipublikasikan tetapi lupa mendefinisikannya pada tabel langganan, atau membuat kesalahan pada jenisnya dan kedua jenis tidak kompatibel. Semua kesalahan itu akan menghentikan replikasi. Ada dua cara untuk menyelesaikan konflik:
- Memecahkan masalah yang sebenarnya
- Lewati transaksi yang gagal dengan memanggil pg_replication_origin_advance
Solusi b. seperti yang juga ditunjukkan di sini bisa berbahaya dan rumit karena pada dasarnya adalah proses coba-coba, dan jika seseorang memilih LSN saat ini di penerbit, dia mungkin dengan mudah berakhir dengan sistem replikasi yang rusak karena mungkin ada operasi antara LSN yang bermasalah dan LSN saat ini yang ingin kami pertahankan. Jadi cara terbaik adalah dengan benar-benar menyelesaikan masalah di sisi pelanggan. Misalnya. jika terjadi pelanggaran KUNCI UNIK maka kami mungkin memperbarui data pada pelanggan atau hanya menghapus baris. Dalam lingkungan produksi, semua ini harus otomatis atau setidaknya semi otomatis.
Menyiapkan node penerbit dan pelanggan
Untuk gambaran umum tentang replikasi logis dalam praktik, silakan baca blog ini.
Parameter yang relevan untuk replikasi logis adalah:
- Sisi penerbit
- wal_level>=“logis”
- max_replication_slots>=#langganan + sinkronisasi tabel awal
- max_wal_senders>=max_replication_slots + other_physical_standbys
- Sisi pelanggan
- max_replication_slots>=#langganan
- max_logical_replication_workers>=#langganan + sinkronisasi tabel awal
- max_worker_processes>=max_logical_replication_workers + 1 + max_parallel_workers
Kami akan fokus pada pertimbangan khusus yang muncul dari tujuan khusus kami yang memerlukan replikasi logis untuk dicapai:membuat cluster database pengujian untuk digunakan oleh departemen pengujian . Publikasi dapat didefinisikan baik untuk semua tabel atau tabel demi tabel. Saya menyarankan pendekatan tabel demi tabel karena memberi kita fleksibilitas maksimum. Langkah-langkah umum dapat diringkas sebagai berikut:
- Lakukan initdb baru pada node pelanggan
- Buang skema cluster penerbit dan salin ke node pelanggan
- Buat skema pada pelanggan
- Tentukan tabel mana yang Anda butuhkan dan mana yang tidak Anda butuhkan.
Mengenai butir di atas, ada dua alasan mengapa Anda mungkin tidak memerlukan tabel untuk direplikasi atau disiapkan untuk replikasi:
- Ini adalah tabel tiruan yang tidak penting (dan mungkin Anda juga harus menghapusnya dari produksi)
- merupakan tabel lokal untuk lingkungan produksi, yang berarti sangat masuk akal bahwa tabel yang sama di lingkungan pengujian (pelanggan) memiliki datanya sendiri
Semua tabel yang mengambil bagian dalam replikasi logis harus memiliki IDENTITAS REPLIKA. Ini adalah KUNCI UTAMA secara default, dan jika tidak tersedia, kunci UNIK dapat ditentukan. Langkah selanjutnya untuk menemukan status tabel terkait REPLICA IDENTITY.
- Temukan tabel tanpa kandidat yang jelas untuk REPLICA IDENTITY
select table_schema||'.'||table_name from information_schema.tables where table_type='BASE TABLE' AND table_schema||'.'||table_name NOT IN (select table_schema||'.'||table_name from information_schema.table_constraints WHERE constraint_type in ('PRIMARY KEY','UNIQUE')) AND table_schema NOT IN ('information_schema','pg_catalog') ;
- Temukan tabel tanpa PRIMARY KEY tetapi dengan INDEKS UNIK
select table_schema||'.'||table_name from information_schema.table_constraints WHERE constraint_type = 'UNIQUE' EXCEPT select table_schema||'.'||table_name from information_schema.table_constraints WHERE constraint_type = 'PRIMARY KEY';
- Periksa daftar di atas dan putuskan apa yang harus dilakukan dengan setiap tabel
- Buat publikasi dengan tabel yang memiliki PK
select 'CREATE PUBLICATION data_for_testdb_pub FOR TABLE ONLY ' || string_agg(qry.tblname,', ONLY ') FROM (select table_schema||'.'||quote_ident(table_name) as tblname from information_schema.tables where table_type='BASE TABLE' AND table_schema||'.'||table_name IN (select table_schema||'.'||table_name from information_schema.table_constraints WHERE constraint_type in ('PRIMARY KEY')) AND table_schema NOT IN( 'information_schema','pg_catalog') ORDER BY 1) as qry; \gexec
- Kemudian buat langganan di node pelanggan
Di atas akan menyalin data juga.create subscription data_for_testdb_pub CONNECTION 'dbname=yourdb host=yourdbhost user=repmgr' PUBLICATION data_for_testdb_pub ;
- Tambahkan tabel yang Anda inginkan yang memiliki indeks UNIK
Jalankan baik di node penerbit dan pelanggan, mis.:
Di penerbit:ALTER TABLE someschema.yourtable REPLICA IDENTITY USING INDEX yourindex_ukey;
Pada pelanggan:ALTER PUBLICATION data_for_testdb_pub ADD TABLE ONLY someschema.yourtable;
ALTER SUBSCRIPTION data_for_testdb_pub REFRESH PUBLICATION WITH ( COPY_DATA );
- Pada titik ini (sinkronisasi) Anda harus selalu memperhatikan log PostgreSQL di node pelanggan. Anda tidak ingin ada kesalahan atau apa pun (batas waktu) yang melarang kelanjutan replikasi logis. SELESAIKAN KESALAHAN SEGERA , atau penerbit akan terus mengumpulkan file WAL di pg_wal dan akhirnya kehabisan ruang. Jadi, Anda harus berurusan dengan
- Semua ERROR atau pesan apa pun terkait pekerja logis yang mengakibatkan keluar
- Jaga juga
- wal_receiver_timeout
- wal_sender_timeout
Setelah menyelesaikan semua masalah, Anda seharusnya membuat node pelanggan Anda berjalan dengan baik. Jadi pertanyaan selanjutnya adalah bagaimana menggunakan ini sebagai server database pengujian. Anda harus mengatasi masalah/masalah tersebut:
- Anonimisasi
- Kunci utama dan Kunci unik yang didasarkan pada pelanggaran urutan
- Satu set umum praktik yang baik
- Pemantauan
Anonimisasi
Mengenai anonimisasi data pribadi yang diberlakukan oleh GDPR di UE, Anda harus menulis beberapa pemicu SELALU yang mengosongkan semua bidang terkait alamat, rekening bank, status perkawinan, nomor telepon, email, dll. Anda harus berkonsultasi dengan petugas keamanan di perusahaan Anda tentang apa yang harus disimpan dan apa yang harus dikosongkan. Pemicu harus didefinisikan sebagai SELALU karena pekerja logis menjalankan pernyataan sebagai REPLICA.
Kunci Utama dengan Urutan
Mengenai urutan, jelas akan ada masalah dengan kunci-kunci itu kecuali ditangani sebelum tes dimulai. Pertimbangkan kasus ini:
- Pada hari Jumat sore Anda melakukan beberapa pengujian pada basis data pelanggan dengan menyisipkan baris baru ke beberapa tabel. Ini akan memiliki ID nilai berikutnya yang dihasilkan oleh urutan.
- Kamu pulang untuk akhir pekan.
- Beberapa pengguna produksi memasukkan baris dalam tabel yang sama pada database penerbit.
- Baris akan direplikasi berdasarkan IDENTITAS REPLIKA ke node pelanggan tetapi akan gagal karena pelanggaran PK ERROR. Pekerja latar belakang logis akan keluar dan mencoba lagi. Tapi akan terus gagal selama masalah berlanjut.
- Replikasi akan macet. Slot replikasi akan mulai mengumpulkan WAL.
- Penerbit kehabisan ruang disk.
- Pada akhir pekan Anda mendapatkan email bahwa node Utama Anda PANIK!
Jadi, untuk memecahkan masalah urutan Anda dapat mengambil pendekatan berikut:
select 'SELECT setval(''' || seqrelid::regclass||''','||CASE WHEN seqincrement <0 THEN -214748364 ELSE 214748364 END||');' from pg_sequence where seqtypid=20;
\gexec
Apa yang dilakukan di atas adalah menyetel urutan ke nilai yang cukup besar sehingga tidak pernah tumpang tindih untuk jendela yang cukup besar di masa mendatang, memungkinkan Anda memiliki server uji bebas masalah.
Serangkaian Praktik Baik
Anda harus benar-benar memberi tahu pemrogram Anda untuk membuat pengujian mereka tidak persisten. Jadi setiap pengujian setelah selesai harus meninggalkan database dalam keadaan yang sama seperti sebelum pengujian. Dengan penyisipan ID berbasis urutan, ini bukan masalah, kami telah melihat solusi sebelumnya. Tetapi dengan kunci UNIK non-urutan (misalnya majemuk) yang mungkin menjadi masalah. Jadi sebaiknya hapus data pengujian tersebut sebelum beberapa baris produksi dengan nilai yang sama masuk ke tabel langganan.
Di sini kita juga harus menambahkan berurusan dengan perubahan skema. Semua perubahan skema harus dilakukan juga pada pelanggan agar tidak memutus lalu lintas DML yang direplikasi.
Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh WhitepaperPemantauan
Anda benar-benar harus berinvestasi dalam solusi pemantauan yang baik. Anda harus memantau ...
Di pelanggan:
- SEMUA pesan di log pelanggan yang relevan dengan keluarnya pekerja logis. Memasang alat sebagai tail_n_mail benar-benar dapat membantu dalam hal ini. Konfigurasi yang diketahui berfungsi:
Begitu kami mendapat peringatan dari tail_n_mail, kami harus segera menyelesaikan masalah.INCLUDE: ERROR: .*publisher.* INCLUDE: ERROR: .*exited with exit.* INCLUDE: LOG: .*exited with exit.* INCLUDE: FATAL: INCLUDE: PANIC:
- pg_stat_subscription. Pid tidak boleh nol. Lagnya juga harus kecil.
Di penerbit:
- pg_stat_replication. Ini harus memiliki baris sebanyak yang seharusnya:Satu untuk setiap standby replikasi streaming yang terhubung (termasuk node pelanggan dan standby fisik lainnya).
- pg_replication_slots untuk slot pelanggan. Ini harus aktif.
Umumnya, dibutuhkan beberapa waktu sampai Anda memiliki server database pengujian ideal yang berjalan tanpa masalah, tetapi setelah Anda menyelesaikan semuanya, programmer Anda akan berterima kasih karena Anda telah memilikinya!