replication

PostgreSQL 10 - Logical replication

PostgreSQL 10 mới được release tháng 10 năm 2017 vừa qua, nổi bật với 2 tính năng mới được kỳ vọng là Logical Replication và Declarative Partitioning (ngoài ra cũng có nhiều cải thiện và thay đổi), bài viết này mình muốn giới thiệu qua về chức năng Logical Replication và cách sử dụng trong thực tế.

PostgreSQL Replication

Chức năng Replication của PostgreSQL bắt đầu được giới thiệu ở phiên bản PostgreSQL 9.0 dựa trên kỹ thuật chuyển WAL(Transaction log) qua standby. Chức năng này dần được cải thiện qua các phiên bản và gần đây nhất là chức năng Logical Replication trên phiên bản 10. Các phiên bản của chức năng Replication của PostgreSQL bạn có thể tham khảo ở bài viết chức năng replication của PostgreSQL.


Logical Replication

Logical Replication được thêm vào nhờ một số nhà phát triển PostgreSQL từ công ty 2ndQuadrant dựa trên logic của module pglogical (cũng được phát triển bởi công ty này).
Trước phiên bản logical replication, PostgreSQL cũng đã thực hiện replication qua hình thức chuyển thông tin thay đổi thông qua gửi WAL tới standby. Nhưng ở những phiên bản trước, WAL chuyển qua ở mức độ chi tiết thấp, standby thực hiện phản ảnh lên DB gần như ở mức độ vật lý (đồng bộ các file dữ liệu).
Logical Replication sử dụng WAL ở mức độ chi tiết hơn, có thể decode được thành các câu lệnh SQL (phải sử dụng module ngoài để decode). Phía master (wal sender process) decode và thực hiện ghi lại WAL trước khi gửi tới standby node, phía standby sau đó sử dụng WAL nhận được và phản ảnh vào dữ liệu phía mình ở trạng thái logic thông qua logical worker process.
Logical Replication sử dụng 2 khái niệm mới, PUBLICATION và SUBSCRIPTION. PUBLICATION hiểu đơn giản là nơi phát dữ liệu cập nhật, và SUBSCRIPTION là nơi nhận cập nhật và phản ảnh vào database phía standby.

Thiết lập paramters

Để sử dụng chức năng này. Ta cần chỉnh wal_level (mức độ chi tiết của WAL) lên mức có thể decode được "replica", mỗi một cặp Publication & Subscription cần 1 wal sender processes và một slot chứa wal cho standby ta phải tăng parameters max_wal_senders, max_replication_slots lên giá trị cần thiết.

Parameter Giá trị thiết lập
wal_level replica
max_wal_senders số lượng SUBSCRIPTION + α (cho các kết nối replication khác)
max_replication_slots số lượng SUBSCRIPTION + α (cho các kết nối replication khác)

Ngoài ra, để SUBSCRIPTION có thể connect tới PUBLICATION, ta phải thiết lập authentication cho kết nối replication. Chú ý, không giống với streaming replication, những thiết lập bên trên chỉ cần cho phía PUBLICATION.

Sử dụng Logical Replication

Để sử dụng chức năng Logical Replication, ta cần 2 database cluster riêng biệt cho PUBLICATION và SUBSCRIPTION. Cả 2 database cluster này đều phải hỗ trợ ghi dữ liệu (không giống streaming replication, dữ liệu chỉ có thể ghi ở phía primary).

  1. Thiết lập parameters
    Phía PUBLICATION Server thiết lập các tham số yêu cầu như ở trên.
DangnoMacBook-Pro:postgres bocap$ grep -e max_replication_slots -e max_wal_senders -e wal_level $PGDATA/postgresql.conf
wal_level = logical     # minimal, replica, or logical
#max_wal_senders = 10   # max number of walsender processes
#max_replication_slots = 10 # max number of replication slots
DangnoMacBook-Pro:postgres bocap$ grep replication $PGDATA/pg_hba.conf | grep -v "#"
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust
DangnoMacBook-Pro:postgres bocap$ 
  1. Tạo PUBLICATION
    Ví dụ bên dưới tạo PUBLICATION đối với một bảng dữ liệu(test_logical_rep). Ta cũng có thể tạo PUBLICATION ở các mức độ nhiều bảng hoặc tất cả các bảng.
10000 postgres@postgres=#  create table test_logical_rep(c1 integer primary key, c2 text);
CREATE TABLE
10000 postgres@postgres=# insert into test_logical_rep select generate_series(1,5),random()::text;
INSERT 0 5
10000 postgres@postgres=# table test_logical_rep
postgres-# ;
 c1 |         c2         
----+--------------------
  1 | 0.709808008279651
  2 | 0.426817617379129
  3 | 0.973640063311905
  4 | 0.729786423034966
  5 | 0.0786650250665843
(5 rows)

10000 postgres@postgres=# \h create publication
Command:     CREATE PUBLICATION
Description: define a new publication
Syntax:
CREATE PUBLICATION name
    [ FOR TABLE [ ONLY ] table_name [ * ] [, ...]
      | FOR ALL TABLES ]
    [ WITH ( publication_parameter [= value] [, ... ] ) ]

10000 postgres@postgres=# create publication test_first_pub for table test_logical_rep ;
CREATE PUBLICATION
10000 postgres@postgres=# 
  1. Tạo SUBSCRIPTION
    Ví dụ bên dưới tạo SUBSCRIPTION đối với PUBLICATION đã tạo ở 2. để đồng bộ bảng dữ liệu test_logical_rep từ database phía PUBLICATION sang phía SUBSCRIPTION.
10001 bocap@postgres=# create table test_logical_rep(c1 integer primary key, c2 text);
CREATE TABLE
10001 bocap@postgres=# \h create subscription
Command:     CREATE SUBSCRIPTION
Description: define a new subscription
Syntax:
CREATE SUBSCRIPTION subscription_name
    CONNECTION 'conninfo'
    PUBLICATION publication_name [, ...]
    [ WITH ( subscription_parameter [= value] [, ... ] ) ]

10001 bocap@postgres=# create subscription test_first_sub connection 'port=10000 dbname=postgres user=bocap' publication test_first_pub;
NOTICE:  created replication slot "test_first_sub" on publisher
CREATE SUBSCRIPTION
10001 bocap@postgres=# select * from test_logical_rep ;
 c1 |         c2         
----+--------------------
  1 | 0.709808008279651
  2 | 0.426817617379129
  3 | 0.973640063311905
  4 | 0.729786423034966
  5 | 0.0786650250665843
(5 rows)

10001 bocap@postgres=#  

Mặc định Logical Replication thực hiện đồng bộ dữ liệu ở chế độ không đồng bộ (Async). Nếu muốn thực hiện đồng bộ dữ liệu ở chế độ đồng bộ (Sync), bạn cần:

  • Chỉ định tên của Subscription qua tham số application_name trong thông tin connection khi CREATE SUBSCRIPTION.
  • Chỉ đinh tên của Subscription này trong tham số synchronous_standby_names (postgresql.conf) phía Publication.
  1. Thao tác cơ bản
-- Insert dữ liệu phía PUBLICATION  
10000 postgres@postgres=# insert into test_logical_rep select 6,random()::text;
INSERT 0 1
10000 postgres@postgres=# table  test_logical_rep;
 c1 |         c2         
----+--------------------
  1 | 0.709808008279651
  2 | 0.426817617379129
  3 | 0.973640063311905
  4 | 0.729786423034966
  5 | 0.0786650250665843
  6 | 0.50799278402701
(6 rows)

10000 postgres@postgres=#  

-- Xác nhận dữ liệu cập nhật phía SUBSCRIPTION   
10001 bocap@postgres=# table  test_logical_rep;
 c1 |         c2         
----+--------------------
  1 | 0.709808008279651
  2 | 0.426817617379129
  3 | 0.973640063311905
  4 | 0.729786423034966
  5 | 0.0786650250665843
  6 | 0.50799278402701
(6 rows)

-- Cập nhật dữ liệu phía PUBLICATION  
10000 postgres@postgres=# update test_logical_rep set c2 = random()::text where c1 = 6;
UPDATE 1
10000 postgres@postgres=# delete from test_logical_rep where c1 = 6;
DELETE 1
10000 postgres@postgres=# table  test_logical_rep;
 c1 |         c2         
----+--------------------
  1 | 0.709808008279651
  2 | 0.426817617379129
  3 | 0.973640063311905
  4 | 0.729786423034966
  5 | 0.0786650250665843
(5 rows)

-- Xác nhận thông tin cập nhật phía SUBSCRIPTION  
10001 bocap@postgres=# table  test_logical_rep;
 c1 |         c2         
----+--------------------
  1 | 0.709808008279651
  2 | 0.426817617379129
  3 | 0.973640063311905
  4 | 0.729786423034966
  5 | 0.0786650250665843
(5 rows)
  1. Chú ý
  • Câu lệnh TRUNCATE chưa support
-- Truncate phía PUBLICATION   
10000 postgres@postgres=# truncate test_logical_rep ;
TRUNCATE TABLE
10000 postgres@postgres=# table test_logical_rep;
 c1 | c2 
----+----
(0 rows)

-- Xác nhận cập nhật phía SUBSCRIPTION  
10001 bocap@postgres=# table  test_logical_rep;
 c1 |        c2         
----+-------------------
  1 | 0.709808008279651
  2 | 0.426817617379129
  3 | 0.973640063311905
  4 | 0.729786423034966
  5 | 0.918787303380668
(5 rows)
  • Conflict có thể xảy ra
    Khác với streaming replication, phía SUBSCRIPTION cũng có thể thực hiện các câu lệnh update. Thêm nữa là thao tác giữa PUBLICATION và SUBSCRIPTION là độc lập, không support cơ chế MVCC. Vậy nên dữ liệu có thể xảy ra conflict nếu thao tác xử lý trên SUBSCRIPTION không nhất quán với phía PUBLICATION.

    Giới thiệu về chức năng Replication(đồng bộ dữ liệu) của PostgreSQL

    Replication

    Bạn cần tạo một standby server để backup dữ liệu, load balance trên nhiều node để giảm tải tăng performance?, ... Chức năng replication sẽ đáp ứng nhu cầu đó của bạn.
    Replication là một trong chức năng không thể thiếu của một số RDBMS nói chung và PostgreSQL(Streaming Replication) nói riêng. Ở PostgreSQL bạn có thể liên kiết với một số cluster soft như Pacemaker, hay pgpool-II để triển khai hệ thống High Availablity cho môi trường của bạn. Nguyên lý Streaming Replication của PostgreSQL dựa trên việc chuyển WAL (Transaction log) từ node Master tới Standby, sau đó Standby phản ánh lại nội dung WAL vào dữ liệu.

    Chức năng replication của PostgreSQL đầu tiên được thêm vào ở phiên bản 9.0. Sau nhiều cải tiến qua các phiên bản. Hiện tại replication nổi bật với chức năng logical replication trên phiên bản sắp tới PostgreSQL-10. Quá trình phát triển chức năng replication tới phiên bản PostgreSQL 10 được tóm tắt như bên dưới.

    Chức năng Replication qua các phiên bản PostgreSQL


    Chức năng thiếu đồng bộ - Asynchronous (PostgreSQL 9.0).

    Phải nói thêm là cũng ở phiên bản 9.0 này PostgreSQL có thêm chức năng hot_standby. Chức năng này cho phép tham chiếu dữ liệu ở phía Standby. Nếu chức năng này không hoạt động bạn không thể tham chiếu dữ liệu hay đơn giản là kết nối tới Standby server. Chức năng này gọi là thiếu đồng bộ. Vì dữ liệu cập nhật ở phía Master không được cập nhật tức thì ở Standby. Về nguyên lý thì bạn có thể tham khảo hình bên dưới.

    Replication không đồng bộ

    Chức năng tiền đồng bộ - Synchronous (PostgreSQL 9.1)

    Tiến bộ hơn chức năng Asynchronous, ở chế độ Synchronous Standby Server gửi thông điệp thành công tới Master Server sau khi xác nhận đã nhận được thông tin WAL(Transaction log). Sau khi nhận được được thông điệp từ Standby Server, Master kết thúc xử lý cập nhật dữ liệu. Như vậy sau khi cập nhật dữ liệu ở Master Sever, phải chờ một chút thời gian (thường thì khoảng vài micro giây) để Standby phản ánh (recovery) dữ liệu đó từ WAL vừa nhận được. Lưu ý rằng PostgreSQL chỉ support 1 node là Synchronous. Nếu bạn lập nhiều Standby Server node đầu tiên chỉ định trong tham số synchronous_standby_names.

    Replication tiền đồng bộ

    Chức năng Cascade Replication (PostgreSQL 9.2)

    Chức năng này cho phép bạn thiết lập một hoặc nhiều Standby Sever dựa vào một Standby Server chứ không phải Master Server như trước đây. Ở Cascade Replication mặc định chỉ sử dụng Asynchronous.

    Chức năng replication slot (PostgreSQL 9.4)

    Standby Server dựa vào WAL cung cấp từ Master Server để đồng bộ dữ liệu. Nhưng WAL này cũng có thể bị mất theo cơ chế sử dụng lại WAL của PostgreSQL. Khi WAL chưa được đồng bộ (chuyển tới) ở Standby mà bị mất ở Master Server. Standby này sẽ không thể đồng bộ với Master đó nữa, bạn phải thiết lập lại Standby Server trong trường hợp này.

    Chức năng replication slot cho phép tạo một slot tới Master Server, yêu cầu Master Server giữ lại WAL cần thiết cho Standby đó.

    Số lượng WAL thông thường phụ thuộc vào tham số max_wal_size (Hay checkpoint_segments ở phiên bản trước 9.5). Bạn cũng có thể chỉnh số lượng WAL giữ lại cho standby server qua tham số wal_keep_segments.

    Chức Logical Decoding (PostgreSQL 9.4)

    Chức năng Logical Decoding cho phép sử dụng plugin bên ngoài decoding được nội dung WAL thành các câu lệnh SQL. Chức năng này kết hợp với chức năng Replication Slot là nền tảng chính của chức năng Logical Replication trong phiên bản PostgreSQL 10. 

    Chức năng Full Synchronous

    Mình sử dụng chữ Full vì ở chế độ này, sau khi kết thúc câu lệnh cập nhật dữ liệu ở Master Server, có thể đảm bảo là dữ liệu sẽ chắc chắn đã được cập nhật ở Standby Server.

    Full Synchronous

    Logical Replication

    Chức năng này đang được phát triển ở phiên bản PostgreSQL 10. Master Server public WAL, Standby Server nhận WAL giải mã thành các câu lệnh SQL rồi chạy các câu lệnh đó trên Standby Server. Điều này cho phép PostgreSQL có thể Replication giữa các phiên bản khác nhau, hoặc có thể kỳ vọng là replication với các RDBMS khác.

    Các phiên bản PostgreSQL trước phiên bản 10, dữ liệu trên WAL không đủ chi tiết để giải mã thành các câu lệnh SQL. Và phía Server và Client phải nhất quán về phiên bản.

    Logical replication



    Cấu hình

    Thiết lập Paramters

    Thiết lập paramters cho từng level Asynchronous, Syncrhonous, Full Synchronous, Logical Replication có thể tóm tắt như bên dưới.

    Các parameters liên quan tới Streaming Replication
    Parameters Asynchronous Syncrhonous Full Synchronous Logical Replication
    wal_level lớn hơn minimal lớn hơn minimal lớn hơn minimal

    logical

    synchronous_standby_names '' 'tên Standby hoặc *' 'tên Standby hoặc *'  
    synchronous_commit    

    remote_apply

     
    max_wal_senders số lượng Standby số lượng Standby số lượng Standby số lượng Standby
    hot_standby on nếu muốn tham chiếu Standby on nếu muốn tham chiếu Standby on nếu muốn tham chiếu Standby on nếu muốn tham chiếu Standby

    Ngoài ra nếu bạn muốn archive WAL (lưu lại WAL phục vụ cho mục đích backup), bạn cần archive_mode=on và archive_command='comand để lưu WAL mỗi khi update xong 1 file WAL'

    Cấu hình

    Rất đơn giản để tạo 1 Standby Server trên PostgreSQL. Bạn dùng câu lệnh pg_basebackup để tạo một basebackup chỉnh sửa tham số nếu cần thiết và khởi động là xong.

    
    Bocap-no-MacBook-Pro:~ bocap$ env | grep PG
    PGPORT=9100
    PGUSER=postgres
    PGPASSWORD=postgres
    PGDATABASE=postgres
    PGDATA=/usr/local/pgsql/pg1000/data
    
    
    
    Bocap-no-MacBook-Pro:~ bocap$ psql
    psql (10beta1)
    Type "help" for help.
    
    postgres=# show synchronous_standby_names;
     synchronous_standby_names 
    ---------------------------
     
    (1 row)
    
    postgres=# \q
    
    

    Không quên setting authentication cho kết nối replication. Ở đây mình đặt trust(không yêu cầu password) cho kết nối nội bộ.

    
    Bocap-no-MacBook-Pro:~ bocap$ grep "replication     all" $PGDATA/pg_hba.conf
    local   replication     all                                     trust
    host    replication     all             127.0.0.1/32            trust
    host    replication     all             ::1/128                 trust
    
    

    Kiểm tra trạng thái replication tại Master Server(chưa có kết nối nào).

    
    Bocap-no-MacBook-Pro:~ bocap$ psql
    psql (10beta1)
    Type "help" for help.
    
    postgres=# \x
    Expanded display is on.
    postgres=# select * from pg_stat_replication;
    (0 rows)
    
    postgres=# \q
    
    

    Thực hiện sao chép dữ liệu cho Standby Server. Và khởi động Standby Server. 11111 là port cho Standby

    
    dang-no-MacBoook-Pro:~ bocap$ pg_basebackup -R -D ${PGDATA}.standby
    Bocap-no-MacBook-Pro:~ bocap$ echo port=11111 >> ${PGDATA}.standby/postgresql.conf
    Bocap-no-MacBook-Pro:~ bocap$ pg_ctl start -D ${PGDATA}.standby
    waiting for server to start....2017-07-16 03:01:28.912 JST [79722] LOG:  listening on IPv6 address "::1", port 11111
    2017-07-16 03:01:28.912 JST [79722] LOG:  listening on IPv6 address "fe80::1%lo0", port 11111
    2017-07-16 03:01:28.912 JST [79722] LOG:  listening on IPv4 address "127.0.0.1", port 11111
    2017-07-16 03:01:28.921 JST [79722] LOG:  listening on Unix socket "/tmp/.s.PGSQL.11111"
    2017-07-16 03:01:28.941 JST [79723] LOG:  database system was interrupted; last known up at 2017-07-16 03:00:38 JST
    2017-07-16 03:01:29.126 JST [79723] LOG:  entering standby mode
    2017-07-16 03:01:29.134 JST [79723] LOG:  redo starts at 0/2000028
    2017-07-16 03:01:29.135 JST [79723] LOG:  consistent recovery state reached at 0/20000F8
    2017-07-16 03:01:29.135 JST [79722] LOG:  database system is ready to accept read only connections
    2017-07-16 03:01:29.160 JST [79727] LOG:  started streaming WAL from primary at 0/3000000 on timeline 1
     done
    server started
    
    

    Kiểm tra tình trạng Replication hiện tại (async: chưa đồng bộ)

    
    Bocap-no-MacBook-Pro:~ bocap$ psql
    psql (10beta1)
    Type "help" for help.
    
    postgres=# \x
    Expanded display is on.
    postgres=# select * from pg_stat_replication ;
    -[ RECORD 1 ]----+------------------------------
    pid              | 79728
    usesysid         | 16385
    usename          | postgres
    application_name | walreceiver
    client_addr      | 
    client_hostname  | 
    client_port      | -1
    backend_start    | 2017-07-16 03:01:29.158203+09
    backend_xmin     | 
    state            | streaming
    sent_lsn         | 0/3000060
    write_lsn        | 0/3000060
    flush_lsn        | 0/3000060
    replay_lsn       | 0/3000060
    write_lag        | 
    flush_lag        | 
    replay_lag       | 
    sync_priority    | 0
    sync_state       | async
    
    postgres=# create table test_synchronous(id integer);
    CREATE TABLE
    postgres=# insert into test_synchronous values (1);
    INSERT 0 1
    postgres=# select * from test_synchronous ;
     id 
    ----
      1
    (1 row)
    
    postgres=# \q
    Bocap-no-MacBook-Pro:~ bocap$ psql -p 11111
    psql (10beta1)
    Type "help" for help.
    
    postgres=# select * from test_synchronous ;
     id 
    ----
      1
    (1 row)
    
    postgres=# \q
    
    

    Chuyển qua chế độ tiền đồng bộ và kiểm tra tình trạng Replication

    
    Bocap-no-MacBook-Pro:~ bocap$ echo synchronous_standby_names='walreceiver' >> $PGDATA/postgresql.conf
    Bocap-no-MacBook-Pro:~ bocap$ pg_ctl reload
    server signaled
    2017-07-16 03:04:48.747 JST [69073] LOG:  received SIGHUP, reloading configuration files
    Bocap-no-MacBook-Pro:~ bocap$ 2017-07-16 03:04:48.755 JST [69073] LOG:  parameter "synchronous_standby_names" changed to "walreceiver"
    
    Bocap-no-MacBook-Pro:~ bocap$ 2017-07-16 03:04:50.068 JST [79728] LOG:  standby "walreceiver" is now a synchronous standby with priority 1
    
    
    
    Bocap-no-MacBook-Pro:~ bocap$ psql
    psql (10beta1)
    Type "help" for help.
    
    postgres=# \x
    Expanded display is on.
    postgres=# show synchronous_standby_names;
    -[ RECORD 1 ]-------------+------------
    synchronous_standby_names | walreceiver
    
    postgres=# select * from pg_stat_replication ;
    -[ RECORD 1 ]----+------------------------------
    pid              | 79728
    usesysid         | 16385
    usename          | postgres
    application_name | walreceiver
    client_addr      | 
    client_hostname  | 
    client_port      | -1
    backend_start    | 2017-07-16 03:01:29.158203+09
    backend_xmin     | 
    state            | streaming
    sent_lsn         | 0/3019058
    write_lsn        | 0/3019058
    flush_lsn        | 0/3019058
    replay_lsn       | 0/3019058
    write_lag        | 
    flush_lag        | 
    replay_lag       | 
    sync_priority    | 1
    sync_state       | sync
    
    postgres=# \q
    
    

    Chuyển qua chế độ Full Replication

    
    Bocap-no-MacBook-Pro:~ bocap$ psql
    psql (10beta1)
    Type "help" for help.
    
    postgres=# show synchronous_commit;
     synchronous_commit 
    --------------------
     on
    (1 row)
    
    postgres=# \q
    
    
    
    Bocap-no-MacBook-Pro:~ bocap$ echo synchronous_commit='remote_apply' >> $PGDATA/postgresql.conf
    Bocap-no-MacBook-Pro:~ bocap$ pg_ctl reload
    server signaled
    2017-07-16 03:23:54.258 JST [69073] LOG:  received SIGHUP, reloading configuration files
    Bocap-no-MacBook-Pro:~ bocap$ 2017-07-16 03:23:54.261 JST [69073] LOG:  parameter "synchronous_commit" changed to "remote_apply"
    
    
    
    Bocap-no-MacBook-Pro:~ bocap$ psql
    psql (10beta1)
    Type "help" for help.
    
    postgres=# \x
    Expanded display is on.
    postgres=# select * from pg_stat_replication ;
    -[ RECORD 1 ]----+------------------------------
    pid              | 79728
    usesysid         | 16385
    usename          | postgres
    application_name | walreceiver
    client_addr      | 
    client_hostname  | 
    client_port      | -1
    backend_start    | 2017-07-16 03:01:29.158203+09
    backend_xmin     | 
    state            | streaming
    sent_lsn         | 0/3019138
    write_lsn        | 0/3019138
    flush_lsn        | 0/3019138
    replay_lsn       | 0/3019138
    write_lag        | 
    flush_lag        | 
    replay_lag       | 
    sync_priority    | 1
    sync_state       | sync
    
    postgres=# show synchronous_commit;
    -[ RECORD 1 ]------+-------------
    synchronous_commit | remote_apply
    
    postgres=# \q
    Bocap-no-MacBook-Pro:~ bocap$ 
    
    

    Logical Replication

    Về cơ bản để sử dụng chức năng Logical Replication. Chúng ta tạo Publication bằng lệnh CREATE PUBLICATION phía Master Server. Phía Server còn lại (phía nhận WAL không phải là Standby như trên mà là một DB Server có thể ghi dữ liệu bình thường) tạo Subscription bằng lệnh CREATE SUBSCRIPTION như ví dụ bên dưới. Chi tiết về chức năng này sẽ được viết ở bài viết khác, khi PostgreSQL 10 đã được hoàn thành.

    
    Bocap-no-MacBook-Pro:~ bocap$ echo wal_level='logical' >> $PGDATA/postgresql.conf
    Bocap-no-MacBook-Pro:~ bocap$ pg_ctl restart
    waiting for server to shut down...2017-07-16 03:51:02.705 JST [80462] LOG:  received fast shutdown request
    .2017-07-16 03:51:02.705 JST [80462] LOG:  aborting any active transactions
    2017-07-16 03:51:02.708 JST [80464] LOG:  shutting down
    2017-07-16 03:51:02.750 JST [80462] LOG:  database system is shut down
     done
    server stopped
    waiting for server to start....2017-07-16 03:51:03.739 JST [80476] LOG:  listening on IPv6 address "::1", port 9100
    2017-07-16 03:51:03.739 JST [80476] LOG:  listening on IPv6 address "fe80::1%lo0", port 9100
    2017-07-16 03:51:03.739 JST [80476] LOG:  listening on IPv4 address "127.0.0.1", port 9100
    2017-07-16 03:51:03.754 JST [80476] LOG:  listening on Unix socket "/tmp/.s.PGSQL.9100"
    2017-07-16 03:51:03.787 JST [80477] LOG:  database system was shut down at 2017-07-16 03:51:02 JST
    2017-07-16 03:51:03.791 JST [80476] LOG:  database system is ready to accept connections
     done
    server started
    Bocap-no-MacBook-Pro:~ bocap$
    Bocap-no-MacBook-Pro:~ bocap$ psql -c "CREATE TABLE test_logical_rep(id integer)"
    CREATE TABLE
    Bocap-no-MacBook-Pro:~ bocap$ psql -c "CREATE PUBLICATION pub_test FOR TABLE test_logical_rep"
    CREATE PUBLICATION
    Bocap-no-MacBook-Pro:~ bocap$ psql -p 5432 -c "CREATE TABLE test_logical_rep(id integer)" 
    CREATE TABLE
    Bocap-no-MacBook-Pro:~ bocap$ psql -p 5432 -c "CREATE SUBSCRIPTION sub_test CONNECTION 'dbname=postgres port=9100 user=postgres' PUBLICATION pub_test"
    NOTICE:  synchronized table states
    2017-07-16 03:58:54.172 JST [80532] LOG:  logical decoding found consistent point at 0/3033BB0
    2017-07-16 03:58:54.172 JST [80532] DETAIL:  There are no running transactions.
    NOTICE:  created replication slot "sub_test" on publisher
    CREATE SUBSCRIPTION
    Bocap-no-MacBook-Pro:~ bocap$ 2017-07-16 03:58:54.190 JST [80533] LOG:  logical replication apply worker for subscription "sub_test" has started
    2017-07-16 03:58:54.196 JST [80534] LOG:  starting logical decoding for slot "sub_test"
    2017-07-16 03:58:54.196 JST [80534] DETAIL:  streaming transactions committing after 0/3033BE8, reading WAL from 0/3033BB0
    2017-07-16 03:58:54.196 JST [80534] LOG:  logical decoding found consistent point at 0/3033BB0
    2017-07-16 03:58:54.196 JST [80534] DETAIL:  There are no running transactions.
    2017-07-16 03:58:54.198 JST [80535] LOG:  logical replication table synchronization worker for subscription "sub_test", table "test_logical_rep" has started
    2017-07-16 03:58:54.207 JST [80536] LOG:  logical decoding found consistent point at 0/3033BE8
    2017-07-16 03:58:54.207 JST [80536] DETAIL:  There are no running transactions.
    2017-07-16 03:58:55.197 JST [80535] LOG:  logical replication table synchronization worker for subscription "sub_test", table "test_logical_rep" has finished
    
    Bocap-no-MacBook-Pro:~ bocap$ psql -c "INSERT INTO test_logical_rep VALUES(11111);"
    INSERT 0 1
    Bocap-no-MacBook-Pro:~ bocap$ psql -p 5432 -c "select * from test_logical_rep"
      id   
    -------
     11111
    (1 row)
    
    Bocap-no-MacBook-Pro:~ bocap$ 
    
    

    Xin vui lòng đặt câu hỏi hoặc thảo luận bằng comments box bên dưới.

    Đăng kí nhận RSS - replication