您的位置:首页 > 数据库

TimesTen 数据库复制学习:7. 管理Active Standby Pair(无缓存组)

2016-06-06 18:52 786 查看
Active Standby Pair是TimesTen复制的一种固定模式,就是1个active到1个standby,再到0个或127个subscriber,如下图:



配置 Active Standby Pair (不带缓存组)

大致步骤如下:

1. 创建数据库

2. 使用CREATE ACTIVE STANDBY PAIR创建复制

3. 调用
Call ttRepStateSet('ACTIVE')
,将active数据库的角色设为ACTIVE

4. 调用
Call ttRepStart
, 启动复制代理

5. 在active数据库中创建用户(用户名建议为repadmin),并赋予ADMIN权限

6. 克隆active数据库到standby数据库

7. 在standby数据库启动复制代理

8. 等待standby的角色自动变为STANDBY. (
call ttrepstateget
)

9. 克隆standby到subscriber数据库,如果有的话

10. 在subscriber数据库上启动复制代理

从active数据库的错误中恢复

当standby 可用时的恢复

当复制是return receipt 或 异步复制时

停止失效数据库的复制代理

将standby数据库角色设为ACTIVE。(ttRepStateSet(‘ACTIVE’))

在新的active数据库中,将原来的active设为失效。(ttRepStateSave(‘FAILED’, ‘failed_database’,’host_name’))

这一步是必要的,因为正常情况下,只有standby才能向subscriber复制,而此时,我们必须让active向subscriber复制

删除失效的active数据库。(ttdestroy failed_database)

通过新的active克隆一个新的standby

在新的standby上启动复制代理

新的standby与active同步后,会接管向subscriber的复制任务

拓扑恢复正常,只不过此时active和standby调换了角色

实验过程如下:

首先设置一个active,standby和subscriber,过程可参见TimesTen 数据库复制学习:2. 配置Active Standby Pair ,确保三个库的状态分别为ACTIVE, STANDBY和IDLE。

master1> call ttrepstop; <- 停止active数据库上的复制代理,模拟其失效

master2> call ttRepStateSet('ACTIVE');
master2> call ttRepStateGet;
< ACTIVE, NO GRID >
1 row found.
master2> call ttRepStateSave('FAILED', 'master1','timesten-hol');
master2> @insert2

INSERT INTO employees VALUES
( 203,
'Judy',
'Fox',
'JFOX',
'603-123-7777',
TO_DATE('17-AUG-1997', 'dd-MON-yyyy'),
'MK_REP',
6000,
NULL,
201,
20
);
1 row inserted. <- 此时active暂时接管了向subscriber的复制

subscriber1> select * from employees;
< 203, Judy, Fox, JFOX, 603-123-7777, 1997-08-17 00:00:00, MK_REP, 6000, <NULL>, 201, 20 >
1 rows found.

[oracle@timesten-hol ~]$ ttdestroy master1

[oracle@timesten-hol ~]$ ttRepAdmin -duplicate -from master2 -host $(hostname) -uid repadmin -pwd timesten master1

master1> call ttrepstart;
master1> call ttrepstateget;
< STANDBY, NO GRID > <-之前失效的active数据库变为standby
1 row found.

master2> @insert2

INSERT INTO employees VALUES
( 203,
'Judy',
'Fox',
'JFOX',
'603-123-7777',
TO_DATE('17-AUG-1997', 'dd-MON-yyyy'),
'MK_REP',
6000,
NULL,
201,
20
);
1 row inserted. <- 在新的active上插入数据后,新的standby,subscriber都可以接受到数据,此时,standby重新接管了向subscriber的复制

master1> select count(*) from employees where employee_id = 203;
< 1 >
1 row found.

subscriber1> select count(*) from employees where employee_id = 203;
< 1 >
1 row found.


当复制是return twosafe时

将standby数据库角色设为ACTIVE。(ttRepStateSet(‘ACTIVE’))

在新的active数据库中,将原来的active设为失效。(ttRepStateSave(‘FAILED’, ‘failed_database’,’host_name’))

连接到之前失效的active数据库,自动启动恢复;如果恢复失败,则从新的active克隆,之后的过程与return receipt和异步相同。

将standby数据库角色设为ACTIVE。(ttRepStateSet(‘ACTIVE’))

在新的standby上启动复制代理

当新的standby同步后,会重写接管向subscriber复制的任务。

实验过程如下:

首先设置一个active,standby和subscriber,过程可参见TimesTen 数据库复制学习:2. 配置Active Standby Pair ,确保三个库的状态分别为ACTIVE, STANDBY和IDLE;以及复制传输策略为TWOSAFE。

master1> call ttrepstop; <- 停止active数据库上的复制代理,模拟其失效;

master2> call ttRepStateSet('ACTIVE');
master2> call ttRepStateGet;
< ACTIVE, NO GRID >
1 row found.

其实如果不停止,若强制把standby提升为ACTIVE,之前的active也会自动变为STANDBY。
[oracle@timesten-hol ~]$ ttRepAdmin -duplicate -from master2 -host $(hostname) -uid repadmin -pwd timesten master1

master1> call ttrepstart;
master1> call ttrepstateget;
< STANDBY, NO GRID > <-之前的active数据库自动变为standby
1 row found.

master1> call ttrepstateget;
< STANDBY, NO GRID >

下略


恢复到先前的节点

前述当active失效时,standby接管称为新的active,过程称为failover,如果需要failback,可以参见后面一节:对调active和standby数据库的角色

从standby数据库的错误中恢复

检测到standby故障

如果是TWOSAFE模式,standby故障将影响active数据库交易的提交,这时可以使用ttRepSyncSet( null, null, 2)设置本地提交。

在active数据库中调用ttRepStateSave(‘FAILED’,’standby_database’,’host_name’)将standby标记为失效。此时active接管了向subscriber的复制任务

禁止standby数据库复制代理的自动启动(如果设置了的话)

连接到standby数据库启动自动恢复,如果恢复失败,则从active克隆

启动standby数据库的复制代理

实验如下:

master2> call ttrepstop; <- 模拟standby故障

master1> call ttRepStateSave('FAILED','master2','timesten-hol');

master1> @insert1

INSERT INTO employees VALUES
( 202,
'Pat',
'Fay',
'PFAY',
'603-123-7777',
TO_DATE('17-AUG-1997', 'dd-MON-yyyy'),
'MK_REP',
6000,
NULL,
201,
20
);
1 row inserted.

此时standby失效,active接管了向subscriber复制的任务

subscriber1> @s

select * from employees;
< 202, Pat, Fay, PFAY, 603-123-7777, 1997-08-17 00:00:00, MK_REP, 6000, <NULL>, 201, 20 >
1 row found.

恢复standby
master2> call ttrepstart;
master2> call ttrepstateget;
< STANDBY, NO GRID >
1 row found.

master1> @insert2

确认master2和subscriber都接收到了数据。


active和standby数据库同时错误时的恢复

称为dual failure或double failure。如以下的情形:

* standby失效,在standby恢复前或standby与active完全同步前,active又失效

* active失效,standby变为active,然后在恢复过程完成前,新的active又试失效

在两种情形中,subscriber都比standby具有更新的数据。

可以选择从active恢复,或从standby恢复,取决于哪个库的数据最新。

从active数据库恢复

连接到失效的active,触发自动恢复

确认复制代理已启动

设置角色为ACTIVE。(ttRepStateSet(‘ACTIVE’))

接下来介绍克隆等操作了

从standby数据库恢复(此处没有读懂)

连接到失效的standby,触发自动恢复

确保复制代理未启动

删除复制配置(DROP ACTIVE STANDBY PAIR)

重新创建复制配置(CREATE ACTIVE STANDBY PAIR)

ttRepStateSet(‘ACTIVE’)设置master数据库的角色为active

在新的standby上启动复制代理

从subscriber数据库的错误中恢复

比较简单,可以有两种方法:

1. 连接subscriber数据库,让其自动从日志恢复,然后自动与其源数据库同步

2. 重新从standby克隆到subscriber,如果standby不可用,则从active克隆

对调active和standby数据库的角色

通常用于failover之后的failback,步骤如下:

1. 停止应用对数据库的更新

2. 调用ttRepSubscriberWait 确保所有active数据库的更新已同步到standby。也即两个数据库是完全同步的(返回值为0x00)

3. 停止active数据库的复制代理

4. 在active数据库调用ttRepDeactivate,将数据库状态置为IDLE

5. 调用
ttRepStateSet('ACTIVE')
将standby角色提升为ACTIVE

6. 在之前的active数据库中启动复制代理

7. 调用
ttRepStateGet
确认之前的active数据库的状态变为STANDBY

8. 恢复应用

测试如下:

master2> call ttRepSubscriberWait(NULL, NULL, 'master1', 'timesten-hol', 10);
< 00 >
1 row found. <- 从master2到master1的复制完全同步

说明:对于ASP复制,前面两个参数设成NULL即可,因为ASP复制只有一个DataStore级别的复制schema,即_ACTIVESTANDBY,owner是TTREP。

Command> SELECT REPLICATION_NAME, REPLICATION_OWNER FROM TTREP.REPLICATIONS;
< _ACTIVESTANDBY                 , TTREP                           >
1 row found.

master2> call ttrepstop;
master2> call ttRepDeactivate;
master2> call ttRepStateGet;
< IDLE, NO GRID >
1 row found.

master1> call ttRepStateSet('ACTIVE');
master1> call ttRepStateGet;
< ACTIVE, NO GRID >
1 row found.

master2> call ttRepStart;
master2> call ttRepStateGet;
< IDLE, NO GRID >
1 row found.
master2> call ttRepStateGet;
< STANDBY, NO GRID >
1 row found.

master1> @insert1
master1> select count(*) from employees;
< 2 >
1 row found.

确认master2和subscriber1上的数据条数也是为1


检查双active数据库

dual active和网络中断导致的split brain很类似,会造成数据的不一致。

以下我们模拟以下dual active的场景, 假设之前有一个正常运作的ASP:

master2> call ttrepstop;
master2> call ttrepstateset('active');
master2> call ttrepstateget;
< ACTIVE, NO GRID >
1 row found.

master1> call ttrepstateget;
< ACTIVE, NO GRID >
1 row found.

此时,两个库的状态都是ACTIVE,更危险的是,两个库还都可以更新

master1> @insert1

INSERT INTO employees VALUES
( 202,
'Pat',
'Fay',
'PFAY',
'603-123-7777',
TO_DATE('17-AUG-1997', 'dd-MON-yyyy'),
'MK_REP',
6000,
NULL,
201,
20
);
1 row inserted.
master1> @s

select * from employees;
< 202, Pat, Fay, PFAY, 603-123-7777, 1997-08-17 00:00:00, MK_REP, 6000, <NULL>, 201, 20 >
1 row found.

master2> @insert2

INSERT INTO employees VALUES
( 203,
'Judy',
'Fox',
'JFOX',
'603-123-7777',
TO_DATE('17-AUG-1997', 'dd-MON-yyyy'),
'MK_REP',
6000,
NULL,
201,
20
);
1 row inserted.
master2> @s

select * from employees;
< 203, Judy, Fox, JFOX, 603-123-7777, 1997-08-17 00:00:00, MK_REP, 6000, <NULL>, 201, 20 >
1 row found.


当网络恢复后,TimesTen会自动的判断哪个数据库比较新,由于我们的例子中,standby即master2是最后插入数据的,因此其保留ACTIVE的状态。

不是最新的数据库被置为无效,并且所有的连接被端口。当重新连接此standby时,如果其上没有未复制到对方的交易,那么其就自动成为STANDBY;如果存在未复制的交易,如我们以下的例子,则其状态被置为IDLE。或者你放弃掉此数据,然后从active数据库克隆,或者先手工补齐此数据,然后再从active数据库克隆。

master2> call ttrepstart;
master2> call ttrepstateget;
< ACTIVE, NO GRID >
1 row found.

master1> call ttrepstateget;
994: Data store connection terminated. Please reconnect.
The command failed.

disconnect master1;
Disconnecting...
[oracle@timesten-hol ~]$ ttisql master1
Command> call ttrepstateget;
< IDLE, NO GRID >
1 row found.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息