在不帶緩存組的ASP中,復制產生在TimesTen的表間;而在帶緩存組的ASP中,復制產生在cache table之間。帶緩沖組的復制僅支持只讀和AWT緩存組。對只讀緩存組,復制的意義在于保持狀態的連續,而對AWT,復制可以保證數據不丟失。
假定active master為cachedb1,standby master為cachedb2
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;
cachedb1> CREATE ACTIVE STANDBY PAIR cachedb1, cachedb2;
cachedb1> call ttRepStateSet('ACTIVE');
cachedb1> call ttRepStateGet;
< ACTIVE, NO GRID >
cachedb1> call ttrepstart;
cachedb1> select * from a;
cachedb1> select * from a where id = 1;
< 1, beijing >
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 ...
$ 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 >
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緩存組, 這時候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失效,以下是緩存組為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.
這類情況比較簡單,由于復制時,數據是先到standby然后在active上提交的。因此很多操作都是自動的。
大不了,從standby升級為active后,再克隆出新的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為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 >
好了,角色換過了了
這個比較簡單,如果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用戶名在Oracle和TimesTen中必須是1樣的,但口令可以不1樣
所以改口令沒甚么特別的,alter user便可。例如
Command> ALTER USER cacheadmin IDENTIFIED BY newpwd;
Command> passthrough 3;
Command> ALTER USER cacheadm IDENTIFIED BY newpwd;
如果改用戶名,就比較麻煩了,必須先刪除掉所有的緩存組,因此不建議。
目前為止,談的都是數據中心內部的HA場景,我們也能夠建立1個位于災備真個subscriber ,在故障時使其成可以繼續與Oracle同步數據,第2個Oracle數據庫也位于災備端。
大致進程以下,由于需要建立第2個Oracle數據庫,這里就不演示了。
http://www.oracledistilled.com/linux/configuring-an-oracle-timesten-logical-server-name-on-unix-based-systems/