PostgreSQL逻辑复制之slony篇

Slony是PostgreSQL领域中最广泛的复制解决方案之一。它不仅是最古老的复制实现之一,它也是一个拥有最广泛的外部工具支持的工具,Slony使用逻辑复制;Slony-I一般要求表有主键,或者唯一键;Slony的工作不是基于PostgreSQL事务日志的,而是基于触发器的;基于逻辑复制高可用性,PostgreSQL除了slony;还有Londiste,BDR等等后续文章会讲到。

1.安装Slony

下载地址:http://www.slony.info
安装步骤

tar -jxvf slony1-2.2.5.tar.bz2
cd slony1-2.2.5
./configure --with-pgconfigdir=/opt/pgsql96/bin
make
make install

安装完成!
执行./configure时;会在当前目录是否可以找到pg_config命令;本例pg_config在/opt/pgsql96/bin目录下;

2. Slony架构图

slony.png

3. 复制表

现有实验环境

主机名 IP 角色
PostgreSQL201 192.168.1.201 master
PostgreSQL202 192.168.1.202 slave

3.1 在两台数据库中都创建一个slony的超级用户;专为slony服务;

create user slony superuser password 'li0924';

3.2 本实验两台主机都有lottu数据库;以lottu数据库中的表作为实验对象;在两个数据库中以相同的方式创建该表synctab,因为表结构不会自动复制

create table synctab(id int primary key,name text);

3.3 在所有节点设置允许Slony-I用户远程登录;在pg_hba.conf文件添加

host    all             slony             192.168.1.0/24        trust

3.4 设置slony(master主机操作)
编写一个slonik脚本用于注册这些节点的脚本如下所示:

[postgres@Postgres201 ~]$ cat slony_setup.sh 
#!/bin/sh
MASTERDB=lottu
SLAVEDB=lottu
HOST1=192.168.1.201
HOST2=192.168.1.202
DBUSER=slony
slonik<<_EOF_
cluster name = first_cluster;
# define nodes (this is needed by pretty much
# all slonik scripts)
node 1 admin conninfo = 'dbname=$MASTERDB host=$HOST1 user=$DBUSER';
node 2 admin conninfo = 'dbname=$SLAVEDB host=$HOST2 user=$DBUSER';
# init cluster
init cluster ( id=1, comment = 'Master Node');
# group tables into sets
create set (id=1, origin=1, comment='Our tables');
set add table (set id=1, origin=1, id=1, fully qualified name = 'lottu.synctab', comment='sample table');
store node (id=2, comment = 'Slave node', event node=1);
store path (server = 1, client = 2, conninfo='dbname=$MASTERDB host=$HOST1 user=$DBUSER');
store path (server = 2, client = 1, conninfo='dbname=$SLAVEDB host=$HOST2 user=$DBUSER');
_EOF_

现在这个表在Slony的控制下,我们可以开始订阅脚本如下所示:

[postgres@Postgres201 ~]$ cat slony_subscribe.sh 
#!/bin/sh
MASTERDB=lottu
SLAVEDB=lottu
HOST1=192.168.1.201
HOST2=192.168.1.202
DBUSER=slony
slonik<<_EOF_
cluster name = first_cluster;
node 1 admin conninfo = 'dbname=$MASTERDB host=$HOST1 user=$DBUSER';
node 2 admin conninfo = 'dbname=$SLAVEDB host=$HOST2 user=$DBUSER';
subscribe set ( id = 1, provider = 1, receiver = 2, forward = no);
_EOF_

在master主机执行脚本

[postgres@Postgres201 ~]$ ./slony_setup.sh 
[postgres@Postgres201 ~]$ ./slony_subscribe.sh &
[1] 1225

定义了我们想要复制的东西之后,我们可以在每台主机启动slon守护进程

slon first_cluster 'host=192.168.1.201 dbname=lottu user=slony' &
slon first_cluster 'host=192.168.1.202 dbname=lottu user=slony' &

验证slony-I是否配置成功。
在master主机执行dml操作

[postgres@Postgres201 ~]$ psql lottu lottu
psql (9.6.0)
Type "help" for help.

lottu=# \d synctab
    Table "lottu.synctab"
 Column |  Type   | Modifiers 
--------+---------+-----------
 id     | integer | not null
 name   | text    | 
Indexes:
    "synctab_pkey" PRIMARY KEY, btree (id)
Triggers:
    _first_cluster_logtrigger AFTER INSERT OR DELETE OR UPDATE ON synctab FOR EACH ROW EXECUTE PROCEDURE _first_cluster.logtrigger('_first_cluster', '1', 'k')
    _first_cluster_truncatetrigger BEFORE TRUNCATE ON synctab FOR EACH STATEMENT EXECUTE PROCEDURE _first_cluster.log_truncate('1')
Disabled user triggers:
    _first_cluster_denyaccess BEFORE INSERT OR DELETE OR UPDATE ON synctab FOR EACH ROW EXECUTE PROCEDURE _first_cluster.denyaccess('_first_cluster')
    _first_cluster_truncatedeny BEFORE TRUNCATE ON synctab FOR EACH STATEMENT EXECUTE PROCEDURE _first_cluster.deny_truncate()
lottu=# insert into synctab values (1001,'lottu');
INSERT 0 1

在slave主机查看是否对应变化

[postgres@Postgres202 ~]$ psql
psql (9.6.0)
Type "help" for help.

postgres=# \c lottu lottu
You are now connected to database "lottu" as user "lottu".
lottu=> select * from synctab ;
  id  | name  
------+-------
 1001 | lottu
(1 row)

4. Slony-I相关表或者视图查看

4.1 配置成功;会在所在的数据库中生成一个schema

[postgres@Postgres201 ~]$ psql lottu lottu
psql (9.6.0)
Type "help" for help.

lottu=# \dn
      List of schemas
      Name      |  Owner   
----------------+----------
 _first_cluster | slony
 lottu          | lottu
 public         | postgres
(3 rows)

4.2 查看集群中的节点信息

lottu=# select * from _first_cluster.sl_node;
 no_id | no_active | no_comment  | no_failed 
-------+-----------+-------------+-----------
     1 | t         | Master Node | f
     2 | t         | Slave node  | f
(2 rows)

4.3 查看集群中的集合信息

lottu=# select * from _first_cluster.sl_set;
 set_id | set_origin | set_locked | set_comment 
--------+------------+------------+-------------
      1 |          1 |            | Our tables
(1 row)

4.4 查看集群中的表信息

lottu=# select * from _first_cluster.sl_table;
 tab_id | tab_reloid | tab_relname | tab_nspname | tab_set | tab_idxname  | tab_altered | tab_comment  
--------+------------+-------------+-------------+---------+--------------+-------------+--------------
      1 |      57420 | synctab     | lottu       |       1 | synctab_pkey | f           | sample table
(1 row)

5. 日常维护

5.1 Slony-I向现有集群中增加一个复制表
以表synctab2为例:

create table synctab2(id int primary key,name text,reg_time timestamp);

我们要创建一个新的表格集;脚本是这样的

[postgres@Postgres201 ~]$ cat slony_add_table_set.sh 
#!/bin/sh
MASTERDB=lottu
SLAVEDB=lottu
HOST1=192.168.1.201
HOST2=192.168.1.202
DBUSER=slony
slonik<<_EOF_
cluster name = first_cluster;
node 1 admin conninfo = 'dbname=$MASTERDB host=$HOST1 user=$DBUSER';
node 2 admin conninfo = 'dbname=$SLAVEDB host=$HOST2 user=$DBUSER';
create set (id=2, origin=1, comment='a second replication set');
set add table (set id=2, origin=1, id=2, fully qualified name ='lottu.synctab2', comment='second table');
subscribe set(id=1, provider=1,receiver=2);
subscribe set(id=2, provider=1,receiver=2);
merge set(id=1, add id=2,origin=1);
_EOF_

执行slony_add_table_set.sh脚本

[postgres@Postgres201 ~]$ ./slony_add_table_set.sh 
<stdin>:8 subscription in progress before mergeSet. waiting
<stdin>:8 subscription in progress before mergeSet. waiting

查看是否添加成功

lottu=# select * from _first_cluster.sl_table;
 tab_id | tab_reloid | tab_relname | tab_nspname | tab_set |  tab_idxname  | tab_altered | tab_comment  
--------+------------+-------------+-------------+---------+---------------+-------------+--------------
      1 |      57420 | synctab     | lottu       |       1 | synctab_pkey  | f           | sample table
      2 |      57840 | synctab2    | lottu       |       1 | synctab2_pkey | f           | second table
(2 rows)

5.2 Slony-I向现有集群中删除一个复制表

[postgres@Postgres201 ~]$ cat slony_drop_table.sh
#!/bin/sh
MASTERDB=lottu
SLAVEDB=lottu
HOST1=192.168.1.201
HOST2=192.168.1.202
DBUSER=slony
slonik<<_EOF_
cluster name = first_cluster;
node 1 admin conninfo = 'dbname=$MASTERDB host=$HOST1 user=$DBUSER';
node 2 admin conninfo = 'dbname=$SLAVEDB host=$HOST2 user=$DBUSER';
set drop table (id=2, origin=1);
_EOF_

执行slony_drop_table.sh脚本

[postgres@Postgres201 ~]$ ./slony_drop_table.sh

查看是否删除成功

lottu=# select * from _first_cluster.sl_table;
 tab_id | tab_reloid | tab_relname | tab_nspname | tab_set | tab_idxname  | tab_altered | tab_comment  
--------+------------+-------------+-------------+---------+--------------+-------------+--------------
      1 |      57420 | synctab     | lottu       |       1 | synctab_pkey | f           | sample table
(1 row)

  1. 3 删除slony
[postgres@Postgres201 ~]$ cat slony_drop_node.sh 
#!/bin/sh
MASTERDB=lottu
SLAVEDB=lottu
HOST1=192.168.1.201
HOST2=192.168.1.202
DBUSER=slony
slonik<<_EOF_
cluster name = first_cluster;
node 1 admin conninfo = 'dbname=$MASTERDB host=$HOST1 user=$DBUSER';
node 2 admin conninfo = 'dbname=$SLAVEDB host=$HOST2 user=$DBUSER';
uninstall node (id = 1);
uninstall node (id = 2);
_EOF_

执行脚本如下

postgres@Postgres201 ~]$ ./slony_drop_node.sh 
<stdin>:4: NOTICE:  Slony-I: Please drop schema "_first_cluster"
<stdin>:4: NOTICE:  drop cascades to 175 other objects
.........
drop cascades to function _first_cluster.unlockset(integer)
drop cascades to function _first_cluster.moveset(integer,integer)
drop cascades to function _first_cluster.moveset_int(integer,integer,integer,bigint)
and 75 other objects (see server log for list)

完美;一切归零!


查考文献
https://www.cnblogs.com/ilifeilong/p/7009322.html
https://www.cnblogs.com/gaojian/p/3196244.html


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • About:PostgreSQL About 《PostgreSQL 源码分析系列》 PostgreSQL 源码分...
    ty4z2008阅读 8,182评论 1 40
  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 3,847评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • 2018年5月2日 星期三 晴 大风 风,总是在这个时节不停歇地“工作”。 上午原本计划带弟弟玩沙子去,可是小家伙...
    漫漫无忧阅读 98评论 2 2
  • 20
    DidorDone阅读 158评论 0 0