也谈PostgreSQL的同步配置
时间:2009-06-09
来源:互联网
· 作者:laruence(http://www.laruence.com/)
· 本文地址: http://www.laruence.com/2009/06/09/912.html
· 转载请注明出处
不知道”拉”一天开始, 好像大家都开始谈论PgSQL了, 呵呵, 最近尝试在项目中使用Pgsql, 现在就将使用Slony-I配置PostgreSQL同步的过程拿来与大家分享.
话说Pgsql虽然很流行,但是国内的文档真的是很少,尤其配置同步这块,基本上都是互相转贴, 写的也很笼统,在我自己配置过程中, 遇到了很多问题. 本文将努力将各种概念解释清楚, 尽量避免大家再遇到我遇到的疑难问题.
Slony-I是一个BSD授权的开源项目, 致力于解决Pgsql的同步.
它通过在配置中指明的数据库中的特定表上增加trigger(触发器), 从而在主库有变更的时候, 通过trigger函数连接到各个要同步的从库上同步从库.
正因为如此, 所以我们需要首先创建在每个数据库上的用户, 并且为超级用户, 并且需要配置pg_hab.conf使得主库和从库之间可以互联.
创建用户可以简单的使用pgsql的createuser, 以下我们假设创建的超级用户为repl,密码也为repl
$ pgsql_dir/bin/createuser -p repl
另外, 由于Slony的触发器函数是PLPGSQL语言写的, 所以我们也要给相应的数据库安装相应的语言包.
$ pgsql_dir/bin/createlang -d dbname plpgsql
接下来, 必须在主服务器和从服务器上都下载编译安装 slony-i(我的配置中, slony安装在/home/work/local/slony下, 请根据情况调整相关参数).
首先我们配置主服务器上:
1. 在主服务器上, 我们编辑一个shell脚本:configMaster.
#!/bin/sh
SLONIK=/home/work/local/slony/bin/slonik #slonik可执行文件位置
CLUSTER=Laruence #自定定义你的集群(Cluster)的名称
MASTER_ID=1 #主库ID
MASTER_HOST=db1.laruence.com #主库IP或主机名
MASTER_DBNAME=ams #需要复制的数据库名字
MASTER_USER=repl #主库数据库超级用户名
MASTER_PASSWORD=repl #主库数据库超级用户密码
SLAVER_ID=2 #从库ID
SLAVER_HOST=db2.laruence.com #从库IP或主机名
SLAVER_DBNAME=ams #需要同步的数据库名字(可以和主库数据库的名字不同)
SLAVER_USER=repl #从库数据库超级用户名
SLAVER_PASSWORD=repl #从库数据库超级用户密码
$SLONIK<<_EOF_
cluster name = $CLUSTER; #指明要定义的Cluster名
node $MASTER_ID admin conninfo = 'dbname=$MASTER_DBNAME host=$MASTER_HOST user=$MASTER_USER password=$MASTER_PASSWORD';
node $SLAVER_ID admin conninfo = 'dbname=$SLAVER_DBNAME host=$SLAVER_HOST user=$SLAVER_USER password=$SLAVER_PASSWORD';
init cluster(id = 1, comment = 'Primary Cluster'); #初始化Cluster,ID从1开始
create set ( id = 1, origin = $MASTER_ID, comment = 'Data Provider' ); #定义复制集, origin指明主库
set add table ( set id = 1, origin = $MASTER_ID, id = 1, fully qualified name = 'public.repl', comment='Repl Table' );
#为复制集合中增加表, fully qualified name 指明了要复制的表名.
store node ( id = $SLAVER_ID, comment = 'Slave Node', event node=$MASTER_ID); #定义从库节点
#定义路由路径
store path ( server=1, client=2, conninfo = 'dbname=$MASTER_DBNAME host=$MASTER_HOST user=$MASTER_USER password=$MASTER_PASSWORD');
#添加事件监听
store listen ( origin = $MASTER_ID, provider = $MASTER_ID, receiver = $SLAVER_ID );
_EOF_
然后赋予这个脚本可执行权限, 并在主库服务器上执行这个脚本.
如果执行成功, 我们在$MASTER_DBNAME的数据库中, 查看响应的表的话, 会发现, 这个表被增加了俩个触发器函数:
ams=# \d repl
Table "public.repl"
Column | Type | Modifiers
----------+------------------------+---------------------------------------------------
id | integer | not null default nextval('repl_id_seq'::regclass)
username | character varying(100) |
Indexes:
"repl_pkey" PRIMARY KEY, btree (id)
Triggers:
"_Laruence_logtrigger" AFTER INSERT OR DELETE OR UPDATE ON repl FOR EACH ROW EXECUTE PROCEDURE "_Laruence".logtrigger('_Laruence', '1', 'k')
Disabled triggers:
"_Laruence_denyaccess" BEFORE INSERT OR DELETE OR UPDATE ON repl FOR EACH ROW EXECUTE PROCEDURE "_Laruence".denyaccess('_Laruence')
详细信息, 大家也可以在pg_proc, pg_namespace寻找到更多信息.
2. 然后分别在主库服务器和从库服务器上启动slon进程, 开始监听.
主库服务器上:
./slon Laruence "dbname=ams host=slaver_host user=repl password=repl port=5432" & //其中Laruence为你定义的Cluster名
从库服务器上:
./slon Laruence "dbname=ams host=slaver_host user=repl password=repl port=5432"& //其中Laruence为你定义的Cluster名
3. 接下来,在主库服务器上提交同步集, 同样的建立一个shell脚本
#!/bin/bash
SLONIK=/home/work/local/slony/bin/slonik #slonik可执行文件位置
CLUSTER=Laruence #自定定义你的集群(Cluster)的名称
MASTER_ID=1 #主库ID
MASTER_HOST=db1.laruence.com #主库IP或主机名
MASTER_DBNAME=ams #需要复制的数据库名字
MASTER_USER=repl #主库数据库超级用户名
MASTER_PASSWORD=repl #主库数据库超级用户密码
SLAVER_ID=2 #从库ID
SLAVER_HOST=db2.laruence.com #从库IP或主机名
SLAVER_DBNAME=ams #需要同步的数据库名字(可以和主库数据库的名字不同)
SLAVER_USER=repl #从库数据库超级用户名
SLAVER_PASSWORD=repl #从库数据库超级用户密码
$SLONIK<<_EOF_
cluster name = $CLUSTER; #指明要定义的Cluster名
node $MASTER_ID admin conninfo = 'dbname=$MASTER_DBNAME host=$MASTER_HOST user=$MASTER_USER password=$MASTER_PASSWORD';
node $SLAVER_ID admin conninfo = 'dbname=$SLAVER_DBNAME host=$SLAVER_HOST user=$SLAVER_USER password=$SLAVER_PASSWORD';
# 提交订阅复制集
subscribe set ( id=1, provider=$MASTER_ID, receiver=$SLAVER_ID, forward=no);
_EOF_
同样,赋予这个脚本执行权限, 执行既可.
现在看看是否已经开始同步了呢?
Q&A:
1. 提示db_getLocalNodeId() wrong database?
检查store path是否设置正确, 主从是否指向正确.
2. 提示duplicate key sl_nodelock-pkey and duplicate …?
检查主机和从机上的slon进程都是连接向对方, 不要重复.
3. 运行configmain的时候, 提示REQUIRE EVENT NODE?
在定义store node 的时候, 需要指明事件源节点, 在本例中是主机节点($MASTER_ID)
4. 提示cannot connect to local database - fe_sendauth: no password supplied:
这是因为slony使用的c pgsql lib需要你在用户根目录下建立一个.pgpass文件, 文件的属性必须为0600, 文件的内容格式为: hostname:port:database:username:passwor
5. 能否实现主从互相同步呢?
可以, 只要指明反向的store path, 在订阅集中指明对映的复制条目, 既可.
6. 能否实现多个从机呢?
可以, 添加多个node, store path, set条目既可.
7. 还有其他问题,怎么办?
访问我的blog留言交流.
参考文档: SLONY-I
· 本文地址: http://www.laruence.com/2009/06/09/912.html
· 转载请注明出处
不知道”拉”一天开始, 好像大家都开始谈论PgSQL了, 呵呵, 最近尝试在项目中使用Pgsql, 现在就将使用Slony-I配置PostgreSQL同步的过程拿来与大家分享.
话说Pgsql虽然很流行,但是国内的文档真的是很少,尤其配置同步这块,基本上都是互相转贴, 写的也很笼统,在我自己配置过程中, 遇到了很多问题. 本文将努力将各种概念解释清楚, 尽量避免大家再遇到我遇到的疑难问题.
Slony-I是一个BSD授权的开源项目, 致力于解决Pgsql的同步.
它通过在配置中指明的数据库中的特定表上增加trigger(触发器), 从而在主库有变更的时候, 通过trigger函数连接到各个要同步的从库上同步从库.
正因为如此, 所以我们需要首先创建在每个数据库上的用户, 并且为超级用户, 并且需要配置pg_hab.conf使得主库和从库之间可以互联.
创建用户可以简单的使用pgsql的createuser, 以下我们假设创建的超级用户为repl,密码也为repl
$ pgsql_dir/bin/createuser -p repl
另外, 由于Slony的触发器函数是PLPGSQL语言写的, 所以我们也要给相应的数据库安装相应的语言包.
$ pgsql_dir/bin/createlang -d dbname plpgsql
接下来, 必须在主服务器和从服务器上都下载编译安装 slony-i(我的配置中, slony安装在/home/work/local/slony下, 请根据情况调整相关参数).
首先我们配置主服务器上:
1. 在主服务器上, 我们编辑一个shell脚本:configMaster.
#!/bin/sh
SLONIK=/home/work/local/slony/bin/slonik #slonik可执行文件位置
CLUSTER=Laruence #自定定义你的集群(Cluster)的名称
MASTER_ID=1 #主库ID
MASTER_HOST=db1.laruence.com #主库IP或主机名
MASTER_DBNAME=ams #需要复制的数据库名字
MASTER_USER=repl #主库数据库超级用户名
MASTER_PASSWORD=repl #主库数据库超级用户密码
SLAVER_ID=2 #从库ID
SLAVER_HOST=db2.laruence.com #从库IP或主机名
SLAVER_DBNAME=ams #需要同步的数据库名字(可以和主库数据库的名字不同)
SLAVER_USER=repl #从库数据库超级用户名
SLAVER_PASSWORD=repl #从库数据库超级用户密码
$SLONIK<<_EOF_
cluster name = $CLUSTER; #指明要定义的Cluster名
node $MASTER_ID admin conninfo = 'dbname=$MASTER_DBNAME host=$MASTER_HOST user=$MASTER_USER password=$MASTER_PASSWORD';
node $SLAVER_ID admin conninfo = 'dbname=$SLAVER_DBNAME host=$SLAVER_HOST user=$SLAVER_USER password=$SLAVER_PASSWORD';
init cluster(id = 1, comment = 'Primary Cluster'); #初始化Cluster,ID从1开始
create set ( id = 1, origin = $MASTER_ID, comment = 'Data Provider' ); #定义复制集, origin指明主库
set add table ( set id = 1, origin = $MASTER_ID, id = 1, fully qualified name = 'public.repl', comment='Repl Table' );
#为复制集合中增加表, fully qualified name 指明了要复制的表名.
store node ( id = $SLAVER_ID, comment = 'Slave Node', event node=$MASTER_ID); #定义从库节点
#定义路由路径
store path ( server=1, client=2, conninfo = 'dbname=$MASTER_DBNAME host=$MASTER_HOST user=$MASTER_USER password=$MASTER_PASSWORD');
#添加事件监听
store listen ( origin = $MASTER_ID, provider = $MASTER_ID, receiver = $SLAVER_ID );
_EOF_
然后赋予这个脚本可执行权限, 并在主库服务器上执行这个脚本.
如果执行成功, 我们在$MASTER_DBNAME的数据库中, 查看响应的表的话, 会发现, 这个表被增加了俩个触发器函数:
ams=# \d repl
Table "public.repl"
Column | Type | Modifiers
----------+------------------------+---------------------------------------------------
id | integer | not null default nextval('repl_id_seq'::regclass)
username | character varying(100) |
Indexes:
"repl_pkey" PRIMARY KEY, btree (id)
Triggers:
"_Laruence_logtrigger" AFTER INSERT OR DELETE OR UPDATE ON repl FOR EACH ROW EXECUTE PROCEDURE "_Laruence".logtrigger('_Laruence', '1', 'k')
Disabled triggers:
"_Laruence_denyaccess" BEFORE INSERT OR DELETE OR UPDATE ON repl FOR EACH ROW EXECUTE PROCEDURE "_Laruence".denyaccess('_Laruence')
详细信息, 大家也可以在pg_proc, pg_namespace寻找到更多信息.
2. 然后分别在主库服务器和从库服务器上启动slon进程, 开始监听.
主库服务器上:
./slon Laruence "dbname=ams host=slaver_host user=repl password=repl port=5432" & //其中Laruence为你定义的Cluster名
从库服务器上:
./slon Laruence "dbname=ams host=slaver_host user=repl password=repl port=5432"& //其中Laruence为你定义的Cluster名
3. 接下来,在主库服务器上提交同步集, 同样的建立一个shell脚本
#!/bin/bash
SLONIK=/home/work/local/slony/bin/slonik #slonik可执行文件位置
CLUSTER=Laruence #自定定义你的集群(Cluster)的名称
MASTER_ID=1 #主库ID
MASTER_HOST=db1.laruence.com #主库IP或主机名
MASTER_DBNAME=ams #需要复制的数据库名字
MASTER_USER=repl #主库数据库超级用户名
MASTER_PASSWORD=repl #主库数据库超级用户密码
SLAVER_ID=2 #从库ID
SLAVER_HOST=db2.laruence.com #从库IP或主机名
SLAVER_DBNAME=ams #需要同步的数据库名字(可以和主库数据库的名字不同)
SLAVER_USER=repl #从库数据库超级用户名
SLAVER_PASSWORD=repl #从库数据库超级用户密码
$SLONIK<<_EOF_
cluster name = $CLUSTER; #指明要定义的Cluster名
node $MASTER_ID admin conninfo = 'dbname=$MASTER_DBNAME host=$MASTER_HOST user=$MASTER_USER password=$MASTER_PASSWORD';
node $SLAVER_ID admin conninfo = 'dbname=$SLAVER_DBNAME host=$SLAVER_HOST user=$SLAVER_USER password=$SLAVER_PASSWORD';
# 提交订阅复制集
subscribe set ( id=1, provider=$MASTER_ID, receiver=$SLAVER_ID, forward=no);
_EOF_
同样,赋予这个脚本执行权限, 执行既可.
现在看看是否已经开始同步了呢?
Q&A:
1. 提示db_getLocalNodeId() wrong database?
检查store path是否设置正确, 主从是否指向正确.
2. 提示duplicate key sl_nodelock-pkey and duplicate …?
检查主机和从机上的slon进程都是连接向对方, 不要重复.
3. 运行configmain的时候, 提示REQUIRE EVENT NODE?
在定义store node 的时候, 需要指明事件源节点, 在本例中是主机节点($MASTER_ID)
4. 提示cannot connect to local database - fe_sendauth: no password supplied:
这是因为slony使用的c pgsql lib需要你在用户根目录下建立一个.pgpass文件, 文件的属性必须为0600, 文件的内容格式为: hostname:port:database:username:passwor
5. 能否实现主从互相同步呢?
可以, 只要指明反向的store path, 在订阅集中指明对映的复制条目, 既可.
6. 能否实现多个从机呢?
可以, 添加多个node, store path, set条目既可.
7. 还有其他问题,怎么办?
访问我的blog留言交流.
参考文档: SLONY-I
作者: laruence 发布时间: 2009-06-09
看看
作者: nianjin 发布时间: 2009-06-13
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28