1. 程式人生 > >PostgreSQL 邏輯複製外掛 UDR,可以愉快的玩類似MySQL的binlog複製了。

PostgreSQL 邏輯複製外掛 UDR,可以愉快的玩類似MySQL的binlog複製了。

Postgres2015全國使用者大會將於11月20至21日在北京麗亭華苑酒店召開。本次大會嘉賓陣容強大,國內頂級PostgreSQL資料庫專家將悉數到場,並特邀歐洲、俄羅斯、日本、美國等國家和地區的資料庫方面專家助陣:

  • Postgres-XC專案的發起人鈴木市一(SUZUKI Koichi)
  • Postgres-XL的專案發起人Mason Sharp
  • pgpool的作者石井達夫(Tatsuo Ishii)
  • PG-Strom的作者海外浩平(Kaigai Kohei)
  • Greenplum研發總監姚延棟
  • 周正中(德哥), PostgreSQL中國使用者會創始人之一
  • 汪洋,平安科技資料庫技術部經理
  • ……
2015年度PG大象會報名地址:
http://postgres2015.eventdove.com/
PostgreSQL中國社群: http://postgres.cn/PostgreSQL專業1群: 3336901(已滿)PostgreSQL專業2群: 100910388PostgreSQL專業3群: 150657323


PostgreSQL 的流複製素來以高效,實時,穩定著稱;為企業解決了很多問題,例如容災,備份,HA,讀寫分離等等。 但是流複製有一個無法克服的弊端,下游節點只能做到只讀,並且只能複製整個叢集(使用walbouncer可以做到基於表空間或庫級別的物理流複製)。 如果使用者確實有表級或行級的複製需求,我們不得不使用其他手段來實施,例如londiste3, dblink, trigger, bucardo, slony-I等。 這些外掛或工具是基於觸發器的,所以對上游節點的效能影響比較大,而且複製效率一般般。 PostgreSQL社群一直在努力將邏輯複製加入到PG的核心中,同樣使用的是XLOG,從XLOG中解出row,在下游節點回放。有點類似於MySQL的binlog複製方案。 在邏輯複製加入PostgreSQL核心程式碼前(預計9.6的版本可能會加入),使用者可以使用2nd提供的bdr外掛來實現邏輯複製。 如果做單向的複製,使用9.4或以上的PostgreSQL版本即可,而如果要使用雙向複製(多主),則需要使用2nd提供的PostgreSQL版本。 地址: 本文以單向複製為例,即UDR,講解一下這個外掛的使用。 下載外掛,我們需要的是bdr-plugin的穩定分支。 # git clone -b bdr-plugin/REL0_9_STABLE git://git.postgresql.org/git/2ndquadrant_bdr.git bdr-plugin
安裝UDR外掛 # export PATH=/opt/pgsql/bin:$PATH# cd bdr-plugin# ./autogen.sh# ./configure BUILDING_UDR=1# make; make install 修改BUG # cd /opt/pgsql/share/extension[root@digoal extension]# cat bdr.control |grep default_versiondefault_version = '0.9.2.0'# vi bdr--0.9.2.0.sql -- 註釋掉這行,應該是bdr的BUG,這個函式依賴的C函式在2nd改版的postgresql下面。
-- CREATE OR REPLACE FUNCTION bdr.bdr_internal_sequence_reset_cache(seq regclass)-- RETURNS void LANGUAGE c AS 'MODULE_PATHNAME' STRICT; 配置上游和下游節點 上游節點 $ vi postgresql.conf listen_addresses='0.0.0.0'port=1921max_connections=100unix_socket_directories='.'ssl=onssl_ciphers='EXPORT40'shared_buffers=512MBhuge_pages=trymax_prepared_transactions=0max_stack_depth=100kBdynamic_shared_memory_type=posixmax_files_per_process=500shared_preload_libraries='bdr'max_worker_processes=8wal_level=logicalfsync=offsynchronous_commit=offwal_sync_method=open_datasyncfull_page_writes=offwal_log_hints=offwal_buffers=16MBwal_writer_delay=10mscheckpoint_segments=8archive_mode=offarchive_command='/bin/date'max_wal_senders=10max_replication_slots=10hot_standby=onwal_receiver_status_interval=1shot_standby_feedback=onenable_bitmapscan=onenable_hashagg=onenable_hashjoin=onenable_indexscan=onenable_material=onenable_mergejoin=onenable_nestloop=onenable_seqscan=onenable_sort=onenable_tidscan=onlog_destination='csvlog'logging_collector=onlog_directory='pg_log'log_truncate_on_rotation=onlog_rotation_size=10MBlog_checkpoints=onlog_connections=onlog_disconnections=onlog_duration=offlog_error_verbosity=verboselog_line_prefix='%ilog_statement='none'log_timezone='PRC'autovacuum=onlog_autovacuum_min_duration=0autovacuum_vacuum_scale_factor=0.0002autovacuum_analyze_scale_factor=0.0001datestyle='iso,timezone='PRC'lc_messages='C'lc_monetary='C'lc_numeric='C'lc_time='C'default_text_search_config='pg_catalog.english'bdr.conflict_logging_include_tuples=truebdr.log_conflicts_to_table=truebdr.temp_dump_directory='pg_bdr_temp_dump_dir' $ vi pg_hba.conf # "local" is for Unix domain socket connections onlylocal   all             all                                     trust# IPv4 local connections:host    all             all             127.0.0.1/32            trust# IPv6 local connections:#host    all             all             ::1/128                 trust# Allow replication connections from localhost, by a user with the# replication privilege.local   replication     postgres                                trusthost    replication     postgres 127.0.0.1/32            trust 配置下游節點 1. 只有postgresql.conf中配置的監聽埠不一樣,其他一樣。 2. 建立邏輯備份目錄。在下游節點初始化訂閱時,需要用來儲存從上游節點dump的整個被訂閱的資料庫的資料,所以這個目錄的空間要足夠大。 mkdir $PGDATA/pg_bdr_temp_dump_dir 啟動資料庫。 # 假設我的上游節點是1921埠,下游節點是1922埠。 pg_ctl start -D /data01/pgdata_1921pg_ctl start -D /data01/pgdata_1922 # 在上游節點,我有一個數據庫為up,我需要將這個資料庫複製到下游節點的資料庫down中。 # 建立上游資料庫,並且在up庫建立bdr擴充套件。 postgres@digoal-> psql -h 127.0.0.1-p 1921psql(9.4.4)Type"help"for help.postgres=# create database up;CREATE DATABASEpostgres=# \c upYou are now connected to database "up" as user "postgres".up=# create table tb(id int,info text);
CREATE TABLE
up=# insert into tb select generate_series(1,100);
INSERT 0100
up=# create extension btree_gist;CREATE EXTENSIONup=# create extension bdr;CREATE EXTENSION # 建立測試表,測試資料型別,測試函式,測試檢視 postgres=# \c upYou are now connected to database "up" as user "postgres".up=# create table t1(id int primary key,info text);CREATE TABLEup=# create or replace function f1() returns void as $$ declare begin   raise notice '%', now(); end; $$ language plpgsql;CREATE FUNCTIONup=# create view v1 as select count(*) as cnt from t1;CREATE VIEWup=# create type dt as (c1 int,c2 int,c3 int);CREATE TYPEup=# insert into t1 select generate_series(1,100);INSERT 0 100up=# create table t2(id int,c1 dt);CREATE TABLEup=# insert into t2 values (1,'(1,1,1)');INSERT 0 1up=# insert into t2 values (2,'(1,1,1)');INSERT 0 1up=# insert into t2 values (2,'(1,1,1)');INSERT 0 1up=# insert into t2 values (2,'(1,1,1)');INSERT 0 1up=# insert into t2 values (2,'(1,1,1)');INSERT 0 1 建立bdr擴充套件後,新建的表會自動新增TRUNCATE觸發器 up=# \d t1      Table "public.t1" Column |  Type   | Modifiers --------+---------+----------- id     | integer | not null info   | text    | Indexes:    "t1_pkey" PRIMARY KEY, btree (id)Triggers:    truncate_trigger AFTER TRUNCATE ON t1 FOR EACH STATEMENT EXECUTE PROCEDURE bdr.queue_truncate() # 建立下游節點的資料庫down,同時也在這個資料庫中建立bdr擴充套件。 postgres@digoal-> psql -h 127.0.0.1-p 1922psql(9.4.4)Type"help"for help.postgres=# create database down;CREATE DATABASEpostgres=# \c downYou are now connected to database "down" as user "postgres".down=# create extension btree_gist;CREATE EXTENSIONdown=# create extension bdr;CREATE EXTENSIONdown=# create database up; -- 務必建立哦 為什麼在下游節點還需要建立一個up庫(雖然我們不是將資料訂閱到up庫),但是沒有這個庫,還原會報錯,例如: 這顯然是個BUG。 Dumping remote database "hostaddr=127.0.0.1 port=1921 dbname=up user=postgres fallback_application_name='bdr (6203675445083668497,1,16385,): init_replica dump'"with1 concurrent workers to "pg_bdr_temp_dump_dir/postgres-bdr-000C837A-1.8393"Restoringdump to local DB "hostaddr=127.0.0.1 port=1922 dbname=down user=postgres fallback_application_name='bdr (6203675445083668497,1,16385,): init_replica restore' options='-c bdr.do_not_replicate=on -c bdr.permit_unsafe_ddl_commands=on -c bdr.skip_ddl_replication=on -c bdr.skip_ddl_locking=on'"with1 concurrent workers from"pg_bdr_temp_dump_dir/postgres-bdr-000C837A-1.8393"pg_restore:[archiver (db)]Errorwhile PROCESSING TOC:pg_restore:[archiver (db)]Errorfrom TOC entry 3265;1262