你的位置:首页 > 数据库

[数据库]PostgreSQL Replication之第十章 配置Slony(5)


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

您可以开始一个事务,并尝试删除一行。它应该失败。如果他不失败,您可以安全地回滚,并尝试解决您的问题。就像您在使用事务一样,从不提交,什么都不会会出现错误。