前几天大家讨论一个问题,oracle 11g dataguard分为哪几种,本来只想到还是物理standby和逻辑standby2种,没想到今天在查阅了oracle 11g的在线文档后发现,实际上载oracle 11g中已经分了三种类型的standby,当然以前听说oracle 11g支持叫做active standby的功能,仔细研究后发现只不过是一种在只读模式下就可以应用恢复,这样在很多设计中可以将备库来做一些报表功能,减少主库的查询带来的一些负载和性能问题,当然这个功能其实也不是什么新技术了,早在informix 7的HDR就做到了,看来相对来说,oracle在这块的功能也比较滞后了些,同时我发现每种数据库其实存在都是因为有其先进的技术独到之处,informix之所以能够在顶住即将被淘汰的命运大环境下顽强生存到现在,并且本来原厂打算放弃,但是在用户的继续坚持下,IBM终究还是妥协,继续进行发展的承诺,更是说明了这一点,下面就继续来看看oracle 11gdata guard的三种类型并且适用的常见。
Standby数据库类型分为三类:物理Standby、逻辑Standby和快照standby
1.物理Standby
物理Standby与Primary数据库在物理数据库磁盘上具有主库相同架构的块与块级别主库的物理copy,DG通过REDO应用来维护物理Standby数据库。通常在物理Standby没有执行REDO应用操作的时候,可以将物理Standby数据库以READ ONLY模式打开,如果数据库中指定了Flashback Area的话,甚至还可以被临时性的置为READ WRITE模式,操作完之后再通过Flashback Database特性恢复回READ
WRITE前的状态,以便继续接收Primary端发送的REDO并应用。物理Standby通过REDO应用来保持与Primary数据库的一致性,所谓的REDO应用,实质是通过Oracle的恢复机制,应用归档文件(或Standby Redologs文件)中的REDO数据。恢复操作属于块对块的应用。如果正在执行REDO应用的操作,Oracle数据库就不能被Open。
Oracle 11g版本中增强物理Standby的应用功能,在11g版本中,物理Standby可以在OPEN READ ONLY模式下继续接收和应用primaru库产生的REDO数据,这就极大地提升了物理Standby数据库的应用场合。
如果以READ WRITE模式打开,那么Standby数据库将暂停从Primary数据库接收REDO数据,并且暂时失去灾难保护的功能。当然,以READ WRITE模式打开也并非一无是处,如你可能需要临时调试一些数据,但又不方便在正式库中操作,那就可以临时将Standby数据库置为READ WRITE模式,操作完之后将数据库闪回到操作前的状态(闪回之后,Data Guard会自动同步,不需要重建物理Standby,不过如果从另一个方向看,没有启动闪回,那就回不到READ WRITE前的状态了)。
物理Standby特点如下:
(1)灾难恢复及高可用性。物理Standby提供了一个健全、高效的灾难恢复,以及高可用性的解决方案。更加易于管理switchover/failover角色转换及在更短的计划内或计划外停机时间。
(2)数据保护。使用物理Standby数据库,DG能够确保即使面对无法预料的灾害也能够不丢失数据。前面也提到物理Standby是基于块对块的复制,因此与对象、语句无关,Primary数据库上有什么,物理Standby数据库端也会有什么。
(3)分担Primary数据库压力。通过将一些备份任务、仅查询的需求转移到物理Standby数据库,可以有效节省Primary数据库的CPU及I/O资源。
(4)提升性能。物理Standby所使用的REDO应用技术使用最底层的恢复机制,这种机制能够绕过SQL级代码层,因此效率最高。
2.逻辑Standby
逻辑Standby也要通过Primary数据库(或其备份,或其复制库,如物理Standby)创建,因此在创建之初与物理Standby数据库类似。不过由于逻辑Standby通过SQL应用的方式应用REDO数据,因此逻辑Standby的物理文件结构,甚至数据的逻辑结构都可以与Primary不一致。与物理Standby不同,逻辑Standby正常情况下是以READ WRITE模式打开,用户可以在任何时候访问逻辑Standby数据库,就是说逻辑Standby是在OPEN状态执行SQL应用。同样有利也有弊,由于SQL应用自身特点,逻辑Standby对于某些数据类型及一些DDL/DML语句会有操作上的限制。可以在视图DBA_LOGSTDBY_UNSUPPORTED
中查看不支持的数据类型,如果使用了这种数据类型,则不能保证数据库完全一致。
逻辑Standby 的读写打开可以使它做报表系统,这样减轻系统的压力。
除了上述物理Standby中提到的类似灾难恢复、高可用性及数据保护等特点之外,逻辑Standby还有下列一些特点:
(1)有效地利用备机的硬件资源。除灾难恢复外,逻辑Standby数据库还可用于其他业务需求。如通过在Standby数据库创建额外的索引、物化视图等提高查询性能并满足特定业务需要;又如创建新的SCHEMA(该SCHEMA在Primary数据库端并不存在),然后在这些SCHEMA中执行那些不适于在Primary数据库端执行的DDL或者DML操作等。
(2)分担Primary数据库压力。逻辑Standby数据库可以在保持与Primary同步时仍然置于打开状态,这使得逻辑Standby数据库能够同时用于数据保护
和报表操作,从而将主数据库从报表和查询任务中解脱出来,节约宝贵的 CPU和I/O资源。
(3)平滑升级。可以通过逻辑Standby来实现如跨版本升级,为数据库打补丁等操作。应该说应用的空间很大,而带来的风险却很小(前提是如果你拥有足够的技术实力。另外虽然物理Standby也能够实现一些升级操作,但如果跨平台的话恐怕就力不从心了,所以此项没有作为物理Standby的特点列出),我个人认为这是一种值得可行的在线的滚动的平滑的升级方式,如果你的应用支持创建逻辑Standby的话。
3.快照standby
一个快照standby数据库就是一个完全可更新的standby数据库,就像一个物理或者逻辑standby数据库,一个快照standby数据库从主库接收和归档redo数据。但是不像物理standby或者逻辑standby数据库会应用它所接收的redo数据。通过快照standby接收的redo数据不会被应用直到在首次放弃任何本地更新操作后被转化还原为一个物理standby数据库。
snapshot standby被使用在需要一个临时,可更新物理standby的快照的场景,注意因为redo数据只会被快照standby数据库接收但是不会被应用,直到被转化为一个物理standby数据库,而从一个主库恢复的故障时间和需要被应用的redo数据的数据量成正比。
============================================
Oracle 专家QQ群:60632593、60618621、23145225
一、问题情景:
原SQL:
select c.CATEGORY_ID,
c.CATEGORY_NAME,
SYS_CONNECT_BY_PATH(c.CATEGORY_NAME, '/') PATH
from TBL_CATEGORY_PATH c
start with c.CATEGORY_ID = 0
connect by c.PARENT_NODE_ID =prior c.NODE_ID
在执行上述SQL语句时,Oracle报错误 ORA-30004,具体如下图:
二、分析:
错误提示的含义是:当使用SYS_CONNECT_BY_PATH 函数时,不能将分隔符作为字段值的一部分。
根据此含义,猜测是否某条记录的该字段内容包含有我们的分割符“/”。据此思路,检查了所有记录的“CATEGORY_NAME”字段内容,确实发现了有一条记录该字段内容就包含了“/”。
三、最简单的办法是改用其他的分割符号就可以。
select c.CATEGORY_ID,
c.CATEGORY_NAME,
SYS_CONNECT_BY_PATH(c.CATEGORY_NAME, '||') PATH
from TBL_CATEGORY_PATH c
start with c.CATEGORY_ID = 0
connect by c.PARENT_NODE_ID = c.NODE_ID
rollup(字段1,字段2):
cube(字段1,字段2):
rollup(col1, col2,...) 和 cube(col1, col2,...) 用法区别在 cube 在 rollup 汇总的记录集上,还会增加对 col2 等字段的汇总;
ROLLUP只对第一个参数(字段)进行汇总,CUBE可以对参数(字段)依次汇总,所以ROLLUP中参数个数只有一个会起作用(且排名在前的参数)。
Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句。
ROLLUP(A, B, C):
首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。
CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP BY操作。
CUBE 和 ROLLUP 之间的区别在于:
CUBE 生成的结果集显示了所选列中值的所有组合的聚合。
ROLLUP 生成的结果集显示了所选列中值的某一层次结构的聚合。
例子:
create table student( cgrade varchar2(64), cclass varchar2(64), cgroup varchar2(64), stu int )
insert into student(cgrade,cclass,cgroup,stu) values('1','1','1',10); insert into student(cgrade,cclass,cgroup,stu) values('1','2','1',10); insert into student(cgrade,cclass,cgroup,stu) values('1','2','2',20); insert into student(cgrade,cclass,cgroup,stu) values('2','1','1',30); insert into student(cgrade,cclass,cgroup,stu) values('2','2','2',40);
select * from student;
select cgrade,cclass,sum(stu) from student group by cgrade,cclass;
select cgrade,cclass,sum(stu) from student group by cube(cgrade,cclass);
select decode(grouping(cgrade),1,'学校人数',0,cgrade),decode(grouping(cclass)+grouping(cgrade),1,'年级人数',0,cclass),sum(stu) from student group by rollup(cgrade,cclass);