程序员人生 网站导航

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

栏目:数据库应用时间:2016-07-15 08:44:42

带缓存组的Active standby pairs(ASP)

在不带缓存组的ASP中,复制产生在TimesTen的表间;而在带缓存组的ASP中,复制产生在cache table之间。带缓冲组的复制仅支持只读和AWT缓存组。对只读缓存组,复制的意义在于保持状态的连续,而对AWT,复制可以保证数据不丢失。

设置带只读缓存组的ASP(例)

假定active master为cachedb1,standby master为cachedb2

  1. 在active上创建dynamic readonly缓存组
cachedb1> CREATE DYNAMIC READONLY CACHE GROUP "RO" AUTOREFRESH MODE INCREMENTAL INTERVAL 5 SECONDS STATE PAUSED FROM "TTHR"."A" ( "ID" NUMBER(38) NOT NULL, "NAME" VARCHAR2(32 BYTE), PRIMARY KEY("ID") ) cachedb1> cachegroups; Cache Group TTHR.RO: Cache Group Type: Read Only (Dynamic) Autorefresh: Yes Autorefresh Mode: Incremental Autorefresh State: Paused <- 确保此状态是paused Autorefresh Interval: 5 Seconds Autorefresh Status: ok Aging: LRU on Root Table: TTHR.A Table Type: Read Only

缓存组的状态必须为paused,否则后续操作会报错,可使用alter cache group命令修改状态

5166: Autorefresh state ON for TTHR.RO is incompatible with replication store state Idle. Autorefresh state should be PAUSED. Alter the autorefresh state and reexecute statement. cachedb1> alter cache group ro set autorefresh state paused;
  1. 创建active standby pair,缺省是异步的传输
cachedb1> CREATE ACTIVE STANDBY PAIR cachedb1, cachedb2;
  1. 设置active数据库的状态为ACTIVE
cachedb1> call ttRepStateSet('ACTIVE'); cachedb1> call ttRepStateGet; < ACTIVE, NO GRID >
  1. 启动复制代理并动态加载1条数据
cachedb1> call ttrepstart; cachedb1> select * from a; cachedb1> select * from a where id = 1; < 1, beijing >
  1. 从active复制出standby, 注意-keepCG选项
cachedb1>create user repadmin identified by timesten; cachedb1> grant admin to repadmin; $ ttRepAdmin -duplicate -from cachedb1 -host $(hostname) -uid repadmin -pwd timesten -keepCG cachedb2 Enter cache administrator UID: cacheadm Enter cache administrator password: oracle Waiting for the Duplicate operation to complete ...
  1. 登录cachedb2,启动缓存和复制代理,状态自动变成STANDBY
$ ttisql -v1 -e "set prompt 'cachedb2> '" "dsn=cachedb2;uid=tthr;pwd=timesten;oraclepwd=oracle" cachedb2> call ttCacheStart; cachedb2> call ttRepStateGet; < IDLE, NO GRID > cachedb2> call ttRepStart; cachedb2> call ttRepStateGet; < STANDBY, NO GRID >
  1. 缓存组的数据已复制到standby,但standby是只读的,不能运行LOAD操作
cachedb2> select * from a; < 1, beijing > cachedb2> select * from a where id = 2; <-只读 8151: TTHR.RO's replication role disallows the requested operation cachedb1> select * from a where id = 2; < 2, shanghai > cachedb2> select * from a; < 1, beijing > < 2, shanghai > <- 可以看到cache group的数据已复制过来 目前1切正常

设置带AWT缓存组的ASP(例)

建立AWT缓存组, 这时候active是cachedb2, standby是cachedb1, 全部进程以下:

cachedb2> CREATE DYNAMIC ASYNCHRONOUS WRITETHROUGH CACHE GROUP "AWT" FROM "TTHR"."A" ( "ID" NUMBER(38) NOT NULL, "NAME" VARCHAR2(32 BYTE), PRIMARY KEY("ID") ) AGING LRU ON cachedb2> cachegroups; Cache Group TTHR.AWT: Cache Group Type: Asynchronous Writethrough (Dynamic) Autorefresh: No Aging: LRU on Root Table: TTHR.A Table Type: Propagate cachedb2> call ttcachestart; cachedb2> CREATE ACTIVE STANDBY PAIR cachedb2, cachedb1; cachedb2> call ttrepstart; cachedb2> call ttrepstateset('active'); cachedb2> call ttrepstateget; < ACTIVE, NO GRID > cachedb2> insert into a values(1, 'beijing'); cachedb2> commit; cachedb2> select * from a; < 1, beijing > $ ttRepAdmin -duplicate -from cachedb2 -host $(hostname) -uid repadmin -pwd timesten -keepCG cachedb1 Enter cache administrator UID: cacheadm Enter cache administrator password: Waiting for the Duplicate operation to complete ... $ ttisql -v1 -e "set prompt 'cachedb1> '" "dsn=cachedb1;uid=tthr;pwd=timesten;oraclepwd=oracle" cachedb1> call ttrepstart; cachedb1> call ttcachestart; cachedb1> call ttrepstateget; < STANDBY, NO GRID > cachedb1> select * from a; < 1, beijing > cachedb1> insert into a values(2, 'shanghai'); 16265: This store is currently the STANDBY. Change to TTHR.A not permitted. cachedb2> insert into a values(2, 'shanghai'); cachedb1> select * from a; < 1, beijing > < 2, shanghai > <- 复制的数据 cachedb1> call ttrepstop; cachedb1> call ttRepStateSet('ACTIVE'); cachedb1> call ttrepstateget; < ACTIVE, NO GRID > cachedb1> call ttRepStateSave('FAILED', 'cachedb2','timesten-hol'); $ ttdestroy cachedb2 $ ttRepAdmin -duplicate -from cachedb1 -host $(hostname) -uid repadmin -pwd timesten -keepCG -recoveringNode cachedb2 $ ttisql -v1 -e "set prompt 'cachedb2> '" "dsn=cachedb2;uid=tthr;pwd=timesten;oraclepwd=oracle" cachedb2> call ttrepstart; cachedb2> call ttcachestart; calcachedb2> call ttrepstateget; < STANDBY, NO GRID > cachedb2> select * from a; < 1, beijing > < 2, shanghai > cachedb2> insert into a values(3, 'guangzhou'); 16265: This store is currently the STANDBY. Change to TTHR.A not permitted. cachedb1> insert into a values(3, 'guangzhou'); cachedb2> select * from a; < 1, beijing > < 2, shanghai > < 3, guangzhou >

active数据库失效时的恢复

当传输模式为return receipt或异步时

停止复制代理来摹拟active失效,以下是缓存组为read-only的情形,如果是AWT,也是类似的

cachedb1> call ttrepstop;

将standby提升为active, 并标记之前的active为失效状态

cachedb2> call ttRepStateSet('ACTIVE'); cachedb2> call ttRepStateSave('FAILED', 'cachedb1','timesten-hol');

这时候新的active可以LOAD数据了

cachedb2> select * from a; < 1, beijing > < 2, shanghai > cachedb2> select * from a where id = 3; < 3, guangzhou >

烧毁原来的active,正常的情况下直接用ttdestroy便可

cachedb1> call ttcachestop; cachedb1> drop active standby pair; cachedb1> drop cache group ro; cachedb1> exit $ ttdestroy cachedb1

重新的active克隆出standby,注意-keepCG -recoveringNode选项

$ ttRepAdmin -duplicate -from cachedb2 -host $(hostname) -uid repadmin -pwd timesten -keepCG -recoveringNode cachedb1 Enter cache administrator UID: cacheadm Enter cache administrator password: Waiting for the Duplicate operation to complete ...

启动standby的复制和缓存代理

$ ttisql -v1 -e "set prompt 'cachedb1> '" "dsn=cachedb1;uid=tthr;pwd=timesten;oraclepwd=oracle" cachedb1> call ttrepstart; cachedb1> call ttcachestart; cachedb1> call ttrepstateget; < STANDBY, NO GRID >

数据已复制到standby,但standby的缓存组不能进行LOAD操作

cachedb1> select * from a; < 1, beijing > < 2, shanghai > < 3, guangzhou > cachedb1> unload cache group ro; 16265: This store is currently the STANDBY. Change to TTHR.A not permitted.

当传输模式为return twosafe时

这类情况比较简单,由于复制时,数据是先到standby然后在active上提交的。因此很多操作都是自动的。
大不了,从standby升级为active后,再克隆出新的standby便可

standby数据库失效时的恢复

如果复制是return twosafe, 以下是缓存组为read-only的情形

CREATE ACTIVE STANDBY PAIR cachedb1, cachedb2 return twosafe cachedb2> unload cache group ro; 8099: TWOSAFE operation not permitted with AutoCommit = 1. cachedb2> set autocommit 0; cachedb2> unload cache group ro; cachedb2> commit; cachedb2> select * from a; cachedb2> select * from a where id = 1; < 1, beijing > cachedb1> call ttrepstateget; < STANDBY, NO GRID > cachedb1> select * from a; < 1, beijing > cachedb1> call ttrepstop; cachedb2> select * from a where id = 2; <- HANG了1会,结果还是出来了, < 2, shanghai > cachedb1> select * from a; < 1, beijing > <- 不过数据自然是不会复制过去的了

如果缓存组为AWT,并且传输模式为return twosafe,这时候会禁止active真个事务提交,这时候需要设置主端:

call ttRepSyncSet( null, null, 2); commit; ttRepStateSave('FAILED','standby_database','host_name') 然后再克隆standby

交换active和standby的角色

假定active为cachedb1,standby为cachedb2 首先停止利用更新数据库。 cachedb1> call ttRepSubscriberWait(NULL, NULL, 'cachedb2', 'timesten-hol', 10); < 00 > <- 返回值必须为00 call ttRepDeactivate(); cachedb1> call ttrepstop; cachedb1> call ttRepDeactivate(); cachedb1> call ttrepstateget; < IDLE, NO GRID > cachedb2> call ttRepStateSet('ACTIVE'); cachedb2> call ttrepstateget; < ACTIVE, NO GRID > cachedb1> call ttrepstart; cachedb1> call ttrepstateget; < IDLE, NO GRID > 过1小会 cachedb1> call ttrepstateget; < STANDBY, NO GRID > 好了,角色换过了了

修改复制的用户名和口令

修改schema user的口令

这个比较简单,如果DDLReplicationLevel 是2,则口令的修改会自动复制到standby。否则就必须手工在每个库中修改。例如:

cachedb2> alter user tthr identified by oracle; User altered. [oracle@timesten-hol ~]$ ttisql -v1 -e "set prompt 'cachedb1> '" "dsn=cachedb1;uid=tthr;pwd=timesten;oraclepwd=oracle" 7001: User authentication failed [oracle@timesten-hol ~]$ ttisql -v1 -e "set prompt 'cachedb1> '" "dsn=cachedb1;uid=tthr;pwd=oracle;oraclepwd=oracle"

修改cache admin 用户的口令

这个实际上是不常见的。
cache admin用户名在Oracle和TimesTen中必须是1样的,但口令可以不1样
所以改口令没甚么特别的,alter user便可。例如

Command> ALTER USER cacheadmin IDENTIFIED BY newpwd; Command> passthrough 3; Command> ALTER USER cacheadm IDENTIFIED BY newpwd;

如果改用户名,就比较麻烦了,必须先删除掉所有的缓存组,因此不建议。

创建灾备用的subscriber

目前为止,谈的都是数据中心内部的HA场景,我们也能够建立1个位于灾备真个subscriber ,在故障时使其成可以继续与Oracle同步数据,第2个Oracle数据库也位于灾备端。

大致进程以下,由于需要建立第2个Oracle数据库,这里就不演示了。

  1. 在主点建立AWT缓存组的ASP
  2. 建立灾备真个Oracle数据库
  3. 在灾备端建立1个subscriber, 这里关键是有1个ttRepAdmin -duplicate的-initCacheDR选项

参考

http://www.oracledistilled.com/linux/configuring-an-oracle-timesten-logical-server-name-on-unix-based-systems/

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐