oracle 11g standby query error: ora-08103 and ora-01410

September 3, 2008 – 11:55 am

范鑫做的测试,我转过来。看起来很简单的一件事情,由于具有偶然性,不能每次都重现,所以特地记录下来,一直报的 ORA-08103: object no longer exists 是由于 standby 上的查询进程导致 ,把standby 激活后查询就正常了

当然这里要交代一下前提,就是在主数据库上有一个job,每天晚上将一个表truncate再插入数据,第二天就发现standby上查询错误,在主数据库上move表之后恢复正常。 但是手工做 truncate却取法重现,重新做个job任务偶尔重现,也不是一定得到这个现象。目前正在进一步测试中,但至少发现了 11g的 standby提供适时查询功能是存在缺陷的。当然不truncate就没问题。

测试在一个已经存在问题的standby上进行,先以standby模式open,再open read only,最后激活open:

 

oracle@ctr_db1:/home/oracle>export ORACLE_SID=testctrdmsb2

oracle@ctr_db1:/home/oracle>sqlplus /nolog

 

SQL*Plus: Release 11.1.0.6.0 - Production on Wed Sep 3 10:28:45 2008

 

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

 

@>

@>sqlplus /nolog

SP2-0734: unknown command beginning “sqlplus /n…” - rest of line ignored.

@>conn / as sysdba

Connected.

sys@CTRDM_DB1>

sys@CTRDM_DB1>select count(*) from mcc.sync_job_status;

select count(*) from mcc.sync_job_status

                         *

ERROR at line 1:

ORA-01410: invalid ROWID

 

 

sys@CTRDM_DB1>select count(*) from mcc.testd2;

 

  COUNT(*)

———-

      1127

 

sys@CTRDM_DB1>

sys@CTRDM_DB1>

sys@CTRDM_DB1>

sys@CTRDM_DB1>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

sys@CTRDM_DB1>startup mount;

ORA-32004: obsolete and/or deprecated parameter(s) specified

ORACLE instance started.

 

Total System Global Area 2004340736 bytes

Fixed Size                  2145744 bytes

Variable Size             402653744 bytes

Database Buffers         1593835520 bytes

Redo Buffers                5705728 bytes

Database mounted.

sys@CTRDM_DB1>alter database open ;

 

Database altered.

 

sys@CTRDM_DB1>select count(*) from mcc.sync_job_status;

select count(*) from mcc.sync_job_status

                         *

ERROR at line 1:

ORA-08103: object no longer exists

 

 

sys@CTRDM_DB1>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

sys@CTRDM_DB1>startup mount;

ORA-32004: obsolete and/or deprecated parameter(s) specified

ORACLE instance started.

 

Total System Global Area 2004340736 bytes

Fixed Size                  2145744 bytes

Variable Size             402653744 bytes

Database Buffers         1593835520 bytes

Redo Buffers                5705728 bytes

Database mounted.

sys@CTRDM_DB1>alter database open read only;

 

Database altered.

 

sys@CTRDM_DB1>select count(*) from mcc.sync_job_status;

select count(*) from mcc.sync_job_status

                         *

ERROR at line 1:

ORA-08103: object no longer exists

 

 

sys@CTRDM_DB1>

sys@CTRDM_DB1>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

sys@CTRDM_DB1>

sys@CTRDM_DB1>

sys@CTRDM_DB1>

sys@CTRDM_DB1>startup mount;

ORA-32004: obsolete and/or deprecated parameter(s) specified

ORACLE instance started.

 

Total System Global Area 2004340736 bytes

Fixed Size                  2145744 bytes

Variable Size             402653744 bytes

Database Buffers         1593835520 bytes

Redo Buffers                5705728 bytes

Database mounted.

sys@CTRDM_DB1>alter database open;

 

Database altered.

 

sys@CTRDM_DB1>select count(*) from mcc.sync_job_status;

 

  COUNT(*)

———-

        25

 

sys@CTRDM_DB1>

 

如何恢复被删除的表空间?

September 2, 2008 – 1:19 pm

前几天看到论坛上有人问,看到大家都是纸上谈兵,我做了个example。

下载地址:
删除表空间恢复.pdf

学习latch笔记

August 31, 2008 – 3:17 pm

<!– @page { size: 21cm 29.7cm; margin: 2cm } P { margin-bottom: 0.21cm } –>

个人认为科学技术之间存在一定的相关性的,先举一个例子,来比较浅显的了解一下latch的一些特点。下图为一张十字路口照片,来来往往的车辆就是靠十字路口的一个交通信号灯来指挥的,当然有时候也会有按照交通警察的指令来执行。

<!– @page { size: 21cm 29.7cm; margin: 2cm } P { margin-bottom: 0.21cm } –>

中国的交通,十字路口有交通信号灯,信号灯周期性的变化。当东西直行的信号灯是绿的时,东西方向的汽车可以行走,此时南北方向的车需要等待;当南北方向的信号灯是绿的时候,南北方向的车是可以行走的,东西方向的车要等待。当一个方向为绿灯时另一个方向一定是红灯,除非线路故障。看到这个图,我突然想到和latch很有一比,到底有多少呢,让我们一起看看下面几个问题:

1、那么信号灯是起一个什么作用呢?

告诉行使的车里和行人你能不能通过十字路口。

2、汽车等待的是什么?

汽车在等待交通信号灯变成绿色,这样可以通过。

3、汽车是使用信号灯呢还是使用十字路口的那一块马路呢?

汽车得到绿色信号灯之后,会立即行使通过路口,他使用的就是那一个马路。

4、 同时得到这个绿色信号灯的是不是不仅仅一辆车?

同时看到绿灯的车辆有很多,并发的比较多。

5、信号灯变化时间越长是不是就堵的更严重?

信号灯的时间越长,导致一次等待的时间过长,押车的长度会变长,通过路口的速度要明显小于正常形式的速度,这样导致车会越来越多的堵在路上。

6、是不是有的车得不到中间的道路资源他就不等待信号灯而直接右柺呢?

有些车辆在直行的时候没有得到绿灯,他们还有别的方向可以选择,就会右转来直接走掉

7、是不是车辆的个头越大,同时通过路口的车辆就越少?

一次占用整个车道,那岂不是要让后边的车没法通过?

8、当一辆车在一次信号灯没有通过路口时,是不是继续等待,下一次绿色信号灯亮的时候是不是他第一时间可以通过?

当一次绿灯正好没有通过路口,下一次绿灯到来的时候他就可以比较迅速的得到绿灯信号,而快速通过。

发现交通信号灯这个设计很有意思,和oraclelatch很像,不知道是谁学习的谁.

  • Latch到底是什么呢?

是能不能独自访问或执行某一种共享资源的信号灯。从程序上来讲就是一个变量,标记了某个资源的一个状态。

Latch有三种类型,父latch,子latch,独立latch。其中,在v$latch_parent这个表中存放的是独立latch和父latch,每一个latch存放一条记录。子latch放在 v$latch_children表中,每个子latch存放一条记录,只有少数的latch有子latch,所以在v$latch_children表中,其latch name是一样的,但是其地址不一样,表明他保护block不想同。在v$latch表中,保存了所有的latch的聚合信息,在这里能看到宏观的latch信息,在v$latch_children中可以看到微观的每个latch的信息。

根据概念理解,对于共享的数据结构都是需要使用latch进行保护的,有些数据结构使用一个latch有些数据结构使用多个latch(子latch),多个latch的使用可以增加并发度,因为不用访问一个资源而占用了整个链表的latchlatch的访问是独享的

<!– @page { size: 21cm 29.7cm; margin: 2cm } P { margin-bottom: 0.21cm } –>

看了latch的概念,那么进程如何得到latch呢?

进程得到latch的方式:willing-to-waitno_wait两种方式:

Willing-to-wait方式是请求一个latch如果一次请求没有获得,然后又有经过spintry again经过多次的spin_SPIN_COUNT如果还没有得到latch则进入到sleep状态,进入sleep前,它需要先安排一下他的后事,不能一睡不起呀(如何醒来,超时和repost,还有就是通知v$session_wait自己发生了latch free wait,从这里可以知道,每次sleep都会对应着一个latch free wait eventspin也可以称之为active waitcpu时间片该进程还没有消耗完毕,那么这样进程还是在消耗cpu时间的。这样的方式请求的latch的(level)级别要比自己持有的高才可以,为什么呢?如果a进程占有一个level 5latch,它去请求一个level3latch,而进程b,占有这个level3latch,又去请求那个level 5latch,这样会有什么问题呢?因为它是可以去spin的,又是可以去sleep的,sleep之后还是继续重复?那就永远没有完没有了了。所以呢,levelrequest是有level顺序的,不能随便的请求。

为什么要spin呢?spin是对于多cpu系统而言的,一个cpu是没有必要的,因为,spin是一个进程在cpu时间片内等待一个latch,它会让spin进程去其他的cpupin一下,如果有其他的进程释放了该latch,那么就可以得到了,又因为一个cpu,在一个时刻只能处理一个进程,进程切换的代价又很高,要建立上下文环境,所以尽量在cpu没有切换的时候能得到latch最好。Spin的次数也是有一个参数来指定的,_SPIN_COUNT,文档上有一个公式说

_SPIN_COUNT * sleeps / misses 的值越小越好,但是我没有明白过来,请大牛们解释一下。

v$latch中,有getsmisses。那么gets是什么意思呢?gets是进程通过willng-to-wait得到的latch的次数,misseswilling-to-wait模式并且没有pin也没有得到latch的次数。那么经过多次的spin得到latch计作一个gets,经过多次spin没有的到latch,那就是sleep了。

Sleepwilling-to-wait模式请求latch失败了,然后就要去sleepsleep要去告诉v$session_waitV$SYSTEM_EVENT发生了latch free 等待事件。Sleep之后还是要醒来的,要么是闹钟(超时),要么就是告诉别人叫他一下(repost)。Sleep醒来之后,其下次的sleep时间要变长的,不知道为什么,睡得越多,每次睡眠的时间就越长(2s),但是当一个进程持有latch的时候睡眠的时间会很短(4厘秒)。1=1000毫秒(ms)1毫秒=11,000(s) 1=1,000,000 微秒(μs) 1微秒=11,000,000(s) 1=1,000,000,000 纳秒(ns) 1纳秒=11,000,000,000(s) 1=1,000,000,000,000 皮秒(ps) 1皮秒=11,000,000,000,000(s)

在上面看来,latch如果出现sleeps比较多,造成的影响是比较严重,因为每次request latch都会耗用cpu时间,sleep说明了白白浪费了cpu时间,这样会造成资源的浪费。

No_wait方式去请求一个latch,有两种情况:1、他请求的latch有多个类型相同的latch可以请求,会先请求一个,如果得不到,就请求下一个同样的latch,如果都扫描了一遍,还是没有得到,则转入willing-to-wait2、请求的latch级别与请求的相同或者低的时候,因为他有deadlock保护,所以可以。

No_wait方式在v$latch的记录为:IMMEDIATE_GETS IMMEDIATE_MISSES

Latchcleanup,在latch的使用过程中,可能会出现一些异常,而导致有些latch被异常占有得不到释放,这样就会有问题了,别的进程过来请求不到。出现这样的异常pmon进程会跟进处理,对于其处理的流程来说,最重要的莫过于将没有提交的事物回滚,那么就需要latch支持恢复,那么latch在开始操作前会先写一些信息去latch的恢复区。Pmon 3秒钟会自动运行一下,但是这也使很长的一段时间了,所以在进程在请求一个latch失败多次之后,会post pmon进程去check一下占有这个latchprocess是不是正常。

Spingetsmissessleepcleanup

Spin是对于多cpu系统而设计的,目的是为了能够尽量不发生进程交换的情况下得到latch,该进程去查看别的cpu有没有释放其需要的latch如果能得到就可以在一次cpu时间内处理完事情,多好呀。

Gets willing-to-wait模式的not spinspin(不论一次还是多次spin)的gets

Misses willing-to-wait fail to get without spin

Sleep 在一次cpu时间内没有得到latch,就会睡眠

IMMEDIATE_GETSno_wait模式的get

IMMEDIATE_MISSESno_wait模式的miss

Cleanup 占有latch的进程出现异常,需要PMON进行清理,以免长期占有latch。在进程得到latch之后需要先将恢复数据写到恢复区,保证出现异常之后能够正常恢复。

  • 查看latch的视图:

1select latch#, name from v$latchname

可以看到latch的名字

2、Select total_waits from v$system_event where event=‘latch free’;

2、Select sum(sleeps) from v$latch;

上面这两个的结果实一样的。

3、select name, gets, misses, immediate_gets, immediate_misses, sleeps from v$latch order by sleeps;

4select * from (SELECT file#, dbablk, class, state, TCH FROM X$BH b,v$latch_children lc WHERE b.HLADDR=lc.addr order by TCH desc) where rownum<=10;

sql可以查询一下hot block,其中 TCH touch count header? 该值大,说明了被访问的次数相当多。X$bh中的HLaddr就是说的在block头的latch地址,正好是v$latch_childrenaddr

MySQL MyIsam 存储引擎索引长度限制测试记录

August 17, 2008 – 5:51 pm

MySQL MyIsam 存储引擎在创建索引的时候,索引键长度是有一个较为严格的长度限制的,所有索引键最大长度总和不能超过1000,而且不是实际数据长度的总和,而是索引键字段定义长度的总和。下面做个简单的测试,记录一下。

root@sky:~# mysql -u sky -p -h127.0.0.1
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 44
Server version: 5.0.51a-log MySQL Community Server (GPL)

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.

sky@127.0.0.1 : (none) 05:23:08> use test;
Database changed
sky@127.0.0.1 : test 05:23:11>
sky@127.0.0.1 : test 05:23:12>

先创建一个MyIsam表,字符集选择latin1,三个字段均设置为varchar 255,:
sky@127.0.0.1 : test 05:23:12> create table test_ind
-> (a varchar(255),
->  b varchar(255),
->  c varchar(255)
-> ) engine=myisam charset=latin1;
Query OK, 0 rows affected (0.01 sec)

创建效果:
sky@127.0.0.1 : test 05:23:32> show create table test_ind\G
*************************** 1. row ***************************
Table: test_ind
Create Table: CREATE TABLE `test_ind` (
`a` varchar(255) default NULL,
`b` varchar(255) default NULL,
`c` varchar(255) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

三个字段联合索引(长度应该在1000以内)

sky@127.0.0.1 : test 05:23:41> create index test_a_b_c_ind on test_ind(a,b,c);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

我们看到,创建成功了。

下面我们做一次字符集转换,将字符集转换成utf8

sky@127.0.0.1 : test 05:25:54> alter table test_ind convert to charset utf8;
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes
sky@127.0.0.1 : test 05:26:24>
sky@127.0.0.1 : test 05:28:03> show create table test_ind\G
*************************** 1. row ***************************
Table: test_ind
Create Table: CREATE TABLE `test_ind` (
`a` varchar(255) default NULL,
`b` varchar(255) default NULL,
`c` varchar(255) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

结果报错了,查看表实际情况也确实没有成功,仍然是latin1的字符集。

我们现drop掉索引,再转换字符集。

sky@127.0.0.1 : test 05:28:10> drop index test_a_b_c_ind on test_ind;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

sky@127.0.0.1 : test 05:28:15> alter table test_ind convert to charset utf8;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
sky@127.0.0.1 : test 05:28:20> show create table test_ind\G
*************************** 1. row ***************************
Table: test_ind
Create Table: CREATE TABLE `test_ind` (
`a` varchar(255) default NULL,
`b` varchar(255) default NULL,
`c` varchar(255) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
转换很顺利,成功了。

现在再创建索引看看效果怎样:

sky@127.0.0.1 : test 05:28:36> create index test_a_b_c_ind on test_ind(a,b,c);
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes

失败,减少索引键字段
sky@127.0.0.1 : test 05:28:54> create index test_a_b_c_ind on test_ind(a,b);
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes

还是失败,继续减少
sky@127.0.0.1 : test 05:29:00> create index test_a_b_c_ind on test_ind(a);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

ok,总算成功了。

最后再看看其他存储引擎有没有这个限制呢?就看当前用的最广泛的存储引擎之一Innodb吧:

sky@127.0.0.1 : test 05:29:03> drop index test_a_b_c_ind on test_ind;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

sky@127.0.0.1 : test 05:29:54>
sky@127.0.0.1 : test 05:29:58>
sky@127.0.0.1 : test 05:30:11> alter table test_ind engine=innodb;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
sky@127.0.0.1 : test 05:31:15> show create table test_ind\G
*************************** 1. row ***************************
Table: test_ind
Create Table: CREATE TABLE `test_ind` (
`a` varchar(255) default NULL,
`b` varchar(255) default NULL,
`c` varchar(255) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

sky@127.0.0.1 : test 05:31:23> create index test_a_b_c_ind on test_ind(a,b,c);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

很顺利,创建成功,Innodb是没有这个限制的。

敏捷多模式匹配

August 2, 2008 – 10:57 am

业务方一个需求, 要对一个表中某些文本字段进行多模式匹配, 找出含有某个关键词列表中关键词的记录.
为了实现这个需求, 搞了如下的SQL:

select id, result
from
(
select /*+parallel(t 16)*/id,
decode(sign(instr(x,’关键词1′)),1,’关键词1,’,null) ||
decode(sign(instr(x,’关键词2′)),1,’关键词2,’,null) ||
decode(sign(instr(x,’关键词3′)),1,’关键词3,’,null)
as result
from
(
select id as id, col1||’,'||col2 as x
from table1
) t
)
where result is not null
/

说明一下:

1. 输出结果:
 所有包含任意关键词的记录, 输出记录的id和该笔记录中所匹配到的关键词, 也可以根据需要输出其他字段.
 
2. 关键词列表: 把需要扫描的关键词都拼凑到SQL中, 而不是选择存放在一个表中去做表关联.
 这样做是考虑到如果做表关联, instr这样的需求只能走nest loop, 而table1的记录有很大(百万级甚至更高).
 而且关键词数量也不少, 一般是一两千个, 我这里为了便于阅读, 只写了三个.
 这样的情况无论怎么样走nest loop, 逻辑读都非常大.
 
3. 关于并行: 需求紧急, 为了短平快的实现, 我用了并行.
 也正好说说我对并行的理解.
 并行, 其实是利用闲置的数据库服务器资源来换取任务执行的时间.
 如果简单对一个10G级的大表进行全表扫描, 把并行开到32, 存储的吞吐一下子就到了极限.
 而对于上面写的instr的SQL, 把并行度开到16, 则存储很闲, CPU里的user%一下子就到了96,7, 服务器load也到了很高的水平.
 有一次不小心开了两个上面的SQL同时跑, 我有幸看到了三位数的load.
 这样的工作不能在线上数据库做, 只能找一个空闲的非关键的环境来做.
 付出这些代价, 换来的结果还是比较满意的, 任务执行时间平均缩短一半.

关于大数据量模糊查询的方法

July 21, 2008 – 11:39 pm

说实话,在ITPUB上也好,CNOUG上也好,看到很多人问数据模糊查询的问题,特别是一张表的数据量在200M以后,你的查询速度越来越慢。

其实最最简单的就是 like ‘%xx%’,但是这样效率极差,纯粹在拼机器的IO了。

其实在我的日常工作中,对于模糊查询,主要使用以下几种方案提高效率:

A:全文索引

Oracle自带的,SQL SERVER,MYSQL也有这个功能。它的主要实现方式是拆字。记得“玉面飞龙”有一篇文章介绍ORACLE全文索引的,介绍的很详细。

但是全文索引也有很多不足,如:繁体字,孤僻字的支持不好;内部BUG比较多;自身维护的代价和成本很高;新来的开发搞不懂全文索引查询语法;

目前也就少数几个数据库在用全文索引了,打算在不远的将来,将全文索引拿下线了。全部使用Search实现。

B:搜索引擎

其实alibaba集团全部使用的搜索技术,叫“ISEARCH”;100%的知识产权归阿里巴巴所有。

其实在业界最有名的搜索引擎叫“Lunce”,它不仅仅支持JAVA,也支持.NET。

使用搜索最大的好处,它是可以线性扩展的,不像我们的DB。此外我介绍一下搜索引擎大致过程:

数据库有张LOG表,记录变化过的数据》》搜索引擎根据LOG表的数据,DUMP出一份BUILD数据》》把DUMP的东西分发到各个集群》》每台机器再把这个应用到索引文件》》APCHE提供WEB SERVICE给前台

大致过程就这样。至于索引文件本身是个二进制文件。

我觉得搜索引擎本身的实现机制和ORACLE的全文索引类似,也是根据分词器来分词。如果去查找也是根据一个个字Hash mapping出来的,然后根据位置先后次序,找出哪些是符合的。

ASM 磁盘组也可以当成AIX的VG来用

July 21, 2008 – 8:50 am

当多台AIX连接相同的SAN存储时,存储lun可以同时输出到各个主机,这样VG可以在各个主机自由的切换,
为拷贝转移文件提供了极大的便利,现在发现ASM也可以这么做

我们的RAC环境是4个linux接点加一个linux standby
存储输出是4个lun ,disk[1,2,3,4],每个512G,每个lun都同时输出到5台主机,
其中disk1,disk2作为4个RAC接点的共享磁盘,做了裸设备,并创建了asm磁盘组 mydiskgroup
disk3,disk4作为standby的磁盘,也做了asm磁盘组 diskgroupstb

现在rac里面已经导入了点数据,数据库有400G,要做standby,走网络拷贝到备机上感觉太慢了,就试了下上面的想法

1.备机上卸载磁盘组diskgroupstb
@>shutdown immediate;
ASM diskgroups dismounted
ASM instance shutdown

2.4个rac接点的ASM参数文件修改asm_diskstring
@>alter system set asm_diskstring=’/opt/oracle/oradata/myasm/disk[1,2,3,4]‘ scope = spfile;
System altered.

3.重起asm,并挂上diskgroupstb
@>startup force;
ASM instance started

Total System Global Area  283930624 bytes
Fixed Size                  2143704 bytes
Variable Size             256621096 bytes
ASM Cache                  25165824 bytes
ASM diskgroups mounted
@>show parameter string

NAME                                 TYPE        VALUE
———————————— ———– ——————————
asm_diskstring                       string      /opt/oracle/oradata/myasm/disk
                                                 [1,2,3,4]
@>alter diskgroup diskgroupstb mount;

Diskgroup altered.

ASMCMD> ls -l
State    Type    Rebal  Name
MOUNTED  EXTERN  N      DISKGROUPSTB/
MOUNTED  EXTERN  N      MYDISKGROUP/

4.开始备份
alter database create standby controlfile as ‘+DISKGROUPSTB/datafile/control01.ctl’;

run
{
copy datafile ‘+MYDISKGROUP/datafile/system01.dbf’         to ‘+DISKGROUPSTB/datafile/system01.dbf’       ;
copy datafile ‘+MYDISKGROUP/datafile/sysaux01.dbf’         to ‘+DISKGROUPSTB/datafile/sysaux01.dbf’       ;
copy datafile ‘+MYDISKGROUP/datafile/undotbs01.dbf’        to ‘+DISKGROUPSTB/datafile/undotbs01.dbf’      ;
copy datafile ‘+MYDISKGROUP/datafile/undotbs2.dbf’         to ‘+DISKGROUPSTB/datafile/undotbs2.dbf’       ;
copy datafile ‘+MYDISKGROUP/datafile/undotbs3.dbf’         to ‘+DISKGROUPSTB/datafile/undotbs3.dbf’       ;
copy datafile ‘+MYDISKGROUP/datafile/undotbs4.dbf’         to ‘+DISKGROUPSTB/datafile/undotbs4.dbf’       ;
copy datafile ‘+MYDISKGROUP/datafile/tbs_big_test.dbf’     to ‘+DISKGROUPSTB/datafile/tbs_big_test.dbf’   ;
copy datafile ‘+MYDISKGROUP/datafile/tbs_statspack01.dbf’  to ‘+DISKGROUPSTB/datafile/tbs_statspack01.dbf’;
copy datafile ‘+MYDISKGROUP/datafile/tbs_test_sunwg.dbf’   to ‘+DISKGROUPSTB/datafile/tbs_test_sunwg.dbf’ ;
}

两个接点同时做rman,速度大概有300M/S,这个比起网络传输,可是快的多了

5.拷贝完成,RAC接点全部dismount掉diskgroupstb
@>alter diskgroup diskgroupstb dismount;

Diskgroup altered.

6.回到备机,挂上diskgroupstb,standby就可以直接启动了
@>startup;
ASM instance started

Total System Global Area  283930624 bytes
Fixed Size                  2143704 bytes
Variable Size             256621096 bytes
ASM Cache                  25165824 bytes
ASM diskgroups mounted

[oracle@hack5 dbs]$ asmcmd
ASMCMD> ls -l
State    Type    Rebal  Name
MOUNTED  EXTERN  N      DISKGROUPSTB/
ASMCMD> cd DISKGROUPSTB
ASMCMD> ls -l
Type  Redund  Striped  Time             Sys  Name
                                        Y    SWORD/
                                        N    archive/
                                        N    datafile/
ASMCMD> cd datafile
ASMCMD> ls -l
Type         Redund  Striped  Time             Sys  Name
                                               N    control01.ctl => +DISKGROUPSTB/SWORD/CONTROLFILE/Backup.256.660528811
                                               N    sysaux01.dbf => +DISKGROUPSTB/SWORD/DATAFILE/SYSAUX.258.660528931
                                               N    system01.dbf => +DISKGROUPSTB/SWORD/DATAFILE/SYSTEM.257.660528893
                                               N    tbs_big_test.dbf => +DISKGROUPSTB/SWORD/DATAFILE/TBS_BIG_TEST.264.660530865
                                               N    tbs_statspack01.dbf => +DISKGROUPSTB/SWORD/DATAFILE/TBS_STATSPACK.265.660532623
                                               N    tbs_test_sunwg.dbf => +DISKGROUPSTB/SWORD/DATAFILE/TBS_TEST_SUNWG.260.660529175
                                               N    undotbs01.dbf => +DISKGROUPSTB/SWORD/DATAFILE/UNDOTBS1.259.660528967
                                               N    undotbs2.dbf => +DISKGROUPSTB/SWORD/DATAFILE/UNDOTBS2.261.660529203
                                               N    undotbs3.dbf => +DISKGROUPSTB/SWORD/DATAFILE/UNDOTBS3.262.660530331
                                               N    undotbs4.dbf => +DISKGROUPSTB/SWORD/DATAFILE/UNDOTBS4.263.660530599
ASMCMD>
alter database add standby logfile group 17 ‘+DISKGROUPSTB/datafile/redostb01.log’ size 512M;
alter database add standby logfile group 18 ‘+DISKGROUPSTB/datafile/redostb02.log’ size 512M;
alter database add standby logfile group 19 ‘+DISKGROUPSTB/datafile/redostb03.log’ size 512M;
alter database add standby logfile group 20 ‘+DISKGROUPSTB/datafile/redostb04.log’ size 512M;

@>ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;
Database altered.
@>ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
Database altered.
@>ALTER DATABASE OPEN READ ONLY;
Database altered.
@>ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;
Database altered.

Oracle 11G RAC环境的load balance + TAF配置

July 14, 2008 – 12:02 pm

一.客户段的load balance + TAF
sword =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack1-vip)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack2-vip)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack3-vip)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack4-vip)(PORT = 1521))
    (LOAD_BALANCE = yes)
    (FAILOVER = ON)
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = sword.db.alibaba.com)
      (FAILOVER_MODE =
        (TYPE = SESSION)
        (METHOD = BASIC)
      )
    )
  )

LOAD_BALANCE = yes表示程序走sword连接的时候,将在下面4个地址里面随机的选择一个,达到接点间连接均匀
failover表示开启TAF(Transparent Application Failover)特性,其中TYPE = SESSION表示当一个连接好的会话
的实例发生故障,系统会自动将会话切换到其他可用的实例,前台应用无须再度发起连接,但会话正在执行的SQL
需要重新执行,METHOD = BASIC表示初始连接就连接一个接点,他还有个选项是preconnect,表示初始连接所有的
接点,在failover的时候可以很快就切过去,这个基本是资源浪费

二.服务器端的负载平衡
1.listener.ora文件里面配置
LISTENER_SWORD_HACK<n> =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
      (ADDRESS = (PROTOCOL = TCP)(HOST = hack<n>-vip)(PORT = 1521)(IP = FIRST))
      (ADDRESS = (PROTOCOL = TCP)(HOST = hack<n>-priv)(PORT = 1521)(IP = FIRST))
    )
  )
 
2.tnsnames.ora文件里面加入
LISTENERS_SWORD =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack1-vip)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack2-vip)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack3-vip)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack4-vip)(PORT = 1521))
  )
 
3.各个实例修改remote_listener参数
alter system set REMOTE_LISTENER = ‘LISTENERS_SWORD’ scope=both sid=’sword1′;
alter system set REMOTE_LISTENER = ‘LISTENERS_SWORD’ scope=both sid=’sword2′;
alter system set REMOTE_LISTENER = ‘LISTENERS_SWORD’ scope=both sid=’sword3′;
alter system set REMOTE_LISTENER = ‘LISTENERS_SWORD’ scope=both sid=’sword4′;

服务器段的负载均衡主要是通过REMOTE_LISTENER参数控制的,在连接被定位到某个接点后,系统会根据REMOTE_LISTENER
考虑多个接点的负载(主机load是个很重要的参考标准),把连接再次分发出去,这个和客户段的load balance是可以结合
在一起混合使用的,互不干扰

三.连接RAC数据库
[oracle@hack2 admin]$ sqlplus system/sg6n9ol0ij117@sword
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Jul 14 10:29:33 2008
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
Enter password:
ERROR:
ORA-12520: TNS:listener could not find available handler for requested type of server

如果出现ORA-12520错误,应该是oracle的BUG,解决方法是加入local_listener参数控制各个接点service的注册
1.tnsnames.ora文件添加
LISTENER_HACK1 =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack1-vip)(PORT =1521))
  )

LISTENER_HACK2 =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack2-vip)(PORT =1521))
  )

LISTENER_HACK3 =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack3-vip)(PORT =1521))
  )

LISTENER_HACK4 =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = hack4-vip)(PORT =1521))
  )

2.修改各个接点的local_listener参数
alter system set LOCAL_LISTENER = ‘LISTENER_HACK1′ scope=both sid=’sword1′;
alter system set LOCAL_LISTENER = ‘LISTENER_HACK2′ scope=both sid=’sword2′;
alter system set LOCAL_LISTENER = ‘LISTENER_HACK3′ scope=both sid=’sword3′;
alter system set LOCAL_LISTENER = ‘LISTENER_HACK4′ scope=both sid=’sword4′;

3.重新启动listener
lsnrctl start LISTENER_SWORD_HACK<n>

4.连接
[oracle@hack2 admin]$ sqlplus system/sg6n9ol0ij117@sword
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Jul 14 11:50:52 2008
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, Real Application Clusters and Real Application Testing options
SQL> show user
USER is “SYSTEM”

错误详细信息请参考metalink Note:342419.1