Để thực hiện yêu cầu này, chúng ta nên đưa ra một số loại bộ lọc như TRIGGERs / RULEs trên Slave Node để nó tránh chuyển tiếp các câu lệnh DELETE và UPDATE. Vì chúng tôi đang xử lý Slony-I nên nó không có cơ chế tích hợp sẵn như vậy để lọc DML trong khi phát lại chúng trên nút phụ mặc dù nó đã tập hợp tất cả các sự kiện từ nút Chính. (AFAIK Mysql, Oracle, SQL Server hỗ trợ bộ lọc ).
Để có được điều này, cách Slony-I truyền thống duy trì tính duy nhất của các hàng trên tất cả các nút với khái niệm cốt lõi là bảng phải có khóa chính. Trong thiết kế kiến trúc như vậy, thật khó để loại trừ các câu lệnh DELETE / UPDATE, hãy lấy ví dụ về cột khóa chính “orderid” của bảng “order” có câu lệnh INSERT đầu tiên với giá trị 100 và nó được sao chép dưới dạng đầu tiên trên Slave Node đã lọc. Sau đó, một câu lệnh DELETE được thực thi cho “orderid =100” và hàng đã bị xóa, bây giờ nếu bất kỳ câu lệnh INSERT hoặc UPDATE nào cố gắng sử dụng “orderid =100” thì nút Slave sẽ vi phạm khóa trùng lặp và nó đơn giản phá vỡ bản sao.
ERROR: duplicate key value violates unique constraint "reptest_pkey"
DETAIL: Key (id)=(2) already exists.
CONTEXT: SQL statement "INSERT INTO "public"."reptest" ("id", "name") VALUES ($1, $2);"
.....
or
....
CONTEXT: SQL statement "UPDATE ONLY "public"."reptest" SET "id" = $1 WHERE "id" = $2;"
2014-11-17 23:18:53 PST ERROR remoteWorkerThread_1: SYNC aborted
Vì vậy, việc thực hiện các quy tắc chưa phải là một vấn đề mà người ta phải cực kỳ thận trọng khi áp dụng nó. Tuy nhiên, trong thực tế, việc áp dụng các bộ lọc này trên nút nô lệ Slony-I là rất mong manh, đặc biệt là ứng dụng / nhà phát triển phải luôn ghi nhớ điều này bất kỳ mục nhập trùng lặp nào của hàng bằng CHÈN HOẶC CẬP NHẬT có thể phá vỡ bản sao.
Vì các quy tắc DML không thể thực hiện một mình với Slony-I, chúng ta có thể sử dụng PostgreSQL CREATE RULE… ON DELETE / ON UPDATE DO INSTEAD NOTHING và áp dụng RULE đó trên bảng bằng ALTER TABLE… BẬT REPLICA RULE để hủy bỏ câu lệnh DELETE / UPDATE. Việc sử dụng tùy chọn này cần có nhiều kỷ luật, vì vậy bạn có thể đảm bảo ứng dụng của mình và nhân viên thực sự tuân theo các quy tắc này.
Để tiếp tục các bước, bạn nên thiết lập slony, nếu cần thiết lập, bạn có thể tham khảo bài đăng trước đây của tôi tại đây.
Các bước trên Slave Node (Master DB:postgres, Slave DB:demo, Port:5432):
1. Dừng slon daemon
2. Tạo ON DELETE và ON UPDATE DO INSTEAD NOTHING quy tắc
demo=# CREATE RULE void_delete AS ON DELETE TO reptest DO INSTEAD NOTHING;
CREATE RULE
demo=# CREATE RULE void_update AS ON UPDATE TO reptest DO INSTEAD NOTHING;
CREATE RULE
3. Áp dụng RULE trên bảng
demo=# ALTER TABLE reptest ENABLE REPLICA RULE void_delete;
ALTER TABLE
demo=# ALTER TABLE reptest ENABLE REPLICA RULE void_update ;
ALTER TABLE
4. Khởi động daemon Slon
Bây giờ, bạn có thể nhận thấy bên dưới rằng UPDATE / DELETE không ảnh hưởng đến Slave Node:
postgres=# delete from reptest where id =2;
DELETE 1
postgres=# update reptest set id=2 where id=1;
UPDATE 1
--On Master
postgres=# select * from reptest ;
id | name
----+------------
2 | A
(1 row)
--On Slave
demo=# select * from reptest ;
id | name
----+------------
1 | A
2 | C
(2 rows)
Nếu câu lệnh INSERT được thực thi với giá trị 1 thì nó sẽ phá vỡ bản sao. Hãy lưu ý… !!
Hãy nhớ rằng có những cách khác để điền đầy đủ yêu cầu này như liên kết dblinks, các trình kích hoạt như TRƯỚC KHI XÓA… trả về giá trị NULL từ hàm, nhưng tôi tin rằng cách hiệu quả nhất sẽ là sử dụng RULE / ENABLE REPLICA RULE khi bạn đang làm việc với bản sao Slony.
Đến bây giờ bạn có thể đã đọc nhiều blog về tính năng mới của Logical Decoding Replication trong PostgreSQL 9.4, hy vọng trong tương lai nó có thể bao gồm khái niệm về bộ lọc DML trên Slave.
Cảm ơn bạn đã ghé thăm.