10.5 给复制添加表和管理的问题
一旦我们增加了此表到系统中,我们可以将它添加到复制设置。这样做有点复杂。首先,我们必须创建我们自己的新表集合并把这个和我们已经有的表合并。因此,过一段时间,我们将有两个表集合。该脚本是这样的:
#!/bin/sh
MASTERDB=db1
SLAVEDB=db2
HOST1=localhost
HOST2=localhost
DBUSER=hs
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=5,
fully qualified name = 'public.t_second',
comment='second table');
subscribe set(id=1, provider=1,receiver=2);
merge set(id=1, add id=2,origin=1);
_EOF_
成功的关键是在脚本结尾处的 merge 调用。它将确保,这些新表将被集成到现有的表集合。
当脚本被执行是,我们将面临一个预期的问题,具体如下:
hs@hs-VirtualBox:~/slony$ sh slony_add_to_set.sh
<stdin>:7: PGRES_FATAL_ERROR select "_first_cluster".determineIdxnameU
nique('public.t_second', NULL); - ERROR: Slony-I: table "public"."t_
second" has no primary key
我们已经创建了一个 没有主键的妙。这是非常重要的—Slony没有办法复制一个没有主键的表。因此,我们必须添加这个主键。基本上,我们有两个选择做到它。这里所期望的方法是一定要使用execute script,就像我们在前面展示的那样。如果您的系统是空闲的,您也可以使用麻烦的方法快速做到:
db1=# ALTER TABLE t_second ADD PRIMARY KEY (id);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "t_second_pkey" for table "t_second"
ALTER TABLE
db1=# \q
hs@hs-VirtualBox:~/slony$ psql db2
psql (9.2.4)
Type "help" for help.
db2=# ALTER TABLE t_second ADD PRIMARY KEY (id);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "t_second_pkey" for table "t_second"
ALTER TABLE
然而,这是不推荐的—使用Slony接口来做这样的修改是跟理想的。
一旦我们修改了数据结构,我们可以再次执行 slonik 脚本,看看会发生什么:
hs@hs-VirtualBox:~/slony$ sh slony_add_to_set.sh
<stdin>:6: PGRES_FATAL_ERROR lock table "_first_cluster".sl_event_lock,
"_first_cluster".sl_config_lock;select "_first_cluster".storeSet(2, 'a
second replication set'); - ERROR: duplicate key value violates unique
constraint "sl_set-pkey"
DETAIL: Key (set_id)=(2) already exists.
CONTEXT: SQL statement "insert into "_first_cluster".sl_set
(set_id, set_origin, set_comment) values
(p_set_id, v_local_node_id, p_set_comment)"
PL/pgSQL function _first_cluster.storeset(integer,text) line 7 at SQL
statement
您看到的是一个典型的使用Slony您将面对的问题。如果出现错误,它真的,真的很难让所有的事情井然有序。这是一个您应该准备的场景。
[如果您在一台生产系统上使用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';
drop set (id=2, origin=1);
_EOF_
要删除一个表集,我们可以运行 drop set 。它将帮助您回到您开始的地方。这个脚本会执行的很干净:
hs@hs-VirtualBox:~/slony$ sh slony_drop_set.sh
现在,我们可以再次重新启动,并添加表。请注意,我们在对slave使用两个集合,以确保这干净地执行:
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=5, fully qualified name =
'public.t_second', 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_
现在,我们可以干净地执行那个脚本,一切都将被如期复制:
hs@hs-VirtualBox:~/slony$ sh slony_add_to_set_v2.sh
<stdin>:11 subscription in progress before mergeSet. waiting
<stdin>:11 subscription in progress before mergeSet. waiting
正如我们已经指出的,在本章中,我们特意犯了一个小错误,您已经看到了,即使它只是一个小错误,使事情顺利是多么的棘手和紧张。其中的一个原因是,一个脚本基本上不是服务端的一个事务。所以,如果一个脚本在中间某个地方失败,它将停止工作—它将不会撤销迄今为止所做的改变。这可能会导致一些问题;这是在节说描述的。
所以,一旦您做出来改变,您应该经常看一下,并看看是否一切都正常工作。下面是一个这样做的简单的方法:
db2=# BEGIN;
BEGIN
db2=# DELETE FROM t_second;
ERROR: Slony-I: Table t_second is replicated and cannot be modified on a subscriber node - role=0
db2=# ROLLBACK;
ROLLBACK
您可以开始一个事务,并尝试删除一行。它应该失败。如果他不失败,您可以安全地回滚,并尝试解决您的问题。就像您在使用事务一样,从不提交,什么都不会会出现错误。