联机分析处理 (OLAP) 的概念最早是由关系数据库之父E.F.Codd于1993年提出的,他同时提出了关于OLAP的12条准则。OLAP的提出引起了很大的反响,OLAP作为一类产品同联机事务处理 (OLTP) 明显区分开来。
当今的数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。下表列出了OLTP与OLAP之间的比较。
|
OLAP是使分析人员、管理人员或执行人员能够从多角度对信息进行快速、一致、交互地存取,从而获得对数据的更深入了解的一类软件技术。OLAP的目标是满足决策支持或者满足在多维环境下特定的查询和报表需求,它的技术核心是"维"这个概念。
“维”是人们观察客观世界的角度,是一种高层次的类型划分。“维”一般包含着层次关系,这种层次关系有时会相当复杂。通过把一个实体的多项重要的属性定义为多个维(dimension),使用户能对不同维上的数据进行比较。因此OLAP也可以说是多维数据分析工具的集合。
OLAP的基本多维分析操作有钻取(roll up和drill down)、切片(slice)和切块(dice)、以及旋转(pivot)、drill across、drill through等。
·钻取是改变维的层次,变换分析的粒度。它包括向上钻取(roll up)和向下钻取(drill down)。roll up是在某一维上将低层次的细节数据概括到高层次的汇总数据,或者减少维数;而drill down则相反,它从汇总数据深入到细节数据进行观察或增加新维。 ·切片和切块是在一部分维上选定值后,关心度量数据在剩余维上的分布。如果剩余的维只有两个,则是切片;如果有三个,则是切块。 ·旋转是变换维的方向,即在表格中重新安排维的放置(例如行列互换)。
OLAP有多种实现方法,根据存储数据的方式不同可以分为ROLAP、MOLAP、HOLAP。
ROLAP表示基于关系数据库的OLAP实现(Relational OLAP)。以关系数据库为核心,以关系型结构进行多维数据的表示和存储。ROLAP将多维数据库的多维结构划分为两类表:一类是事实表,用来存储数据和维关键字;另一类是维表,即对每个维至少使用一个表来存放维的层次、成员类别等维的描述信息。维表和事实表通过主关键字和外关键字联系在一起,形成了"星型模式"。对于层次复杂的维,为避免冗余数据占用过大的存储空间,可以使用多个表来描述,这种星型模式的扩展称为"雪花模式"。
MOLAP表示基于多维数据组织的OLAP实现(Multidimensional OLAP)。以多维数据组织方式为核心,也就是说,MOLAP使用多维数组存储数据。多维数据在存储中将形成"立方块(Cube)"的结构,在MOLAP中对"立方块"的"旋转"、"切块"、"切片"是产生多维数据报表的主要技术。
HOLAP表示基于混合数据组织的OLAP实现(Hybrid OLAP)。如低层是关系型的,高层是多维矩阵型的。这种方式具有更好的灵活性。
还有其他的一些实现OLAP的方法,如提供一个专用的SQL Server,对某些存储模式(如星型、雪片型)提供对SQL查询的特殊支持。
OLAP工具是针对特定问题的联机数据访问与分析。它通过多维的方式对数据进行分析、查询和报表。维是人们观察数据的特定角度。例如,一个企业在考虑产品的销售情况时,通常从时间、地区和产品的不同角度来深入观察产品的销售情况。这里的时间、地区和产品就是维。而这些维的不同组合和所考察的度量指标构成的多维数组则是OLAP分析的基础,可形式化表示为(维1,维2,……,维n,度量指标),如(地区、时间、产品、销售额)。多维分析是指对以多维形式组织起来的数据采取切片(Slice)、切块(Dice)、钻取(Drill-down和Roll-up)、旋转(Pivot)等各种分析动作,以求剖析数据,使用户能从多个角度、多侧面地观察数据库中的数据,从而深入理解包含在数据中的信息。
根据综合性数据的组织方式的不同,目前常见的OLAP主要有基于多维数据库的MOLAP及基于关系数据库的ROLAP两种。MOLAP是以多维的方式组织和存储数据,ROLAP则利用现有的关系数据库技术来模拟多维数据。在数据仓库应用中,OLAP应用一般是数据仓库应用的前端工具,同时OLAP工具还可以同数据挖掘工具、统计分析工具配合使用,增强决策分析功能。 |
http://www.huihoo.com/database/dw2.html
如何在Linux上扩展SGA超过1.7G
今天一台Linux服务器扩展了一下内存,达到4G,开发的人自己修改了一下SGA结果数据库无法启动了. 启动不了时,出的错误是这个样子的:
[oracle@neirong oracle]$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Fri Nov 25 15:43:26 2005
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to an idle instance.
SQL> startup
ORA-27123: unable to attach to shared memory segment
Linux Error: 22: Invalid argument
Additional information: 1
Additional information: 458753
SQL> exit
Disconnected |
在32位平台上,缺省的SGA最大只能扩展到1.7G,如果需要支持更大的内存,就需要降低mapped_base,重新Link Oracle软件. 俺的平台为:
[oracle@neirong bdump]$ cat /etc/redhat-release
Red Hat Enterprise Linux AS release 3 (Taroon Update 2) |
简单操作如下:
cd $ORACLE_HOME/rdbms/lib cp ksms.s ksms.s.bak ( if u have a ksms.s file) genksms -s 0x12000000 > ksms.s make -f ins_rdbms.mk ksms.o make -f ins_rdbms.mk ioracle
此处先备份ksms.s文件,如果编译过程中出现错误,保证操作可以被恢复: 恢复步骤大致如下:
cd $ORACLE_HOME/rdbms/lib cp ksms.s.bak ksms.s (if u have backup ksms.s file) genksms > ksms.s make -f ins_rdbms.mk ksms.o make -f ins_rdbms.mk ioracle
以下是操作日志:
[oracle@neirong dbs]$ cd $ORACLE_HOME/rdbms/lib
[oracle@neirong lib]$ genksms -s 0x12000000 > ksms.s
[oracle@neirong lib]$ make -f ins_rdbms.mk ksms.o
[oracle@neirong lib]$ make -f ins_rdbms.mk ioracle
- Linking Oracle
rm -f /opt/oracle/product/9.2.0/rdbms/lib/oracle
gcc -o /opt/oracle/product/9.2.0/rdbms/lib/oracle -L/opt/oracle/product/9.2.0/rdbms/lib/
-L/opt/oracle/product/9.2.0/lib/ -L/opt/oracle/product/9.2.0/lib/stubs/
-Wl,-E `test -f /opt/oracle/product/9.2.0/rdbms/lib/skgaioi.o && echo
/opt/oracle/product/9.2.0/rdbms/lib/skgaioi.o` /opt/oracle/product/9.2.0/rdbms/lib/opimai.o
/opt/oracle/product/9.2.0/rdbms/lib/ssoraed.o /opt/oracle/product/9.2.0/rdbms/lib/ttcsoi.o
/opt/oracle/product/9.2.0/lib/nautab.o /opt/oracle/product/9.2.0/lib/naeet.o
/opt/oracle/product/9.2.0/lib/naect.o /opt/oracle/product/9.2.0/lib/naedhs.o
/opt/oracle/product/9.2.0/rdbms/lib/config.o -lserver9 -lodm9 -lskgxp9 -lskgxn9 -lclient9
-lvsn9 -lwtcserver9 -lcommon9 -lgeneric9 /opt/oracle/product/9.2.0/rdbms/lib/defopt.o
-lknlopt `if /usr/bin/ar tv /opt/oracle/product/9.2.0/rdbms/lib/libknlopt.a | grep
xsyeolap.o > /dev/null 2>&1 ; then echo "-loraolap9" ; fi`
-lslax9 -lpls9 -lplp9 -lserver9 -lclient9 -lvsn9 -lwtcserver9 -lcommon9 -lgeneric9
-lknlopt -lslax9 -lpls9 -lplp9 -ljox9 -lserver9 -locijdbcst9 -lwwg9
`cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9
-ln9 -lnl9 -lnro9 `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9
......
mv -f /opt/oracle/product/9.2.0/bin/oracle /opt/oracle/product/9.2.0/bin/oracleO
mv /opt/oracle/product/9.2.0/rdbms/lib/oracle /opt/oracle/product/9.2.0/bin/oracle
chmod 6751 /opt/oracle/product/9.2.0/bin/oracle |
数据库优化的讨论可以说是一个永恒的主题。资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack,贴出数据库配置等等。还有的人认为要抓出执行最慢的语句来进行优化。但实际情况是,提出疑问的人很可能根本不懂执行计划,更不要说statspack了。而我认为,数据库优化,应该首先从大的方面考虑:网络、服务器硬件配置、操作系统配置、Oracle服务器配置、数据结构组织、然后才是具体的调整。实际上网络、硬件等往往无法决定更换,应用程序一般也无法修改,因此应该着重从数据库配置、数据结构上来下手,首先让数据库有一个良好的配置,然后再考虑具体优化某些过慢的语句。我在给我的用户系统进行优化的过程中,总结了一些基本的,简单易行的办法来优化数据库,算是我的三板斧,呵呵。不过请注意,这些不一定普遍使用,甚至有的会有副作用,但是对OLTP系统、基于成本的数据库往往行之有效,不妨试试。(注:附件是Burleson写的用来报告数据库性能等信息的脚本,本文用到) 一.设置合适的SGA 常常有人抱怨服务器硬件很好,但是Oracle就是很慢。很可能是内存分配不合理造成的。 (1)假设内存有512M,这通常是小型应用。建议Oracle的SGA大约240M,其中:共享池(SHARED_POOL_SIZE)可以设置60M到80M,根据实际的用户数、查询等来定。数据块缓冲区可以大致分配120M-150M,8i下需要设置DB_BLOCK_BUFFERS,DB_BLOCK_BUFFER*DB_BLOCK_SIZE等于数据块缓冲区大小。9i 下的数据缓冲区可以用db_cache_size来直接分配。 (2)假设内存有1G,Oracle 的SGA可以考虑分配500M:共享池分配100M到150M,数据缓冲区分配300M到400M。 (3)内存2G,SGA可以考虑分配1.2G,共享池300M到500M,剩下的给数据块缓冲区。 (4)内存2G以上:共享池300M到500M就足够啦,再多也没有太大帮助;(Biti_rainy有专述)数据缓冲区是尽可能的大,但是一定要注意两个问题:一是要给操作系统和其他应用留够内存,二是对于32位的操作系统,Oracle的SGA有1.75G的限制。有的32位操作系统上可以突破这个限制,方法还请看Biti的大作吧。 二.分析表和索引,更改优化模式 Oracle默认优化模式是CHOOSE,在这种情况下,如果表没有经过分析,经常导致查询使用全表扫描,而不使用索引。这通常导致磁盘I/O太多,而导致查询很慢。如果没有使用执行计划稳定性,则应该把表和索引都分析一下,这样可能直接会使查询速度大幅提升。分析表命令可以用ANALYZE TABLE 分析索引可以用ANALYZE INDEX命令。对于少于100万的表,可以考虑分析整个表,对于很大的表,可以按百分比来分析,但是百分比不能过低,否则生成的统计信息可能不准确。可以通过DBA_TABLES的LAST_ANALYZED列来查看表是否经过分析或分析时间,索引可以通过DBA_INDEXES的LAST_ANALYZED列。 下面通过例子来说明分析前后的速度对比。(表CASE_GA_AJZLZ大约有35万数据,有主键)首先在SQLPLUS中打开自动查询执行计划功能。(第一次要执行\RDBMS\ADMIN\utlxplan.sql来创建PLAN_TABLE这个表) SQL> SET AUTOTRACE ON SQL>SET TIMING ON 通过SET AUTOTRACE ON 来查看语句的执行计划,通过SET TIMING ON 来查看语句运行时间。 SQL> select count(*) from CASE_GA_AJZLZ; COUNT(*) ---------- 346639 已用时间: 00: 00: 21.38 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 SORT (AGGREGATE) 2 1 TABLE ACCESS (FULL) OF 'CASE_GA_AJZLZ' …………………… 请注意上面分析中的TABLE ACCESS(FULL),这说明该语句执行了全表扫描。而且查询使用了21.38秒。这时表还没有经过分析。下面我们来对该表进行分析: SQL> analyze table CASE_GA_AJZLZ compute statistics; 表已分析。 已用时间: 00: 05: 357.63 然后再来查询: SQL> select count(*) from CASE_GA_AJZLZ; COUNT(*) ---------- 346639 已用时间: 00: 00: 00.71 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=351 Card=1) 1 0 SORT (AGGREGATE) 2 1 INDEX (FAST FULL SCAN) OF 'PK_AJZLZ' (UNIQUE) (Cost=351 Card=346351) ………………………… 请注意,这次时间仅仅用了0.71秒!这要归功于INDEX(FAST FULL SCAN)。通过分析表,查询使用了PK_AJZLZ索引,磁盘I/O大幅减少,速度也大幅提升!下面的实用语句可以用来生成分析某个用户的所有表和索引,假设用户是GAXZUSR: SQL> set pagesize 0 SQL> spool d:\analyze_tables.sql; SQL> select 'analyze table '||owner||'.'||table_name||' compute statistics;' from dba_tables where owner='GAXZUSR'; SQL> spool off SQL> spool spool d:\analyze_indexes.sql; SQL> select 'analyze index '||owner||'.'||index_name||' compute statistics;' from dba_indexes where owner='GAXZUSR'; SQL> spool off SQL> @d:\analyze_tables.sql SQL> @d:\analyze_indexes.sql 解释:上面的语句生成了两个sql文件,分别分析全部的GAXZUSR的表和索引。如果需要按照百分比来分析表,可以修改一下脚本。通过上面的步骤,我们就完成了对表和索引的分析,可以测试一下速度的改进啦。建议定期运行上面的语句,尤其是数据经过大量更新。 当然,也可以通过dbms_stats来分析表和索引,更方便一些。但是我仍然习惯上面的方法,因为成功与否会直接提示出来。 另外,我们可以将优化模式进行修改。optimizer_mode值可以是RULE、CHOOSE、FIRST_ROWS和ALL_ROWS。对于OLTP系统,可以改成FIRST_ROWS,来要求查询尽快返回结果。这样即使不用分析,在一般情况下也可以提高查询性能。但是表和索引经过分析后有助于找到最合适的执行计划。 三.设置cursor_sharing=FORCE 或SIMILAR 这种方法是8i才开始有的,oracle805不支持。通过设置该参数,可以强制共享只有文字不同的语句解释计划。例如下面两条语句可以共享: SQL> SELECT * FROM MYTABLE WHERE NAME='tom' SQL> SELECT * FROM MYTABLE WHERE NAME='turner' 这个方法可以大幅降低缓冲区利用率低的问题,避免语句重新解释。通过这个功能,可以很大程度上解决硬解析带来的性能下降的问题。个人感觉可根据系统的实际情况,决定是否将该参数改成FORCE。该参数默认是exact。不过一定要注意,修改之前,必须先给ORACLE打补丁,否则改之后oracle会占用100%的CPU,无法使用。对于ORACLE9i,可以设置成SIMILAR,这个设置综合了FORCE和EXACT的优点。不过请慎用这个功能,这个参数也可能带来很大的负面影响! 四.将常用的小表、索引钉在数据缓存KEEP池中 内存上数据读取速度远远比硬盘中读取要快,据称,内存中数据读的速度是硬盘的14000倍!如果资源比较丰富,把常用的小的、而且经常进行全表扫描的表给钉内存中,当然是在好不过了。可以简单的通过ALTER TABLE tablename CACHE来实现,在ORACLE8i之后可以使用ALTER TABLE table STORAGE(BUFFER_POOL KEEP)。一般来说,可以考虑把200数据块之内的表放在keep池中,当然要根据内存大小等因素来定。关于如何查出那些表或索引符合条件,可以使用本文提供的access.sql和access_report.sql。这两个脚本是著名的Oracle专家 Burleson写的,你也可以在读懂了情况下根据实际情况调整一下脚本。对于索引,可以通过ALTER INDEX indexname STORAGE(BUFFER_POOL KEEP)来钉在KEEP池中。 将表定在KEEP池中需要做一些准备工作。对于ORACLE9i 需要设置DB_KEEP_CACHE_SIZE,对于8i,需要设置buffer_pool_keep。在8i中,还要修改db_block_lru_latches,该参数默认是1,无法使用buffer_pool_keep。该参数应该比2*3*CPU数量少,但是要大于1,才能设置DB_KEEP_CACHE_BUFFER。buffer_pool_keep从db_block_buffers中分配,因此也要小于db_block_buffers。设置好这些参数后,就可以把常用对象永久钉在内存里。 五.设置optimizer_max_permutations 对于多表连接查询,如果采用基于成本优化(CBO),ORACLE会计算出很多种运行方案,从中选择出最优方案。这个参数就是设置oracle究竟从多少种方案来选择最优。如果设置太大,那么计算最优方案过程也是时间比较长的。Oracle805和8i默认是80000,8建议改成2000。对于9i,已经默认是2000了。 六.调整排序参数 (1) SORT_AREA_SIZE:默认的用来排序的SORT_AREA_SIZE大小是32K,通常显得有点小,一般可以考虑设置成1M(1048576)。这个参数不能设置过大,因为每个连接都要分配同样的排序内存。 (2) SORT_MULTIBLOCK_READ_COUNT:增大这个参数可以提高临时表空间排序性能,该参数默认是2,可以改成32来对比一下排序查询时间变化。注意,这个参数的最大值与平台有关系。 七.调整其它几个关键的性能参数 很多人认为使用oracle数据库,系统的默认参数就是最好的,其实不是这样,很多参数都需要调整,而且调整前后性能大不一样。 (1) log_buffer 日志缓冲区大小默认设置32k太小了,建议设置成512K或者1M。 log_buffer=524288 (2) optimizer_index_caching 这个参数可以设置索引的缓冲度,范围是0到100,默认是0,可以考虑设置成90 (3) optimizer_index_cost_adj 这个参数是一个百分比,表明索引扫描与全表扫描的代价范围是1到1000。默认=100表名索引扫描与全表扫描代价一样。将这个参数设小表名索引代价要小于全表扫描,这样就使得使用CBO进行成本计算时更倾向于使用索引扫描。建议把这个参数设置成30到50。 八.改变联机日志文件大小(一般用于oracle805) Oracle805的联机日志文件默认只有1M大小,这实在是太小了,通过查看数据库的日志,很可能发现“checkpoint not complete”之类的错误提示。这会导致系统稳定性,同样也降低了数据库性能。建议修改成10M。修改方法是删除一个组、添加一个组,直到3个组都换成新的大小。说明:这个操作需要实施人员具有较多的数据库知识,如果不太了解,最好不要试验。 九.改变数据块大小(一般用于oracle805) Oracle805默认的块(DB_BLOCK_SIZE)大小是2K,太小了,因为块小,所以请求同样的数据量的时候,读的次数就要增多,导致性能低下。当然如果服务器性能比较好,还是升级Oracle更好,如果服务器配置比较差,建议改成8K。但是数据块不能直接修改,唯一的办法就是将数据导出,重新创建数据库,然后将数据导入。说明:这个操作需要实施人员具有较多的数据库知识,如果不太了解,最好不要试验。 十.设置合适的表存储参数 对于有很多并发写入用户的系统来说,如果系统没有经过调整,经常会有数据等待现象。这是因为9i之前的表设置的默认的自由队列freelists为1,这样就可能造成数据等待。通过查看v$waitstat,如果发现data block 或者free list类的count次数很大,则说明等待情况严重,需要增加freelists。这个参数在8i、9i中可以动态修改(需要打补丁,否则会有ORA-10620: Operation not allowed on this segment)在ORACLE805中,只能通过重新创建表来修改。 SQL> select * from v$waitstat; CLASS COUNT TIME ------------------ ---------- ---------- data block 11922013 342456 sort block 0 0 save undo block 0 0 segment header 1 0 free list 0 0 如果测算经常有10个并发的写用户,可以把表的freelists改成10。例如下面的脚本可以把GAXZUSR用户的所有表重新设置FREELISTS的语句写在D:\FREELISTS.SQL里: SQL> SET PAGESIZE 0 SQL> SPOOL D:\FREELISTS.SQL SQL> SELECT 'ALTER TABLE '||TABLE_NAME||' STORAGE(FREELISTS 10);' FROM DBA_TABLES WHERE OWNER=’GAXZUSR’; SQL>SPOOL OFF 检查D:\FREELISTS.SQL,没有错误后运行修改FREELISTS: SQL>@D:\FREELISTS.SQL 十一.重新组织表结构 (1) 按照主键重新排序。 数据库运行了一段时间后,可能会有很多数据,而这些数据又可能是经常按照某个字段来选取区段数据。如果我们能够把主键按照顺序重新来组织一下表,那么用主键进行的查询就会明显快很多,主要是因为经过排序后,相似的编号都放在同一个数据块里,ORACLE在进行主键范围查找的时候,就会大大减少物理块度读取数量。在对表和索引分析之后,可以通过DBA_INDEXES的CLUSTERING_FACTOR列来判断表是否需要重新排序。如果该字段的值与表的BLOCK数量差不多,则不需要重新排序,如果和表的行数差不多,则应该考虑重新组织一下了。下面的例子示意性说明怎样对表CASE_GA_AJZLZ按照主键PK_AJZLZ进行重新排序: <1> 将表CASE_GA_AJZLZ的索引、外间约束引用等找出来备用。 SET PAGESIZE 0 SET LINESIZE 300 SPOOL DISABLE_CONSTRAINTS.SQL SELECT 'ALTER TABLE '||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';' FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE='R' AND R_CONSTRAINT_NAME='PK_AJZLZ'; SPOOL OFF SPOOL CREATE_CONSTRAINTS.SQL SELECT 'ALTER TABLE '||TABLE_NAME||' ADD CONSTRAINT '||CONSTRAINT_NAME||' FOREIGN KEY(CASEID) REFERENCES CASE_GA_AJZLZ(CASEID);' FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE='R' AND R_CONSTRAINT_NAME='PK_AJZLZ'; SPOOL OFF SPOOL CREATE_INDEX.SQL SELECT 'CREATE INDEX '||INDEX_NAME||' ON '||TABLE_NAME||'('||COLUMN_NAME||') TABLESPACE INDX ;' FROM USER_IND_COLUMNS WHERE TABLE_NAME='CASE_GA_AJZLZ' AND INDEX_NAME<>'PK_AJZLZ'; <2> 创建新的表CASE_GA_AJZLZ_NEW: SQL> CREATE TABLE CASE_GA_AJZLZ_NEW AS SELECT /*+INDEX(CASE_GA_AJZLZ PK_AJZLZ) */ * FROM CASE_GA_AJZLZ ; 注意,上面的注释(红颜色部分)表名按照PK_AJZLZ排序来重新组织表。 <3>禁用CASE_GA_AJZLZ的外间约束,将表CASE_GA_AJZLZ TRUNCATE,然后删除之 <4> 将表CASE_GA_AJZLZ_NEW更名为CASE_GA_AJZLZ SQL> ALTER TABLE CASE_GA_AJZLZ_NEW RENAME TO CASE_GA_AJZLZ; <5>创建CASE_GA_AJZLZ的所有索引、主键约束等。 SQL> ALTER TABLE CASE_GA_AJZLZ ADD CONSTRAINT PK_AJZLZ PRIMARY KEY(CASEID); SQL> @CREATE_INDEX.SQL SQL> @CREATE_CONSTRAINTS.SQL (2) 将BLOB字段存储到单独的表空间中。 基本上每个业务系统都有很多BLOB字段,而且很可能占据了整个数据库大小的大部分。默认情况下,BLOB字段会将4000个字节的指针与表的行存在一起,这直接会导致行迁移。而且BLOB字段会与表处于同一个表空间,这也对性能有不小的影响。从设计角度来说,BLOB字段都应该单独存储,遗憾的是我所遇到的很多系统都没有单独存储BLOB字段。如果BLOB字段占据了很大的存储,那么将BLOB字段单独存储后,带来的整体性能收益可能会非常的大。 另外BLOB字段存储子句中有一个DISABLE STORAGE IN ROW 属性,在将BLOB字段单独存放时,也应该实用该属性,这样可以有效避免行迁移。
http://publish.it168.com/2005/1118/20051118002701.shtml
原文链接: http://download-west.oracle.com/otndoc/oracle9i/901_doc/server.901/ a90117/whatsnew.htm 是编号为A90120-20文档的概括 前些天看到有人问9I的新功能,就随手翻译了一下有的地方不准确或者是错误的,大家多包涵不清楚的地方请参考文档,谢谢
Oracle9i Release 1 (9.0.1) New Features Oracle9i brings a major new release of the Oracle database server. It includ es features to make the database more available. More online operations reduce the need for offline maintenance. Management of the database requires less effort. Oracle9i can automatically create and manage the underlying operating system files required by the database. There is a theme of self management. Oracle9i带来了一次Oracle数据库服务器的主要升级。它包括了可以使数据库更可靠,更多的在线操作替代了离线维护,管理数据库更有效的新特性。Oracle9i自动管理数据库需要的操作系统文件。这是自动管理的主题。
Performance is enhanced. The Database Resource Manager has new options that allow for more granular control of resources. The performance level required of a resource consumer group can be better sustained. Partitioning enhancements allow tables and indexes to be better partitioned for performance. Security enhancements are an important part of this release. Applications have available more and finer grained methods of implementing security and auditing.
性能得到增强。数据库资源管理器拥有新的选项,允许对资源进行更好的控制。一组资源消费所要求的性能水平可以得到持续满足。分区增强允许表和索引为性能更好的分区。安全增强是这次升级的重要部分。应用程序拥有更多更好的执行安全和审计的方法。
The following are summaries of the new features of Oracle9i that are discussed in this book. 下面是Oracle9i新特性的总结。
Online redefinition of tables The new DBMS_REDEFINITION PL/SQL package provides a mechanism to redefine ta bles online. When a table is redefined online, it is accessible to DML durin g much of the redefinition process. This provides a significant increase in availability compared to traditional methods of redefining tables that require tables to be taken offline. 1. 在线重定义表 新的PL/SQL包DBMS_REDEFINITION提供了在线重定义表的机制。当表被在线重定义的时候,在重定义进程中的大多数时刻对DML是可用的。与传统的要求表先离线再重新定义的方法相比,显著地提高了可用性。
ONLINE option for ANALYZE VALIDATE STRUCTURE statement The ANALYZE statement can now perform validation while DML is ongoing within the object being analyzed. 2. ANALYZE VALIDATE STRUCTURE语句的ONLINE选项 ANALYZE语句现在可以在DML运行的时候提供确认,当目标正在分析的时候。
Controlling Archive Log Oracle now provides a time-based means of switching the current online redo log group. In a primary/standby configuration, where all noncurrent logs of the primary site are archived and shipped to the standby database, this effectively limits the number of redo records, as measured in time, that will not be applied in the standby database. 3. 控制归档日志 Oracle现在提供一种基于时间的方法用来切换目前的在线redo log组。在primary/standby配置中,既所有主站点非当前日志都被归档并传到standby数据库中,它有效地限制了重做记录的数量,从时间上考虑,它不使用在standby database上。
Suspending a database Oracle9i includes a database suspend/resume feature. The ALTER SYSTEM SUSPEND statement suspends a database by halting all input and output (I/O) to dat afiles and control files. When the database is suspended all preexisting I/O operations are allowed to complete and any new database accesses are placed in a queued state. The ALTER SYSTEM RESUME statement resumes normal databas e operation. 4. 挂起数据库 Oracle包括数据库挂起/恢复特性。ALTER SYSTEM SUSPEND语句通过暂停所有对数据文件和控制文件的输入输出(I/O)挂起数据库。当数据库被挂起时,所有先前存在的I/9操作被允许执行完毕并且任何新的请求被放在一个状态队列中。ALTER SYSTEM RESUME语句恢复正常的数据库操作。
Quiescing a database Oracle9i allows you to place the database into a quiesced state, where only DBA transactions, queries, or PL/SQL statements are allowed. This quiesced state allows you to perform administrative actions that cannot safely be done otherwise. The ALTER SYSTEM QUIESCE RESTRICTED statement places a database into a quiesced state 5. 禁用数据库 Oracle9i允许拥护将数据库置于一个禁用状态,只有DBA事务、查询或者PL/SQL语句可以执行。这个状态允许用户进行在其他情况下不能保证安全的管理工作。ALTER SYSTEM QUIESCE RESTRICTED语句将数据库设置为禁用状态。
Resumable Space Allocation Oracle provides a means for suspending, and later resuming, the execution of large database operations in the event of space allocation failures. This enables you to take corrective action, instead of the Oracle database server returning an error to the user. After the error condition is corrected, the suspended operation automatically resumes. 6. 空间分配可恢复 当大型数据库操作在空间分配阶段失败时,Oracle提供了一种先挂起,一段时间后恢复执行的机制。它可以允许纠正操作,代替数据库返回用户一个错误。当错误状态被纠正时,挂起的操作自动恢复。
More archiving destinations The maximum number of destinations to which you can archive the online redo log, has been increased from 5 to 10. 7. 更多的归档目标文件 归档重做日志所用的目标文件的最大数量从5个增加到10个。
Automatic segment- space management Locally managed tablespaces allow extents to be managed automatically by Oracle. Oracle9i allows free and used space within segments stored in locally managed tablespaces to also be managed automatically. Using the SEGMENT SPACE MANAGEMENT clause of CREATE TABLESPACE you specify AUTO or MANUAL to specify the type of segment space management Oracle will use. 8. 自动分段——空间管理 本地管理的表空间允许扩展段由Oracle自动管理。Oracle9i也允许本地表空间段中的free和used空间自动管理。使用CREATE TABLESPACE的SEGMENT SPACE MANAGEMENT子句,通过设置AUTO或MANUAL确定Oracle用来管理段空间所使用的方法。
Update of global indexes when partition maintenance is performed By default, many table maintenance operations on partitioned tables invalida te (mark UNUSABLE) global indexes. You must then rebuild the entire global i ndex or, if partitioned, all of its partitions. Oracle9i allows you to override this default behavior. When you specify the UPDATE GLOBAL INDEX clause in your ALTER TABLE statement for the maintenance operation, the global index is updated in conjunction with the base table operation. 9. 维护分区的时候更新全局索引 在缺省情况下,许多在分区表上进行的表维护操作使全局索引无效(标志为UNUSABLE)。用户必须重建全部的全局索引,或者在在分区的情况下,全部它的分区。Oracle9i允许用户使其无效。当用户在维护操作的ALTER TABLE语句中声明UPDATE GLOBAL INDEX子句时,全局索引和基表操作一起更新。
Multiple block sizes Oracle now supports multiple block sizes. It has a standard block size, as s et by the DB_BLOCK_SIZE initialization parameter, and additionally up to 4 n onstandard block sizes. Nonstandard block sizes are specified when creating tablespaces. The standard block size is used for the SYSTEM tablespace and most other tablespaces. Multiple block size support allows for the transporting of tablespaces with unlike block sizes between databases. 10. 块大小多样化 Oracle现在支持多种块的尺寸。数据块具有一个标准的大小,建立表空间时在DB_BLOCK_SIZE初始化参数中设置。标准块大小用于SYSTEM表空间和大多数其他表空间。多样化的块大小允许数据库间具有不同块大小的表空间传输。
Dynamic buffer cache The size of the buffer cache subcomponent of the System Global Area is now dynamic. The DB_BLOCK_BUFFERS initialization parameter has been replaced by a new dynamic parameter, DB_CACHE_SIZE, where the user specifies the size of the buffer subcache for the standard database block size. The buffer cache now consists of subcaches when multiple block sizes are specified for the database. Up to four DB_nK_CACHE_SIZE initialization parameters allow you to specify the sizes of buffer subcaches for the additional block sizes. 11. 动态buffer cache 现在SGA区的buffer cache部分的大小是动态的。原来的初始化参数DB_BLOCK_BUFFERS被新的动态参数DB_CACHE_SIZE取代,用户可以为标准数据库块大小设置次级缓冲区。当数据库使用不同的块大小时,buffer cache由各个次级缓冲区组成。4个DB_nK_CACHE_SIZE初始化参数允许用户为其他的块尺寸设置次级缓冲。
Dynamic SGA The initialization parameters affecting the size of SGA have been made dynamic. It is possible to alter the size of SGA dynamically through an ALTER SYSTEM SET statement. 12. 动态SGA 影响SGA大小的初始化参数被设置为动态。可以使用ALTER SYSTEM SET语句动态改变SGA的大小。
Automatic undo management Historically, Oracle has used rollback segments to store undo. Undo is defined as information that can be used to roll back, or undo, changes to the database when necessary. Oracle now enables you to create an undo tablespace to store undo. Using an undo tablespace eliminates the complexities of managing rollback segment space, and enables you to exert control over how long undo is retained before being overwritten. 13. 自动UNDO管理 以前Oracle使用回滚段存储UNDO。UNDO定义为可以在需要的时候使用于回滚或者撤消数据库的改变的信息。Oracle现在允许用户建立一个undo表空间用来存储undo。使用undo表空间消除了管理回滚段空间的复杂性,并且允许用户精确地控制undo被重写前所保留的时间。
Oracle managed files The Oracle managed files feature of Oracle9i eliminates the need for you to directly manage the files comprising an Oracle database. Through the DB_CREA TE_FILE_DEST and DB_CREATE_ONLINE_LOG_DEST_n initialization parameters, you specify the file system directory to be used for a particular type of file c omprising a tablespace, online redo log file, or control file. Oracle then e nsures that a unique file, an Oracle-managed file, is created and deleted when no longer needed. 14. Oracle文件管理 Oracle9i的文件管理功能不再需要用户直接管理组成Oracle数据库的文件。通过DB_CREATE_FILE_DEST和DB_CREATE_ONLINE_LOG_DEST_n初始化参数,用户可以指定组成表空间,在线重做日志或控制文件所使用的文件所在的系统目录。Oracle确保自己管理的文件可以建立,并在不需要时删除。
Automatic deletion of datafiles Oracle9i provides an option to automatically remove a tablespaces's operating system files (datafiles) when the tablespace is dropped using the DROP TABLESPACE statement. A similar option for the ALTER DATABASE TEMPFILE statement, causes deletion the operating system files associated with a temporary file. 15. 文件自动删除 Oracle9i提供了在执行DROP TABLESPACE语句删除表空间时,自动删除操作系统数据文件的选项。与之类似的ALTER DATABASE TEMPFILE语句,可以删除相关的临时文件。
Metadata API A new PL/SQL package, DBMS_METADATA.GET_DDL, allows you to obtain metadata ( in the form of DDL used to create the object) about a schema object 16. Metadata API 一个新的PL/SQL包,DBMS_METADATA.GET_DDL,允许用户获得一个概要对象的元数据(以 建立这个对象的DDL形式)。
External tables Oracle9i allows you read-only access to data in external tables. External tables are defined as tables that do not reside in the database, and can be in any format for which an access driver is provided. The CREATE TABLE ... ORG ANIZATION EXTERNAL statement specifies metadata describing the external table. Oracle currently provides the ORACLE_LOADER access driver which provides data mapping capabilities that are a subset of the SQL*Loader control file syntax. 17. 外部表 Oracle9i允许用户只读访问外部表中的数据。外部表定义为不在数据库中的表,以任何可以使用的驱动所能提供的形式。CREATE TABLE ... ORGANIZATION EXTERNAL语句定义描述外部表的元数据。Oracle现在提供ORACLE_LOADER访问驱动,以提供数据映射能力,作为SQL*Loader控制文件语法的子集。
Constraint enhancements Enhancements to the USING INDEX clause of CREATE TABLE or ALTER TABLE allow you to specify the creation or use of a specific index when a unique or primary key constraint is created or enabled. Additionally, you can prevent the dropping of the index enforcing a unique or primary key constraint when the constraint is dropped or disabled. 18. 约束增强 对CREATE TABLE和ALTER TABLE的USING INDEX子句增强允许用户在唯一或主键约束建立或改变时建立或使用一个指定的索引。另外,用户可以防止当删除或禁止一个索引时强制删除唯一或主键约束。
Server parameter file Oracle has traditionally stored initialization parameters in a text initiali zation parameter file, often on a client machine. Starting with Oracle9i, you can elect to maintain initialization parameters in a server parameter file, which is a binary parameter file stored on the database server. Initialization parameters stored in a server parameter file are persistent, in that any changes made to the parameters while an instance is running persist across instance shutdown and startup. 19. 服务器参数文件 以前Oracle将初始化参数存储在客户机上的一个文本文件中。从Oracle9i开始,用户可以选择在服务器参数文件中维护初始化参数,它是一个存储在数据库服务器中的二进制参数文件。存储在服务器参数文件中的初始化参数是不变的,??????
Default temporary tablespace The new DEFAULT TEMPORARY TABLESPACE clause of the CREATE DATABASE statement allows you to create a default temporary tablespace at database creation time. This tablespace is used as the default temporary tablespace for users who are not otherwise assigned a temporary tablespace. 20. 默认临时表空间 CREATE DATABSE语句的新子句DEFAULT TEMPORARY TABLESPACE允许用户在建立数据库时建立默认临时表空间。作为没有指定临时表空间用户的缺省临时表空间。
Setting the database time zone The CREATE DATABASE statement now has a SET TIME_ZONE clause that allows you to set the time zone of the database as a displacement from UTC (Coordinated Universal Time--formerly Greenwich Mean Time). Oracle normalizes all TIMES TAMP WITH LOCAL TIME ZONE data to the time zone of the database when the data is stored on disk. Additionally, a new session parameter TIME_ZONE has bee n added to the SET clause of ALTER SESSION. 21. 设置数据库时区 现在使用CREATE DATABASE的SET TIME_ZONE子句允许用户设置数据库时区为UTC的偏移。当数据存储到磁盘上时,Oracle用本地数据库时区的数据格式化所有时间戳。另外,新的会话参数TIME_ZONE加入ALTER SESSION的SET子句中。
Transaction Naming Oracle now allows you to assign a name to a transaction. The transaction name is helpful in resolving in-doubt distributed transactions, and replaces a COMMIT COMMENT. 22. 事务命名 现在Oracle允许用户为事务指定一个名字。事务名称有助于解决分布事务的不确定性,并取代COMMIT的注释。
Oracle Database Configuration Assistant changes The Oracle Database Configuration Assistant has been redesigned. It now prov ides templates, which are saved definitions of databases, from which you can generate your database. Oracle provides templates, or you can create your own templates by modifying existing ones, defining new ones, or by capturing the definition of an existing database.When creating a database with the Database Configuration Assistant, you can either initially include, or later add as an option, Oracle's new Sample Schemas. These schemas are the basis for many of the examples used in Oracle documentation. 23. Oracle Database Configuration Assistant 变化 Oracle Database Configuration Assistant经过了重新设计。它提供了存储数据库精确定义的模板,通过模板用户可以生成自己的数据库。Oracle提供了模板,用户也可以通过改变现有的,定义新的,或者获得现有数据库的精确定义来建立自己的模板。当使用数据库配置向导建立数据库时,用户可以在开始或之后加入一个选项——Oracle的新方案实例。这些方案是Oracle文档中很多例子的基础。
Monitoring index usage A MONITORING USAGE clause has been added for the ALTER INDEX statement. It allows you to monitor an index to determine if it is actively being used. 24. 监视索引使用 在ALTER INDEX语句中加入了MONITORING USAGE子句。它允许用户监视索引是否被有效地使用。
List partitioning Oracle introduces list partitioning, which enables you to specify a list of discrete values for the partitioning column in the description for each part ition. The list partitioning method is specifically designed for modeling data distributions that follow discrete values. This cannot be easily done by range or hash partitioning. 25.列表分区(List partitioning) Oracle引入列表分区,使得用户能够为各个分区指定一组离散的值。列表分区方法是专门为离散数据模型设计的,原来使用范围和哈希分区很难做到。
Hash partitioning of index-organized tables In this release, support has been added for partitioning index-organized tables by the hash method. Previously, they could be partitioned, but only by the range method. 26. 索引组织表的哈希分区 在这个版本中,增加了使用哈希方法分区的索引组织表。在这之前只能使用排列方法分区。
Dynamic job queue processes The job queue process creation has been made dynamic so that only the required number of processes are created to execute the jobs that are ready for execution. A job queue coordinator background process (CJQ) dynamically spawns Jnnn processes to execute jobs. 27. 动态任务序列进程 动态的建立任务序列进程,这样只有需要的进程数量被在任务准备执行时建立。一个任务序列后台调度进程产生Jnnn进程用来执行任务
New in the Database Resource Manager for Oracle9i The following new functionality has been added to the Database Resource Mana ger:Ability to create an active session pool. This pool consists of a specified maximum number of user sessions allowed to be concurrently active within a g roup of users. Additional sessions beyond the maximum are queued for execution, but you can specify a timeout period, after which queued jobs will abort.Automatic switching of users from one group to another group based on administrator defined criteria. If a member of a particular group of users creates a session that executes for longer than a specified amount of time, that session can be automatically switched to another group of users with different resource requirements. Ability to prevent the execution of operations that are estimated to run for a longer time than a predefined limit Ability to create an undo pool. This pool consists of the amount of undo space that can be consumed in by a group of users. 28. Oracle9i数据库资源管理器新特性下列新功能被加入到数据库资源管理器中: 1) 建立动态进程池功能。由指定的最大数量的一组活动用户进程组成。其他超过这个最大值的进程将加入等待执行的队列,但是用户可以指定一个过期时间,超过后队列中的任务将被取消。 2) 基于管理员定义的标准自动将用户从一个组切换到另一个组。如果一个组中的某个用户建立的进程超过了指定的时间,这个进程可以被自动切换到另一个拥有不同资源的组中。 3) 能够防止操作运行时间过长,超过一个预定的限制。 4) 能够建立undo池。由一组用户使用的undo空间组成。
Proxy authentication and authorization Oracle9i enables you to authorize a middle-tier server to act on behalf of a client. The GRANT CONNECT THROUGH clause of the ALTER USER statement specifies this functionality. You can also specify roles that the middle tier is permitted to activate when connecting as the client. 29. 代理认证和授权 Oracle9i允许用户为客户端授权使用一个中间层服务器。ALTER USER语句的GRANT CONNECT THROUGH子句实现这个功能。用户也可以指定中间层作为客户端连接时允许使用的规则。
Application roles Oracle provides a mechanism by which roles granted to application users are enabled using a designated PL/SQL package. This feature introduces the IDENTIFIED USING package clause for the CREATE ROLE statement. 30. 应用程序角色Oracle提供一种机制,使得被授予应用程序角色的用户可以是使用一个指定的PL/SQL包。这个特性在CREATE ROLE语句的IDENTIFIED USING packet子句中引入。
Fine-grained auditing In Oracle's traditional auditing methods, a fixed set of facts is recorded in the audit trail. Audit options can only be set to monitor access of objects or privileges. A new PL/SQL package, DBMS_FGA, allows applications to implement fine-grained auditing of data access based on content. 31. 细致审计 在Oracle以前的审计方法中,一套固定的因素记录在审计记录中。审计选项只能被设置为监视对象和权限的访问情况。一个新的PL/SQL包,DBMS_FGA,允许应用程序执行基于内容数据访问的细致审计。
New in LogMiner for Release 9.0.1 LogMiner release 9.0.1 has added support for many new features. Some of the new features work with any redo log files from an Oracle 8.0 or later database. Other features only work with redo log files produced on Oracle9i or later. 32. LogMiner9.0.1版新特性 LogMiner9.0.1版增加了对很多新特性的支持。其中一部分可以应用于Oracle8及以后版本数据库的重做日志文件。其他的只能用于Oracle9i和后来版本。
New Features for Redo Log Files Generated by Oracle9i or Later 1) Oracle9i及后续版本重做日志文件的新特性 For any redo log files generated by Oracle9i or later, LogMiner now provides support for the following: 对于任何Oracle9i和后来版本生成的重做日志文件,LogMiner现在提供下列支持: Index clusters 索引簇 Chained and migrated rows 链接的和可移动的行 Direct path inserts (with ARCHIVELOG mode enabled) 直接路径插入(在ARCHIVELOG模式有效时) Extracting the data dictionary into the redo log files. 将数据字典摘取到重做日志文件中。 Using the online catalog as the data dictionary. 使用在线目录作为数据字典。 Tracking of all data definition language (DDL) operations, which enables you to monitor schema evolution. 跟踪所有数据定义语言(DDL),使用户可以监视schema的变化。 Viewing user-executed DDL in the SQL_REDO column. Information regarding the original database user is also returned. 在SQL_REDO栏中看到用户执行的DDL。关于原来数据库用户的信息也被改变。 Generating SQL_REDO and SQL_UNDO with primary key information for updates. T hat is, updated rows are identified by primary keys and ROWIDs (provided sup plemental logging is enabled), thereby making it easier to apply the stateme nts to a different database. 为更新而产生SQL_REDO和SQL_UNDO关于主键的信息。这样更新行是通过主键和ROWID,因此使在另一个数据库上应用这些语句变得更容易。
New Features for Redo Log Files Generated by Oracle Release 8.0 or Later 2) Oracle8.0及后续版本重做日志文件的新特性 For any redo log files generated by Oracle release 8.0 or later, LogMiner now provides support for the following: 对于任何Oracle8.0和后来版本生成的重做日志文件,LogMiner现在提供下列支持: Limiting V$LOGMNR_CONTENTS data to rows belonging to committed transactions only. This option enables you to filter out rolled back transactions and transactions that are in progress. 将V$LOGMNR_CONTENTS中数据限制在属于已提交的事务行上。这个选项允许用户过滤回滚事务和正在进行的事务。 Performing queries based on actual data values in the redo log files. 在重做日志文件中执行基于确定值的查询。
http://www.chinaitlab.com/www/news/article_show.asp?id=1127
Problem:
I'm getting errors when I compile this procedure.
create or replace procedure send_message (v_message in varchar2) is s integer; begin dbms_pipe.pack_message(v_message); s:=dbms_pipe.send_message('DEMO_PIPE'); if s<>0 then raise_application_error(-20200,'ERROR'||to_char(s)||'sending on pipe'); end if; end send_message; The errors are .. PLS-00201: identifier 'SYS.DBMS_PIPE' must be declared PL/SQL: Statement ignored PL/SQL: Statement ignored PLS-00201: identifier 'SYS.DBMS_PIPE' must be declared So whats wrong? Thanks
Resolvent:
sql>connect sys as sysdba sql>password: change_on_install sql> grant execute on dbms_pipe to public; sql>create public synonym dbms_pipe for dbms_pipe;(if the synonym doesn't exist) sql>conn scott/tiger sql>execute the package
ps:the all package execute privilege is included in role EXECUTE_CATALOG_ROLE
一、简介
在过去,如果用户误删/更新了数据后,作为用户并没有什么直接的方法来进行恢复,他们必须求助DBA来对数据库进行恢复,到了Oracle9i,这一个难堪局面有所改善。Oracle 9i中提供了一项新的技术手段--闪回查询,用户使用闪回查询可以及时取得误操作前的数据,并可以针对错误进行相应的恢复措施,而这一切都无需DBA干预。
下面我们通过一个例子来具体说明闪回查询的用法。
二、示例
1、使用闪回查询前必须确定下面两个参数:
UNDO_MANAGEMENT = AUTO
undo_retention = 1200; #这个时间可以随便设,他表示在系统中保留提交了的UNDO信息的时间,1200就是保留20分钟。
2、使用闪回查询
SQL> conn sys/sys as sysdba
Connected.
SQL> create user flash identified by flash;
User created.
SQL> grant connect, resource to flash;
Grant succeeded.
SQL> grant execute on dbms_flashback to flash;
Grant succeeded.
SQL> conn flash/flash
Connected.
SQL> set echo on
SQL> create table t (a varchar2(10));
Table created.
SQL> insert into t values('gototop');
1 row created.
SQL> insert into t values('www.ncn.cn');
1 row created.
SQL> /
SQL> select * from t;
A
----------
gototop
www.ncn.cn
www.ncn.cn
SQL> set time on
15:00:22 SQL>
15:00:22 SQL>
15:00:23 SQL> delete t where a='gototop';
1 row deleted.
15:00:35 SQL> commit;
Commit complete.
15:00:38 SQL> select * from t;
A
----------
www.ncn.cn
www.ncn.cn
15:08:22 SQL> execute DBMS_FLASHBACK.ENABLE_AT_TIME(to_date('2003-05-16 15:00:00'));
PL/SQL procedure successfully completed.
15:09:02 SQL> select * from t;
A
----------
gototop
www.ncn.cn
www.ncn.cn
15:16:43 SQL> execute DBMS_FLASHBACK.DISABLE;
PL/SQL procedure successfully completed.
15:17:05 SQL> select * from t;
A
----------
www.ncn.cn
www.ncn.cn
3、使用闪回查询恢复数据:
15:36:55 SQL> select * from t;
no rows selected
15:36:57 SQL> insert into t values('www.ncn.cn');
1 row created.
15:37:15 SQL> /
1 row created.
15:37:16 SQL> /
1 row created.
15:37:17 SQL> /
1 row created.
15:37:18 SQL> /
1 row created.
15:37:19 SQL> commit;
Commit complete.
15:37:21 SQL> /
Commit complete.
15:37:22 SQL> /
Commit complete.
15:37:23 SQL> select * from t;
A
----------
www.ncn.cn
www.ncn.cn
www.ncn.cn
www.ncn.cn
www.ncn.cn
www.ncn.cn
6 rows selected.
15:37:28 SQL>
15:38:44 SQL> delete t;
6 rows deleted.
15:38:50 SQL> commit;
Commit complete.
15:38:53 SQL> commit;
Commit complete.
15:38:54 SQL> /
Commit complete.
15:38:57 SQL> declare
15:39:28 2 cursor flash_recover is
15:39:28 3 select * from t;
15:39:28 4 t_recode t%rowtype;
15:39:28 5 begin
15:39:28 6 DBMS_FLASHBACK.ENABLE_AT_TIME(to_date('2003-05-16 15:37:23'));
15:39:28 7 open FLASH_RECOVER;
15:39:28 8 DBMS_FLASHBACK.DISABLE;
15:39:28 9 loop
15:39:28 10 FETCH FLASH_RECOVER INTO t_recode;
15:39:28 11 EXIT WHEN FLASH_RECOVER%NOTFOUND;
15:39:28 12 insert into t values (t_recode.a);
15:39:28 13 end loop;
15:39:28 14 CLOSE FLASH_RECOVER;
15:39:28 15 commit;
15:39:28 16 end;
15:39:28 17 /
PL/SQL procedure successfully completed.
15:39:28 SQL> 15:39:28 SQL>
15:39:31 SQL> select * from t;
A
----------
www.ncn.cn
www.ncn.cn
www.ncn.cn
www.ncn.cn
www.ncn.cn
15:39:35 SQL>
我们可以已经恢复了5条纪录,但我们要恢复的6条纪录,为什么会少一条呢?原因就在下面。
三、局限性
1、闪回查询是基于SCN的,虽然我执行的是:
DBMS_FLASHBACK.ENABLE_AT_TIME(to_date('2003-05-16 15:37:23'));
但Oracle并不会精确的这个时间点,而是ROUND DOWN到最近的一次SCN,然后从这个SCN开始进行恢复。而Oracle 9i是每五分钟记录一次SCN的,并将SCN和对应时间的映射做个纪录。时间和 SCN 的对应关系记录在 sys.smon_scn_time 中,估计是 smon 每五分钟更新一次该表,且该表总记录保持为 1440 条,也就是说该表保持 5 天的记录,所以有后面 5 天的限制,如果要用精确恢复,还是用基于 SCN 的恢复比较好。
这正是上面我们进行恢复时少了一条的原因。因此如果使用DBMS_FLASHBACK.ENABLE_AT_TIME来进行恢复,为了避免恢复失败,我可以先等5分钟,然后再进行恢复。
使用DBMS_FLASHBACK.ENABLE_AT_TIME进行恢复还有一个缺点,那就是在Oracle 9i中SCN和对应时间的映射信息只会保留5天,因此我们无法通过DBMS_FLASHBACK.ENABLE_AT_TIME来恢复5天前的数据。如果你想使用闪回查询来恢复5天前的数据,你必须自己来确定需要恢复的SCN,然后使用
DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(SCN_NUMBER); 来定位你的恢复时间点,下面是使用方法:
15:58:58 SQL> VARIABLE SCN_SAVE NUMBER;
16:13:43 SQL> EXECUTE :SCN_SAVE := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER;
PL/SQL procedure successfully completed.
16:13:50 SQL> print SCN_SAVE;
SCN_SAVE
----------
2.1202E+11
16:28:34 SQL> execute DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(:SCN_SAVE);
PL/SQL procedure successfully completed.
另外,在使用DBMS_FLASHBACK.ENABLE_AT_TIME前,你必须设定你的NLS_DATE_FORMAT的精确程度,Oracle默认的是精确到天,如果你不设定,像上面的例子你不会得到预期结果。
2、如果你使用sysdate和DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER来获取时间点或者SCN值,你必须注意它们取得都是当前的时间点和SCN值。
3、你只能在事务开始时进入闪回查询模式,如果之前有DML操作,则必须COMMIT。
4、闪回查询无法恢复到表结构改变之前,因为闪回查询使用的当前的数据字典。
补充: DBMS_FLASHBACK 包将整个 SESSION 恢复到相应的时间点,恢复过去之后不能做任何操作,如果要获得恢复的数据,只能用前面的游标实现,或者可以用简单的 AS OF 的方法: Create table flashback as select * from t1 as of scn/timestamp XXXX
http://www.chinaitlab.com/www/news/article_show.asp?id=12393 http://www.chinaunix.net/jh/19/286443.html
索引可以加快查询的速度,但索引会占用许多存储空间,在插入和删除行的时候,索引还会引入额外的开销,因此确保索引得到有效利用是我们很关注的一个问题。在Oracle9i之前,要知道一个索引是否被使用是困难的,而Oracle 9i中提供了一个有效的监控方法:ALTER INDEX MONITORING USAGE。下面我讲详细说明如何使用该方法来鉴别未使用的索引。
一、我们先通过一个例子具体说明“ALTER INDEX MONITORING USAGE”的使用方法:
1、建测试表
create table test(id number(3),name varchar2(10));
insert into test values(1,'aaaaaaaa');
insert into test values(2,'www.ncn.cn');
insert into test values(3,'aadfaaaa');
insert into test values(4,'gototop');
insert into test values(5,'shenzhen');
insert into test values(6,'china');
commit;
alter table test add (constraint test_pk primary key (id));
2、查询v$object_usage(因为没有监视,所以还看不到内容)
column index_name format a12
column monitoring format a10
column used format a4
column start_monitoring format a19
column end_monitoring format a19
select index_name,monitoring,used,start_monitoring,end_monitoring from v$object_usage;
SQL> l
1* select index_name,monitoring,used,start_monitoring,end_monitoring from v$object_usage
SQL> /
no rows selected
Elapsed: 00:00:00.00
3、开始监控索引的使用情况
SQL> alter index test_pk monitoring usage;
Index altered.
Elapsed: 00:00:00.05
4、查询v$object_usage(可以看到正监视中)
SQL> select index_name,monitoring,used,start_monitoring,end_monitoring from v$object_usage;
INDEX_NAME MONITORING USED START_MONITORING END_MONITORING
------------ ---------- ---- ------------------- -------------------
TEST_PK YES NO 05/15/2003 13:28:22
Elapsed: 00:00:00.00
5、使用索引进行查询
SQL> set autotrace on explain
SQL> select * from test where id = 2;
ID NAME
---------- ----------
2 www.ncn.cn
Elapsed: 00:00:00.00
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
2 1 INDEX (UNIQUE SCAN) OF 'TEST_PK' (UNIQUE)
SQL> set autotrace off
SQL> /
ID NAME
---------- ----------
2 www.ncn.cn
Elapsed: 00:00:00.00
SQL>
从上我们可以看到确实使用了索引。
6、查询v$object_usage(可以看到索引被使用过,但目前还处于被监视过程中)
SQL> select index_name,monitoring,used,start_monitoring,end_monitoring from v$object_usage;
INDEX_NAME MONITORING USED START_MONITORING END_MONITORING
------------ ---------- ---- ------------------- -------------------
TEST_PK YES YES 05/15/2003 13:28:22
Elapsed: 00:00:00.00
7、停止监视,并查询v$object_usage
SQL> alter index test_pk nomonitoring usage;
Index altered.
Elapsed: 00:00:05.03
SQL> select index_name,monitoring,used,start_monitoring,end_monitoring from v$object_usage;
INDEX_NAME MONITORING USED START_MONITORING END_MONITORING
------------ ---------- ---- ------------------- -------------------
TEST_PK NO YES 05/15/2003 13:28:22 05/15/2003 13:40:00
Elapsed: 00:00:00.64
到此为止,监视结束,MONITORING为NO,END_MONITORING给出了时间戳。
二、v$object_usage视图解释
从上面的例子中我们可以看出,索引的监视信息都是存在在v$objec_usage视图中,该视图的定义如下:
CREATE OR REPLACE VIEW SYS.V$OBJECT_USAGE
(
INDEX_NAME,
TABLE_NAME,
MONITORING,
USED,
START_MONITORING,
END_MONITORING
)
AS
select io.name, t.name,
decode(bitand(i.flags, 65536), 0, 'NO', 'YES'),
decode(bitand(ou.flags, 1), 0, 'NO', 'YES'),
ou.start_monitoring,
ou.end_monitoring
from sys.obj$ io, sys.obj$ t, sys.ind$ i, sys.object_usage ou
where io.owner# = userenv('SCHEMAID')
and i.obj# = ou.obj#
and io.obj# = ou.obj#
and t.obj# = i.bo#
/
COMMENT ON TABLE SYS.V$OBJECT_USAGE IS
'Record of index usage'
/
GRANT SELECT ON SYS.V$OBJECT_USAGE TO "PUBLIC"
/
下面是该视图列的描述:
INDEX_NAME: sys.obj$.name 中的索引名字
TABLE_NAME: sys.obj$obj$name 中的表名
MONITORING: YES (索引正在被监控), NO (索引没有被监控)
USED: YES (索引已经被使用过), NO (索引没有被使用过)
START_MONITORING: 开始监控的时间
END_MONITORING: 结束监控的时间
所有被使用过至少一次的索引都可以被监控并显示到这个视图中。
三、监视数据库中所有索引的使用情况
1、生成开始/结束监视索引的SQL脚本:
set heading off
set echo off
set feedback off
set pages 10000
spool start_index_monitor.sql
select 'alter index '||owner||'.'||index_name||' monitoring usage;'
from dba_indexes
where owner in ('YOUR','PROD_DB','OWNER','LIST');
spool off
set heading on
set echo on
set feedback on
------------------------------------------------
set heading off
set echo off
set feedback off
set pages 10000
spool stop_index_monitor.sql
select 'alter index '||owner||'.'||index_name||' nomonitoring usage;'
from dba_indexes
where owner in ('YOUR','PROD_DB','OWNER','LIST');
spool off
set heading on
set echo on
set feedback on
2、进行监视并查询结果:
在业务量比较多的一天上班时运行start_index_monitor.sql,下班前运行stop_index_monitor.sql,之后就可以在各用户自己的v$object_usage视图中看到该SCHEMA下的索引使用情况了:
SQL> conn t/t
Connected.
SQL> select index_name,table_name,used
2 from v$object_usage
3 where used='NO';
INDEX_NAME TABLE_NAME USED
------------ ------------------------------ ----
TEST_PK TEST NO
1 row selected.
SQL>
3、改进结果查寻方法
你也许已经注意到,上面查询结果是需要我们单独查询各SCHEMA中的v$object_usage,其实我们可以通过给v$object_usage视图添加一个owner列来创建一个可以存储所有SHCEMA的v$object_usage视图,不妨叫做v$all_object_usage,定义如下:
CREATE OR REPLACE VIEW SYS.V$ALL_OBJECT_USAGE
(
OWNER,
INDEX_NAME,
TABLE_NAME,
MONITORING,
USED,
START_MONITORING,
END_MONITORING
)
AS
select u.name, io.name, t.name,
decode(bitand(i.flags, 65536), 0, 'NO', 'YES'),
decode(bitand(ou.flags, 1), 0, 'NO', 'YES'),
ou.start_monitoring,
ou.end_monitoring
from sys.obj$ io, sys.obj$ t, sys.ind$ i, sys.object_usage ou, sys.user$ u
where i.obj# = ou.obj#
and io.obj# = ou.obj#
and t.obj# = i.bo#
and io.owner# = u.user#
/
COMMENT ON TABLE SYS.V$ALL_OBJECT_USAGE IS
'Record of all index usage'
/
GRANT SELECT ON SYS.V$ALL_OBJECT_USAGE TO "PUBLIC"
/
CREATE PUBLIC SYNONYM V$ALL_OBJECT_USAGE
FOR SYS.V$ALL_OBJECT_USAGE
/
之后就可以从这个视图中查询相关信息了,下面是示例过程:
----------www.ncn.cn---------示例过程--开始--------------------
SQL> conn sys/sys as sysdba
Connected.
SQL> desc v$all_object_useage
ERROR:
ORA-04043: object v$all_object_useage does not exist
SQL> @/oracle/oracle9/cyx/all_object_usage.sql
SQL> CREATE OR REPLACE VIEW SYS.V$ALL_OBJECT_USAGE
2 (
3 OWNER,
4 INDEX_NAME,
5 TABLE_NAME,
6 MONITORING,
7 USED,
8 START_MONITORING,
9 END_MONITORING
10 )
11 AS
12 select u.name, io.name, t.name,
13 decode(bitand(i.flags, 65536), 0, 'NO', 'YES'),
14 decode(bitand(ou.flags, 1), 0, 'NO', 'YES'),
15 ou.start_monitoring,
16 ou.end_monitoring
17 from sys.obj$ io, sys.obj$ t, sys.ind$ i, sys.object_usage ou, sys.user$ u
18 where i.obj# = ou.obj#
19 and io.obj# = ou.obj#
20 and t.obj# = i.bo#
21 and io.owner# = u.user#
22 /
View created.
SQL> COMMENT ON TABLE SYS.V$ALL_OBJECT_USAGE IS
2 'Record of all index usage'
3 /
Comment created.
SQL> GRANT SELECT ON SYS.V$ALL_OBJECT_USAGE TO "PUBLIC"
2 /
Grant succeeded.
SQL> CREATE PUBLIC SYNONYM V$ALL_OBJECT_USAGE
2 FOR SYS.V$ALL_OBJECT_USAGE
3 /
Synonym created.
SQL> @start_index_monitor.sql
SQL> alter index T.INDEX_CFS monitoring usage;
Index altered.
SQL> alter index T.TEST_PK monitoring usage;
Index altered.
SQL> conn t/t
Connected.
SQL> select * from test where id <5;
ID NAME
---------- ----------
1 aaaaaaaa
2 www.ncn.cn
3 aadfaaaa
4 gototop
4 rows selected.
SQL> conn sys/sys as sysdba
Connected.
SQL> @stop_index_monitor.sql
SQL> alter index T.INDEX_CFS nomonitoring usage;
Index altered.
SQL> alter index T.TEST_PK nomonitoring usage;
Index altered.
SQL> @report_index_usage.sql
SQL> set pages 10000
SQL> set pagesize 200
SQL> set linesize 100
SQL> spool report_index_usage.txt
SQL> ttitle center "--Report of Unused Indexes--"
SQL> select owner,table_name,index_name,used
2 from v$all_object_usage
3 where used='NO';
--Report of Unused Indexes--
OWNER TABLE_NAME INDEX_NAME USED
------------ -------------- ------------ ----
T CFS INDEX_CFS NO
1 row selected.
SQL> spool off
http://www.chinaitlab.com/www/news/article_show.asp?id=12392
Oracle9i引入了具有延续性的初始化参数文件SPFILE(Server Parameter FILE),所谓延续性是指对初始化参数的在线修改可以直接作用到参数文件中,这样所有被修改的参数将永久生效。
SPFILE有以下几个显著优点:
1、“ALTER SYSTEM”所设定的参数可以直接保存在SPFILE中,不像以前那样需要手工更改参数文件才可以使改动永久生效;
2、RMAN支持对SPFILE的备份,在这之前是无法做到使用RMAN来备份初始化参数文件的;
3、可以实现在本地没有远程数据库的INIT.ORA拷贝的时候,远程启动数据库;
4、在RAC的多个实例之间可以共享一个SPFILE
下面我们将详细讨论这几个新特性。
1、SPFILE概述
SPFILE是一个很小的二进制文件,有ORACLE服务器自动维护,位于ORACLE服务器端($ORACLE_HOME/dbs/spfile.ora),因为ORACLE默认就是此SPFILE,所以我们可以通过SQL*PLUS或OEM无需指定初始化参数在客户端远程启动数据库。(8i可以吗?)
2、SPFILE的创建、导出与更新
SYSDBA/SYSOPER(我不知道别人是不是使用SYSOPER,反正我是从来不用这个^_^)可以在数据库处于任何状态下(IDLE/NOMOUNT/MOUNT/OPEN),通过下面的语句来创建一个SPFILE:
CREATE SPFILE[='SPFILE_NAME'] FROM PFILE[='PFILE_NAME'];
而将这个语句反过来就可以通过SPFILE来建立PFILE,ORACLE称之为SPFILE的导出。
CREATE PFILE[='PFILE_NAME'] FROM SPFILE[='SPFILE_NAME'];
导出的文件格式如下:
......
*.background_dump_dest='/oracle/app/oracle/admin/ora9/bdump'
*.compatible='9.2.0.0.0'
*.control_files='/dev/rcon1','/dev/rcon2','/dev/rcon3'
*.core_dump_dest='/oracle/app/oracle/admin/ora9/cdump'
*.db_block_size=8192
*.db_cache_size=3072000000#changed at 20030425
*.db_domain=''
*.db_file_multiblock_read_count=16
*.db_name='ora9'
......
导出SPFILE由两个主要的用途:批量修改参数、作为SPFILE的一种备份方式(如果数据库采用RMAN备份方式,我们可以直接用RMAN来备份SPFILE)。
当批量修改(编辑PFILE)完成后,我们可以通过重新创建SPFILE来实现对SPFILE的更新。
3、参数的修改
对于单个参数的修改,我们可以通过下面的语句来完成:
ALTER SYSTEM SET PARAMETER=value [COMMENT='COMMENT TEXT'][SCOPE=MEMORY|SPFILE|BOTH]
通过SCOPE选项实现了对初始化参数更改的永久性。
对于动态参数,可以加上DEFERRED关键字来标明更改仅对以后的SESSIONS起作用。
SQL> alter system set sort_area_size=104800
2 comment='temporary seting' scope=spfile;
System altered.
4、启动时参数文件的读取顺序
数据库启动时STARTUP默认使用初始化参数文件的顺序是:
[指定的PFILE -->] SPFILE --> $ORACLE_HOME/dbs/PFILE
当然在PFILE中也可以指向SPFILE。
5、读取SPFILE参数设置
我们可以从v$spparameter, v$parameter, v$parameter2中获得相关参数的信息,也依旧可以使用SHOW SGA。
SQL> select name,value,update_comment from v$spparameter
2 where name='sort_area_size';
NAME VALUE UPDATE_COMMENT
-------------------- ------------------------------ --------------------
sort_area_size 104800 temporary seting
6、共享初始化参数文件
在9i RAC中,多个实例可以共享同一个初始化参数文件,而各实例所特有的参数值可以通过在参数前加上实例名称来标示:
hawk19:sort_area_size=104800
hawk29:sort_area_size=102400
关于SPFILE差不多就这些内容了,请继续关注gototop为了你带来的其他Oracle 9i的文章,也欢迎各位网友来信与我讨论和Oracle相关的一些问题。
http://www.chinaitlab.com/www/news/article_show.asp?id=12391
在Oracle 9i里,一个很显著的新特性就是引入了自动的回滚段管理,当使用了AUM (Automatic Undo Management)时,为了区别,名称也由原来的ROLLBACK SEGMENT(回滚段)变成UNDO SEGMENT(撤销段),相对应的是UNDO TABLESPACE。当然我们也可以继续使用传统的MANUAL方式来管理撤销段。
一、初始化参数
使用下面的参数来设置有ORACLE自动管理撤销段:
UNDO_MANAGEMENT = AUTO
ORACLE会自动完成撤销段的创建、删除以及ONLINE/OFFLINE,而DBA将无法干预所有以上操作。
如果想自己来管理回滚段可以将UNDO_MANAGEMENT设成MANUAL(DEFAULT就是MANUAL的)。虽然我们可以在UNDO表空间上创建回滚段,但ORACLE并不建议这样做。
当使用了AUM,我们唯一需要做的就是至少创建一个UNDO表空间,我们可以创建多个UNDO表空间,然后使用下面的参数来指定具体使用哪个。
UNDO_TABLESPACE =UNDORBS1
SQL> l
1* select name ,value from v$parameter where name like 'undo%'
SQL> /
undo_management MANUAL
undo_tablespace UNDOTBS1
undo_suppress_errors FALSE
undo_retention 10800
创建多个UNDO表空间的好处是,我们可以根据不同的应用在不同大小的UNDO表空间之间进行切换。
二、UNDO表空间的创建
1、在建数据库是创建UNDO表空间,具体方法参见本人写的Oracle 9i安装、建库与升级。文章在www.ncn.cn上有下载。
2、我们也可以通过下面的语句来创建:
Create undo tablespace undotbs2 datafile ‘/dev/rundotbs2_1.dbf’ size 100m;
三、UNDO表空间特性
1、UNDO表空间默认就是LOCAL管理方式:
SQL> l
1 select TABLESPACE_NAME, CONTENTS,EXTENT_MANAGEMENT, ALLOCATION_TYPE,
2 SEGMENT_SPACE_MANAGEMENT
3* from dba_tablespaces where contents='UNDO'
SQL> /
TABLESPACE_NAME CONTENTS EXTENT_MANAGEMENT ALLOCATION_TYPE SEGMENT_SPAC
-------------------- ------------------ -------------------- ------------------ ------------
UNDOTBS1 UNDO LOCAL SYSTEM MANUAL
UNDOTBS2 UNDO LOCAL SYSTEM MANUAL
2、除撤销段外,我们不能在UNDO表空间上作其他操作:
SQL> create table gototop_t1(c1 number) tablespace undotbs1;
create table gototop_t1(c1 number) tablespace undotbs1
*
ERROR 位于第 1 行:
ORA-30022: Cannot create segments in undo tablespace
SQL> l
1* create rollback segment ncn_rb1 tablespace undotbs1
SQL> /
create rollback segment ncn_rb1 tablespace undotbs1
*
ERROR 位于第 1 行:
ORA-30019: Illegal rollback Segment operation in Automatic Undo mode
3、一个实例职能使用一个UNDO表空间:
除了在INIT.ORA中指定UNDO表空间外,我们还可以使用下面的语句来在线更改实例所用的UNDO表空间:
SQL> alter system set undo_tablespace=undotbs2;
系统已更改。
四、撤销段的特性
1、撤销段自动创建:
Ø n个撤销段(n基于SESSIONS参数,后面会详细讲)
Ø 名字为_SYSSMUn$
Ø OWNER为PUBLIC(在RAC配置中有用)
Ø 选择AUM后,无法手动管理
SQL> l
1 select owner,segment_name,tablespace_name,status
2* from dba_rollback_segs order by 4
SQL> /
OWNER SEGMENT_NAME TABLESPACE_NAME STATUS
---------- ------------------ -------------------- --------------------------------
PUBLIC _SYSSMU1$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU2$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU3$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU5$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU7$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU9$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU10$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU8$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU6$ UNDOTBS1 OFFLINE
PUBLIC RB1_CYX1 UNDOTBS1 OFFLINE
PUBLIC RB1_CYX UNDOTBS1 OFFLINE
SYS RB1_08 UNDOTBS1 OFFLINE
SYS RB1_07 UNDOTBS1 OFFLINE
SYS RB1_05 UNDOTBS1 OFFLINE
SYS RB1_04 UNDOTBS1 OFFLINE
SYS RB1_03 UNDOTBS1 OFFLINE
SYS RB1_02 UNDOTBS1 OFFLINE
SYS RB1_01 UNDOTBS1 OFFLINE
SYS RB3_06 UNDOTBS3 OFFLINE
SYS RB3_05 UNDOTBS3 OFFLINE
SYS RB3_04 UNDOTBS3 OFFLINE
SYS RB3_03 UNDOTBS3 OFFLINE
SYS RB3_02 UNDOTBS3 OFFLINE
SYS RB3_01 UNDOTBS3 OFFLINE
SYS RB2 INDX OFFLINE
PUBLIC _SYSSMU4$ UNDOTBS1 OFFLINE
SYS SYSTEM SYSTEM ONLINE
PUBLIC _SYSSMU11$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU12$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU13$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU14$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU15$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU16$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU17$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU18$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU19$ UNDOTBS2 ONLINE
PUBLIC _SYSSMU20$ UNDOTBS2 ONLINE
已选择37行。
SQL>
因为我在系统上作测试,之前手动建过回滚段,所以上面返回结果显一般多。
2、只有活动的UNDO表空间上的撤销段和系统回滚段是ONLINE的,其他的撤销段都是OFFLINE的。
这一点从上面的输出中可以清楚地看到。
不过,也不一定一开始所有的撤销段都会ONLINE的,这要依赖于初始化参数SESSIONS的值,默认SESSIONS = 1.1 * PROCESSES + 5,他决定了系统的并发用户数。下面的实验可以让你对这一情况有个明确的认识。
我们将SESSIONS调小后重起数据库,可以看到活动的UNDO表空间UNDOTBS1上共10个撤销段,但只ONLINE了5个。
SQL> show parameter sessions
NAME TYPE VALUE
------------------------------------ ---------------------- -----------
java_max_sessionspace_size integer 0
java_soft_sessionspace_limit integer 0
license_max_sessions integer 0
license_sessions_warning integer 0
logmnr_max_persistent_sessions integer 1
mts_sessions integer 0
sessions integer 27
shared_server_sessions integer 0
SQL> select owner,segment_name,tablespace_name,status
2 from dba_rollback_segs;
OWNER SEGMENT_NAME TABLESPACE_NAM STATUS
------------ -------------------- -------------- ----------
SYS SYSTEM SYSTEM ONLINE
PUBLIC _SYSSMU1$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU2$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU3$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU4$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU5$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU6$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU7$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU8$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU9$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU10$ UNDOTBS1 OFFLINE
PUBLIC _SYSSMU11$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU12$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU13$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU14$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU15$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU16$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU17$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU18$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU19$ UNDOTBS2 OFFLINE
PUBLIC _SYSSMU20$ UNDOTBS2 OFFLINE
SYS RB1_01 UNDOTBS1 OFFLINE
SYS RB1_02 UNDOTBS1 OFFLINE
SYS RB1_03 UNDOTBS1 OFFLINE
SYS RB1_04 UNDOTBS1 OFFLINE
SYS RB1_05 UNDOTBS1 OFFLINE
SYS RB1_07 UNDOTBS1 OFFLINE
SYS RB1_08 UNDOTBS1 OFFLINE
PUBLIC RB1_CYX UNDOTBS1 OFFLINE
PUBLIC RB1_CYX1 UNDOTBS1 OFFLINE
SYS RB2 INDX OFFLINE
SYS RB3_01 UNDOTBS3 OFFLINE
SYS RB3_02 UNDOTBS3 OFFLINE
SYS RB3_03 UNDOTBS3 OFFLINE
SYS RB3_04 UNDOTBS3 OFFLINE
SYS RB3_05 UNDOTBS3 OFFLINE
SYS RB3_06 UNDOTBS3 OFFLINE
已选择37行。
SQL>
五、AUM和RAC
UNDO空间管理方式在RAC中会有一些特殊的要求。
1、RAC所有实例应使用相同UNDO管理模式。
2、不同的实例应使用不同的UNDO表空间,如果没有明确设置不同的UNDO_TABLESPACE参数,每个实例会自动使用第一个可用的UNDO表空间。
六、其它说明
1、当在AUTO模式下进行MANUAL操作时,我们可以设置初始化参数UNDO_SUPPRESS_ERRORS = TRUE来禁止所有报错信息,慎用!
SQL> l
1* alter rollback segment "_SYSSMU6$" online
SQL> /
alter rollback segment "_SYSSMU6$" online
*
ERROR 位于第 1 行:
ORA-30019: Illegal rollback Segment operation in Automatic Undo mode
SQL> alter system set UNDO_SUPPRESS_ERRORS = TRUE;
系统已更改。
SQL> alter rollback segment "_SYSSMU6$" online;
回退段已变更。
SQL>
这条语句看起来是操作成功了,但实际上什么事也没有干!
SQL> select owner,segment_name,tablespace_name,status
2 from dba_rollback_segs where status ='ONLINE';
OWNER SEGMENT_NAME TABLESPACE_NAM STATUS
------------ -------------------- -------------- ---------------
SYS SYSTEM SYSTEM ONLINE
PUBLIC _SYSSMU1$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU2$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU3$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU4$ UNDOTBS1 ONLINE
PUBLIC _SYSSMU5$ UNDOTBS1 ONLINE
已选择6行。
SQL>
2、和手动删除了回滚段一样,查询事务信息如果位于已删除的UNDO表空间时,而快照又比UNDO表空间的DROP-SCN旧,同样会报ORA-01555 "snapshot too old (rollback segment too small)"错。
七、个人看法
无论是叫做ROLLBACK SEGMENT(回滚段)也好,还是叫做UNDO SEGMENT(撤销段)也好,作为用户,我们最关心的是给我们到底带来什么好处。正如Oracle所宣传的那样,自动管理确实给用户减轻了不少管理工作,但是作为企业级应用,我们不仅要考虑管理的复杂性,更要考虑它的性能问题,而在我们所进行的项目测试过程中,发现自动管理并不理想。
也就是说,自动管理是以性能为代价来减少管理的复杂性,这无疑会给用户以鸡肋的感觉。到目前为止我还没有发现一个合理解释,不知道在下一个版本中会不会在性能上有个很大的提高。
在这种情况下,是否采用自动管理?如何选择完全看你自己了。
http://www.chinaitlab.com/www/news/article_show.asp?id=12390
我们都知道在9i之前,要想获得建表和索引的语句是一件很麻烦的事。我们可以通过export with rows=no来得到,但它的输出因为格式的问题并不能直接拿来用。而另一种方法就是写复杂的脚本来查询数据字典,但这对于一稍微复杂的对象,如IOT和嵌套表等,还是无法查到。
从数据字典中获得DDL语句是经常要用的,特别是在系统升级/重建的时候。在Oracle 9i中,我们可以直接通过执行dbms_metadata从数据字典中查处DDL语句。使用这个功能强大的工具,我们可以获得单个对象或整个SCHEMA的DDL语句。最好不过的是因为它使用起来很简单。
1、获得单个表和索引DDL语句的方法:
-----------------------------------------------------------------------
set heading off;
set echo off;
Set pages 999;
set long 90000;
spool get_single.sql
select dbms_metadata.get_ddl('TABLE','SZT_PQSO2','SHQSYS') from dual;
select dbms_metadata.get_ddl('INDEX','INDXX_PQZJYW','SHQSYS') from dual;
spool off;
-----------------------------------------------------------------------
下面是输出。我们只要把建表/索引语句取出来在后面加个分号就可以直接运行了。
-----------------------------------------------------------------------
SQL> select dbms_metadata.get_ddl('TABLE','SZT_PQSO2','SHQSYS') from dual;
CREATE TABLE "SHQSYS"."SZT_PQSO2"
( "PQBH" VARCHAR2(32) NOT NULL ENABLE,
"ZJYW" NUMBER(10,0),
"CGSO" NUMBER(10,0) NOT NULL ENABLE,
"SOLS" VARCHAR2(17),
"SORQ" VARCHAR2(8),
"SOWR" VARCHAR2(8),
"SOCL" VARCHAR2(6),
"YWHM" VARCHAR2(10),
"YWLX" VARCHAR2(6)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA1"
SQL> select dbms_metadata.get_ddl('INDEX','INDXX_PQZJYW','SHQSYS') from dual;
CREATE INDEX "SHQSYS"."INDXX_PQZJYW" ON "SHQSYS"."SZT_PQSO2" ("ZJYW")
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "DATA1"
SQL>
SQL> spool off;
-----------------------------------------------------------------------
2、获得整个SCHEMA DDL语句的方法:
-----------------------------------------------------------------------
set pagesize 0
set long 90000
set feedback off
set echo off
spool get_schema.sql
connect shqsys/shqsys@hawk1;
SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name)
FROM USER_TABLES u;
SELECT DBMS_METADATA.GET_DDL('INDEX',u.index_name)
FROM USER_INDEXES u;
spool off;
-----------------------------------------------------------------------
需要注意的是,当我们的表中有外健(参照约束)时,我们需要判别参照表之间的顺序,确保重建时按照合理的顺序进行。你可以通过查询dba_constraints and dba_cons_columns来确定各表之间的顺序,不再详述。
http://www.chinaitlab.com/www/news/article_show.asp?id=12389
简单陈述一下:
针对每个session,排序首先会使用sort_area_size ,如果不足则会使用临时表空间。但这里面又到底是怎么一个过程呢?下面阐述一下,也许对大家有用处(如果有什么不清楚或者不恰当的地方欢迎大家探讨)
假设sort_area_size = 100k,正好能盛下100条记录进行排序
当排序记录小于等于100条,ok,所有排序在内存中进行,很快 但若超过100条,则会使用临时表空间(利用磁盘进行) 我们选取一个临界值来说明,假设需要排序的记录有10010条
这个时候我们进行的排序会分为101组进行 每读100条进行一次小组排序,然后写入磁盘,第101组只有10条,排序后也写入磁盘
这是进行第二次排序,这次排序将在前100小组里面各抽取一条进行排序。《按照我个人的猜测,应该是排好后每写入一条入磁盘则将该记录所在小组重新抽取一条出来进行排序(这时是有序记录组里面所以很快)》。当这个过程完成后,这时所需要的磁盘空间大约为 实际记录存储空间的2倍(这也是多数书上提到的排序空间大约是记录空间的2倍的原因)
由于还剩下10条记录,于是这10条记录需要跟前面排序的10000条记录进行排序合并,这个代价也是相当大的!
所以,我们通常推荐,假如你需要排序的记录最大为100万条,则sort_area_size最小要能装下1000条,否则如上面的例子,那多余的10条,仅仅10条将会带来巨大的代价!
如果,设置的极度不合理的情况下,排序记录达到了 sort_area_size所能容纳的三次方以上,比如上面例子中排序需要100万记录 那么同样的,重复这个过程,当每一万条记录如上排序后,再如上从这100小组(每组10000条记录)各抽一条进行排序……
在这个过程中,磁盘的消耗和时间的代价大家都应该有个感性认识了 所以,我们建议: sprt_area_size 所能容纳记录数至少大于排序记录数的 平方根
oracle文档 http://download-west.oracle.com/docs/cd/A87861_01/NT817EE/index.htm
http://www.chinaitlab.com/www/news/article_show.asp?id=5978
在9i之前,如果一个数据库用户没有被指定默认临时表空间,那么oracle就会使用system表空间作为该用户的临时表空间,这是很危险的。在9i里面,database可以被指定一个默认临时表空间。这样如果数据库用户没有被明确指定临时表空间,oracle 9i就会自动指定database的默认临时表空间作为该用户的临时表空间。 我们可以通过下面的语句来查询数据库的默认临时表空间: SQL> select * from database_properties where property_name = 'DEFAULT_TEMP_TABLESPACE';  默认临时表空间的限制: 1. 默认临时表空间必须是TEMPORARY的: SQL> alter database default temporary tablespace tools; alter database default temporary tablespace tools * ERROR at line 1: ORA-12902: default temporary tablespace must be SYSTEM or of TEMPORARY type 2. 默认临时表空间一旦被指定,将无法在改成PERMANET: SQL> alter tablespace temp2 permanent; alter tablespace temp2 permanent * ERROR at line 1: ORA-12904: default temporary tablespace cannot be altered to PERMANENT type 3. 在删除默认临时表空间必须先重新指定默认临时表空间: SQL> drop tablespace temp including contents and datafiles; drop tablespace temp including contents and datafiles * ERROR at line 1: ORA-12906: cannot drop default temporary tablespace SQL> create tablespace TEMP2 2 datafile '/data1/ora9data/temp2_01.dbf' 3 size 100k TEMPORARY; Tablespace created. SQL> alter database default temporary tablespace TEMP2; Database altered. SQL> drop tablespace temp including contents and datafiles; Tablespace dropped. 4. 默认临时表空间无法OFFLINE: SQL> alter tablespace temp offline; alter tablespace temp offline * ERROR at line 1: ORA-12905: default temporary tablespace cannot be brought OFFLINE 5. 用户的临时表空间必须是TEMPORARY的(在9i之前没有这个限制,可以是PERMANENT): SQL> alter user scott temporary tablespace TOOLS; alter user scott temporary tablespace TOOLS * ERROR at line 1: ORA-12911: permanent tablespace cannot be temporary tablespace SQL> create tablespace temp2 2 datafile '/data1/ora9data/temp2_01.dbf' 3 size 100k temporary; Tablespace created. SQL> alter user scott temporary tablespace temp2; User altered. 6. 如果删除了用户的临时表空间,而这个临时表空间又不是数据库的默认临时表空间(如果是数据库的默认临时表空间是删不掉的),用户的临时表空间不会自动转换到数据库的默认临时表空间上: SQL> select tablespace_name, contents from dba_tablespaces where tablespace_name like 'TEMP%';  SQL> drop tablespace TEMP2 including contents and datafiles; Tablespace dropped. SQL> select TEMPORARY_TABLESPACE from dba_users where username='SCOTT'; TEMPORARY_TABLESPACE ------------------------------ TEMP2
- 系统环境:
1、操作系统:Windows 2000 2、数据库: Oracle 8i R2 (8.1.6) for NT 企业版 3、安装路径:C:\ORACLE
- 解释:

可用于:表空间、回滚段、表、索引、分区、快照、快照日志
参数名称 |
缺省值 |
最小值 |
最大值 |
说明 |
INITIAL |
5(数据块) |
2(数据块) |
操作系统限定 |
分配给Segment的第一个Extent的大小,以字节为单位,这个参数不能在alter语句中改变,如果指定的值小于最小值,则按最小值创建。 |
NEXT |
5(数据块) |
1(数据块) |
操作系统限定 |
第二个Extent的大小等于NEXT的初值,以后的NEXT值=前一NEXT大小乘以(1+PCTINCREASE/100),如果指定的值小于最小值,则按最小值创建。 如果在alter语句中改变NEXT的值,则下一个分配的Extent将具有指定的大小,而不管上一次分配的Extent大小和PCTINCREASE参数值。 |
MINEXTENTS |
1(Extent) 回滚段为2个Extent |
1(Extent) 回滚段为2个Extent |
操作系统限定 |
Segment第一次创建时分配的Extent数量 |
MAXEXTENTS |
根据数据块大小而定 |
1(Extent) 回滚段为2个Extent |
无限制 |
随着Segment中数据量的增长,最多可分配的Extent数量 |
PCTINCREASE |
50%
(Oracle816中为0%) |
0% |
操作系统限定 |
指定第三个及其后的Extent相对于上一个Extent所增加的百分比, 如果PCTINCREASE为0,则Segment中所有新增加的Extent的大小都相同,等于NEXT的值, 如果PCTINCREASE大于0,则每次计算NEXT的值(用上面的公式), PCTINCREASE不能为负数。 创建回滚段时,不可指定此参数,回滚段中此参数固定为0。 |
OPTIMAL |
---- |
不能小于回滚段初始分配空间 |
操作系统限定 |
仅与回滚段有关,当回滚段因为增长、扩展而超过此参数的设定范围时,Oracle系统会根据情况动态地重新分配Extents,试图收回多分配的Extent。 |
|
FREELISTS |
1 |
1 |
数据块大小限制 |
只能在CREATE TABLE、CLUSTER、INDEX中指定FREELISTS和FREELIST GROUPS参数。 模式对象中每一个自由列表组中自由列表的数量 |
FREELIST GROUPS |
1 |
1 |
取决于Oracle并行实例的数量 |
用户创建的数据库对象的自由列表组的数量,只有用OPS并行服务器选项时才使用这一参数,一个实例对应一个组。 |
BUFFER_POOL |
---- |
---- |
---- |
给模式对象定义缺省缓冲池(高速缓存),该对象的所有块都存储在指定的高速缓存中,对于表空间或回滚段无效。 |
建议PCTINCREASE参数设置为0,可使碎片最小化,使每一个Extent都相同(等于NEXT值)
一旦建立了某个对象,它的INITIAL和MINEXTENTS参数不能修改(Oracle 816中可修改MINEXTENTS参数)
对于NEXT和PCTINCREASE的任何修改都只影响后来分配的那些Extent
在分配一个新Extent时,系统直接按NEXT的值分配一个Extent,
然后用公式:前一NEXT值*(1+PCTINCREASE/100) 计算出下一个应该分配的Extent的大小,
并把计算结果保存到相关数据字典的NEXT_EXTENT列上,做为下一个应该分配的Extent的大小。
CREATE TABLE test(a number)
STORAGE(
INITIAL 100K
NEXT 100K
MINEXTENTS 2
MAXEXTENTS 100
PCTINCREASE 100);
解释:
初始给test表分配两个Extent,
第一个Extent是100K,因INITIAL=100K
第二个Extent是100K,因NEXT=100K
如果因表内数据增长,需要分配第三个Extent,因PCTINCREASE是100,则
第三个Extent是200K=100K+100K
第四个Extent是400K=200K+200K
可通过数据字典表DBA_TABLES、ALL_TABLES、USER_TABLES查看参数设置情况,如:
select table_name,initial_extent,next_extent,min_extents,max_extents,pct_increase from user_tables;
TABLE_NAME INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS PCT_INCREASE
---------- -------------- ----------- ----------- ----------- ------------
TEST 106496 212992 2 100 100
http://www.chinaitpower.com/A200507/2005-07-27/177759.html
http://www.chinaitlab.com/www/news/article_show.asp?id=37456
网上很少有OCI的中文文档,一般英文文档大家可能看了也不太顺,我整理了一份,写了一些常用的OCI函数,供大家参考。 因为无法加附件,只好把内容贴上来了 一. Oracle oci工具包安装: $ORACLE_HOME\BIN:执行文件和help文件 $ORACLE_HOME\OCI\INCLUDE:头文件 $ORACLE_HOME\OCI\LIB\BC: for Borlanf C++的OCI库 $ORACLE_HOME\OCI\LIB\MSVC: for MS Visual C++的OCI库
如果是unix下,对于ORACLE8i,则OCI库在$ORACLE_HOME/lib下,如果是9i,则在$ORACLE_HOME/lib32下,库文件名一般为libclntsh.so 1. 创建OCI环境即创建和初始化OCI工作环境,其他的OCI函数需要OCI环境才能执行。 2. 需要申请的句柄类型: OCI环境句柄: OCI_HTYPE_ENV—它定义所有OCI函数的环境调用环境,是其他句柄的父句柄。(由OCIEnvInit或OCIEnvCreate生成) 错误句柄:OCI_HTYPE_ERROR—作为一些OCI函数的参数,用来记录这些OCI函数操作过程中所产生的错误,当有错误发生时,可用COIErrorGet()来读取错误句柄 中记录的错误信息。 服务器环境句柄:OCI_HTYPE_SVCCTX—定义OCI调用的服务器操作环境,它包含服务器、用户会话和事务三种句柄。 服务器句柄:OCI_HTYPE_SERVER—标识数据源,它转换为与服务器的物理连接。 用户会话句柄:OCI_HTYPE_SESSION—定义用户角色和权限及OCI调用的执行环境。 事务句柄:OCI_HTYPE_TRANS—定义执行SQL操作的事务环境,事务环境中包含用户的会话状态信息。 语句句柄:OCI_HTYPE_STMT—是一个标识SQL语句或PL/SQL块,以及其相关属性的环境。 Bind/Define句柄:属于语句句柄的子句柄,由OCI库隐式自动生成。用户不需要自己再申请,OCI输入变量存储在bind 句柄中,输出变量存储在定义句柄中
3. 句柄属性包括: 服务器环境句柄属性:(OCI_HTYPE_SVCCTX) OCI_ATTR_SERVER—设置/读取服务环境的服务器环境属性 OCI_ATTR_SESSION—设置/读取服务环境的会话认证环境属性 OCI_ATTR_TRANS—设置/读取服务环境的事务环境属性 用户会话句柄属性:(OCI_HTYPE_SESSION) OCI_ATTR_USERNAME—设置会话认证所使用的用户名 OCI_ATTR_PASSWORD—设置会话认证所使用的用户口令 服务器句柄:(OCI_HTYPE_SEVER) OCI_ATTR_NOBLOCKING_MODE—设置/读取服务器连接:=TRUE时服务器连接设置为非阻塞方式 语句句柄:(OCI_HTYPE_STMT) OCI_ATTR_ROW_COUNT—只读,为当前已处理的行数,其default=1 OCI_ATTR_STMT_TYPE—读取当前SQL语句的类型: Eg : OCI_STMT_BEGIN OCI_STMT_SELECT OCI_STMT_INSERT OCI_STMT_UPDATE OCI_STMT_DELETE OCI_ATTR_PARAM_COUNT—返回语句选择列表中的列数 4. 关于输出变量定义:如果在语句执行前就知道select语句的选择列表结构,则定义输出操作可在调用 OCISTMTExecute前进行,如果查询语句的参数为用户动态输入的,则必须在执行后定义。 5. OCI函数返回值: OCI_SUCCESS –函数执行成功 (=0) OCI_SUCCESS_WITH_INFO –执行成功,但有诊断消息返回,可能是警告信息 OCI_NO_DATA—函数执行完成,但没有其他数据 OCI_ERROR—函数执行错误 OCI_INVALID_HANDLE—传递给函数的参数为无效句柄,或传回的句柄无效 OCI_NEED_DATA—需要应用程序提供运行时刻的数据 OCI_CONTINUE—回调函数返回代码,说明回调函数需要OCI库恢复其正常的处理操作 OCI_STILL_EXECUTING—服务环境建立在非阻塞模式,OCI函数调用正在执行中。 6. OCI连接有二种方式:Blocking(阻塞方式)和non_Blocking(非阻塞方式),阻塞方式就是当调用 OCI操作时,必须等到此OCI操作完成后服务器才返回客户端相应的信息,不管是成功还是失败。非阻塞方式是当客户端提交OCI操作给服务器后,服务器立即返回OCI_STILL_EXECUTING信息,而并不等待服务端的操作完成。 对于non-blocking方式,应用程序若收到一个OCI函数的返回值为 OCI_STILL_EXECUTING时必须再次对每一个OCI函数的返回值进行判断,判断其成功与否。 可通过设置服务器属性为OCI_ATTR_NONBLOCKING_MODE来实现。系统默认方式为阻塞模式. 7. OCI函数设置的模式有: OCI_DEFUALT:使用OCI默认的环境 OCI_THREADED:线程环境下使用OCI OCI_OBJECT:对象模式 OCI_SHARED:共享模式 OCI_EVENTS OCI_NO_UCB OCI_ENV_NO_MUTEX:非互斥访问模式 其中模式可以用逻辑运算符进行迭加,将函数设置成多多种模式:如mode=OCI_SHREADED| OCI_OBJECT
8. 当应用进程与服务器断开连接时,程序没有使用OCITransCommit()进行事务的提交,则所有活动的事务会自动回滚。 9. OCI重定义数据类型 typedef unsigned char ub1; typedef signed char sb1; typedef unsigned short ub2; typedef signed short sb2; typedef unsigned int ub4; typedef signed int sb4; typedef ub4 duword; typedef sb4 dsword; typedef dsword dword;
10. 在SQL语句准备后,可以用OCIAttrSet(0设置该语句的类型属性OCI_ATTR_STMT_TYPE,以后可读取语句属性,根据属性分别进行处理。 11. 批量绑定输入和定义输出参数:将数据存入一个静态数据组中。一次执行可以提交或读取多行记录值。 12. 结合占位符和指示器变量: 占位符:在程序中,一些SQL语句需要在程序运行时才能确定它的语句数据,在设计时可用一个占位符来代替,当程序运行时,在它准备好语句后,必须为每个占位符指定一个变量,即将占位符与程序变量地址结合,执行时,Oracle就从这些变量中读取数据,并将它们与SQL语句一起传递给Oracle服务器执行。OCI结合占位符时,它将占位符与程序变量关联起来,并同时要指出程序变量的数据类型和数据长度。 如:select * from test where name=:p1 and age>;:p2 :p1和:p2为占位符
指示器变量:由于在Oracle中,列值可以为NULL,但在C语言中没有NULL值,为了能使OCI程序表达NULL列值,OCI函数允许程序为所执行语句中的结合变量同时关联一个指示符变量或指示符变量数组,以说明所结合的占位符是否为NULL或所读取的列值是否为NULL,以及所读取的列值是否被截取。 除SQLT_NTY(SQL Named DataType)外,指示符变量或指示符变量数组的数据类型为sb2,其值说明: 作为输入变量时:(如insert ,update语句中) =-1:OCI程序将NULL赋给Oracle表的列,忽略占位符结合的程序变量值 >;=0:应用程序将程序变量值赋给指定列 作为输出变量时:(如select语句中) =-2:所读取的列数据长度大于程序变量的长度,则被截取。 =-1:所读取的值为NULL,输出变量的值不会被改变。 =0:数据被完整读入到指定的程序变量中 >0:所读取的列数据长度大于程序变量的长度,则被截取,指示符变量值为所读取数据被截取前的实际长度 三. OCI函数说明 注:红色为输入参数 蓝色为输出参数 ,否则为输入/出参数
示例以下面结构作为说明 sword swResult; OCIBind* hBind; OCIDefine* hDefine; OCIStmt *stmtp OCIError *errhp; OCIStmt *stmtp OCISvcCtx * svchp OCIEnv * envhpp; OCISession * usrhp; sb2 sb2aInd[30]; //指示器变量,用于取可能存在空值的字段 Typedef strcut { char tname[40]; int age; } t_std; typedef struct { sb2 sb2_tname[100]; sb2 sb2_age[100]; } stdInd_T; //指示器数组 typedef struct { ub2 ub2_tname[100]; ub2 ub2_age[100]; } stdLen_T; //字段长度
t_std tstd[100]; //数组变量,用于批量操作 stdInd_T tstdInd; stdLen_T tstdLen; stdLen_T tstdRet;
t_std std;
各函数数明 1.创建OCI环境 sword OCIEnvCreate( OCIEnv **envhpp, //OCI环境句柄指针 ub4 mode, //初始化模式:OCI_DEFAULT/OCI_THREADED 等 CONST dvoid *ctxp, CONST dvoid *(*malicfp)(dvoid *ctxp,size_t size), CONST dvoid *(ralocfp)(dvoid *ctxp,dvoid *memptr,size_t newsize), CONST void *(*mfreefp)(dvoid *ctxp,dvoid *memptr), Size_t xstramemsz, Dvoid **usrmempp ) eg : swResult = OCIEnvCreate(&envhpp, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL); if(swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) return FALSE;
sword OCIInitialize ( ub4 mode, CONST dvoid *ctxp, CONST dvoid *(*malocfp) (/* dvoid *ctxp, size_t size _*/), CONST dvoid *(*ralocfp) (/*_ dvoid *ctxp, dvoid *memptr, size_t newsize _*/), CONST void (*mfreefp) (/*_ dvoid *ctxp, dvoid *memptr _*/) );
sword OCIEnvInit ( OCIEnv **envhpp, ub4 mode, size_t xtramemsz, dvoid **usrmempp ); 注: 在8i以后,可用OCIEnvCreate一个函数就可以初始化环境了,相当于OCIInitialize+ OCIEnvInit 2.申请/释放句柄 sword OCIHandleAlloc( CONST dvoid *parenth, //新申请句柄的父句柄,一般为OCI环境句柄 Dvoid **hndlpp, //申请的新句柄 Ub4 type, type, //句柄类型 Size_t xtramem_sz, //申请的内存数 Dvoid **usrmempp //申请到的内存块指针 ) 注: 一般需要申请的句柄有: 服务器句柄OCIServer, 句柄类型OCI_HTYPE_SERVER 错误句柄OCIError,用于捕获OCI错误信息, 句柄类型OCI_HTYPE_ERROR 事务句柄OCISession, 句柄类型OCI_HTYPE_SESSION 上下文句柄OCISvcCtx, 句柄类型OCI_HTYPE_SVCCTX SQL语句句柄OCIStmt, 句柄类型OCI_HTYPE_STMT eg: 申请一个错误句柄OCIError swResult = OCIHandleAlloc(envhpp, (dvoid *)& errhp, OCI_HTYPE_ERROR, 0, NULL); if(swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) { return FALSE; } 释放句柄 sword OCIHandleFree( dvoid *hndlp, //要释放的句柄 ub4 type //句柄类型 )
eg: OCIHandleFree(stmtp, OCI_HTYPE_STMT) 3.读取/设置句柄属性 sword OCIAttrSet( dvoid *trgthndlp, //需设置的句柄名 ub4 trghndltyp, //句柄类型 dvoid *attributep, //设置的属性名 ub4 size, //属性值长度 ub4 attrtype, //属性类型 OCIError *errhp //错误句柄 ) 注:一般要设置的属性有: 服务器实例: 句柄类型OCI_HTYPE_SVCCTX,属性类型OCI_ATTR_SERVER 连接数据的用户名: 句柄类型OCI_HTYPE_SESSION,属性类型OCI_ATTR_USERNAME 用户密码 句柄类型OCI_HTYPE_SESSION,属性类型OCI_ATTR_PASSWORD 事务: 句柄类型OCI_HTYPE_SVCCTX,属性类型OCI_ATTR_SESSION
eg:设置用户名和密码 char username[20],passwd[20]; strcpy(username,”tiger”) strcpy(passwd,”cotton”) swResult = OCIAttrSet(usrhp, OCI_HTYPE_SESSION, (text*) username, strlen(username), OCI_ATTR_USERNAME, errhp); if(swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) return FALSE; swResult = OCIAttrSet(usrhp, OCI_HTYPE_SESSION, (text*) passwd, strlen(passwd), OCI_ATTR_PASSWORD, errhp); if(swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) return FALSE;
sword OCIAttrGet( dvoid *trgthndlp, //需读取的句柄名 ub4 trghndltyp, //句柄类型 dvoid *attributep, //读取的属性名 ub4 *sizep, //属性值长度 ub4 attrtype, //属性类型 OCIError *errhp //错误句柄 )
4.连接/断开服务器 多用户方式连接: sword OCIServerAttach( OCIServer *srvhp,//未初始化的服务器句柄 OCIError *errhp, CONST text *dblink,//服务器SID sb4 dblink_len, ub4 mode //=OCI_DEFAULT,系统环境将设为阻塞方式 );
sword OCIServerDetach ( OCIServer *srvhp, OCIError *errhp, ub4 mode //OCI_DEFAULT ); 单用户方式连接: sword OCILogon ( OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, CONST text *username, ub4 uname_len, CONST text *password, ub4 passwd_len, CONST text *dbname, ub4 dbname_len ); sword OCILogoff ( OCISvcCtx *svchp OCIError *errhp );
5.开始/结束一个会话 先认证用户再建立一个会话连接 sword OCISessionBegin ( OCISvcCtx *svchp, //服务环境句柄 OCIError *errhp, OCISession *usrhp, //用户会话句柄 ub4 credt, //认证类型 ub4 mode //操作模式 );
*认证类型: OCI_CRED_RDBMS:用数据库用户名和密码进行认证,则先要设置OCI_ATTR_USERNAME和OCI_ATTR_PASSWORD属性 OCI_CRED_EXT:外部认证,不需要设置用户和密码 OCI_DEFAULT:用户会话环境只能被指定的服务器环境句柄所设置 OCI_SYSDBA:用户要具有sysdba权限 OCI_SYSOPER:用户要具有sysoper权限
Eg: swResult = OCISessionBegin(svchp, errh,usrhp, OCI_CRED_RDBMS, OCI_DEFAULT); if(swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) return FALSE;
sword OCISessionEnd ( OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, ub4 mode ); 6.读取错误信息 sword OCIErrorGet ( dvoid *hndlp, //错误句柄 ub4 recordno,//从那里读取错误记录,从1开始 text *sqlstate,//已取消,=NULL sb4 *errcodep, //错误号 text *bufp, //错误内容 ub4 bufsiz, //bufp长度 ub4 type //传递的错误句柄类型 =OCI_HTYPE_ERROR:错误句柄 =OCI_HTYPE_ENV:环境句柄 ); eg: ub4 ub4RecordNo = 1; OCIError* hError sb4 sb4ErrorCode; char sErrorMsg[1024];
if (OCIErrorGet(hError, ub4RecordNo++, NULL, &sb4ErrorCode, (OraText*) sErrorMsg, sizeof(sErrorMsg), OCI_HTYPE_ERROR) == OCI_SUCCESS) printf(“error msg:%s\n”, sErrorMsg);
7.准备SQL语句 sword OCIStmtPrepare ( OCIStmt *stmtp,//语句句柄 OCIError *errhp, CONST text *stmt, //SQL语句 ub4 stmt_len, //语句长度 ub4 language, //语句的语法格式=OCI_NTV_SYNTAX ub4 mode //=OCI_DEFAULT );
eg: char sSQL[1024];
sprintf(sSQL, “select table_name from user_tables”);
swResult = OCIStmtPrepare(stmtp errhp, (CONST OraText*)sSQL, strlen(sSQL), OCI_NTV_SYNTAX, OCI_DEFAULT); if(swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) return FALSE;
8. 绑定输入参数 OCIBindArrayOfStruct() Set skip parameters for static array bind ,数组绑定,一般用于批量操作 OCIBindByName() Bind by name 按名绑定 OCIBindByPos() Bind by position 按位置绑定,建议一般按此方式绑定 OCIBindDynamic() Sets additional attributes after bind with OCI_DATA_AT_EXEC mode OCIBindObject() Set additional attributes for bind of named data type
注: OCIBindArrayOfStruct必须先用OCIBindByPos初始化,然后在OCIBindArrayOfStruct中定义每个参数所跳过的字节数。 如:
存储方式:
第一条记录第二条记录 N
SkipPara(实际就是结构体长度,即本次所有列的长度和)
sword OCIBindByName ( OCIStmt *stmtp, //语句句柄 OCIBind **bindpp,//结合句柄,=NULL OCIError *errhp, CONST text *placeholder,//占位符名称 sb4 placeh_len, //占位符长度 dvoid *valuep, //绑定的变量名 sb4 value_sz, //绑定的变量名长度 ub2 dty, //绑定的类型 dvoid *indp, //指示符变量指针(sb2类型),单条绑定时为NULL, ub2 *alenp, //说明执行前后被结合的数组变量中各元素数据实际的长度,单条绑定时为NULL ub2 *rcodep,//列级返回码数据指针,单条绑定时为NULL ub4 maxarr_len, //最多的记录数,如果是单条绑定,则为0 ub4 *curelep, //实际的记录数,单条绑定则为NULL ub4 mode //=OCI_DEFAULT );
sword OCIBindByPos ( OCIStmt *stmtp, OCIBind **bindpp, OCIError *errhp, ub4 position,// 绑定的位置 dvoid *valuep, sb4 value_sz, ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, ub4 maxarr_len, ub4 *curelep, ub4 mode );
sword OCIBindArrayOfStruct ( OCIBind *bindp,//绑定的结构句柄,由OCIBindByPos定义 OCIError *errhp, ub4 pvskip, //下一列跳过的字节数** ub4 indskip,//下一个指示器或数组跳过的字节数 ub4 alskip, //下一个实际值跳过的字节数 ub4 rcskip //下一个列级返回值跳过的字节数 );
例: sword swResult; OCIBind* hBind; Ub4 rec_num; Sql: insert into student values (:p1,:p2)
单条绑定: hBind = NULL; swResult = OCIBindByPos(stmtp &hBind, errhp,1,ststd.tname, sizeof(ststd.tname), SQLT_CHR, NULL, NULL,NULL,0, NULL, OCI_DEFAULT);
批量取数据,一次取100条 Sql: select username,age from student where username=:p1 and age=:p2
hBind = NULL; swResult = OCIBindByPos(stmtp &hBind, errhp,1,tstd[0].tname, sizeof(tstd[0].tname), SQLT_CHR, &tstdInd.sb2_usernmae[0], &tstdLen.ub2_username[0],&tstdRet.ub2_username[0],100, &rec_num, OCI_DEFAULT); swResult = OCIBindArrayOfStruct(hBind, errhp,sizeof(tstd [0]), sizeof(sb2), sizeof(ub2), sizeof(ub2));
9.执行SQL语句 sword OCIStmtExecute ( OCISvcCtx *svchp, //服务环境句柄 OCIStmt *stmtp, //语句句柄 OCIError *errhp, ub4 iters, // ** ub4 rowoff, //** CONST OCISnapshot *snap_in, OCISnapshot *snap_out, ub4 mode //** ); **注: 1. iters:对于select语句,它说明一次执行读取到buffer中的记录行数,如果不能确定select语句所返回的行数,可将iters设置为0,而对于其他的语句,iters表示这些语句的执行次数,此时iters不能为0。 2. rowoff:在多行执行时,该参数表示从所结合的数据变量中的第几条记录开始执行(即记录偏移量)。 3. mode:=OCI_DEFAULT:default模式 =OCI_DESCRIBE_ONLY:描述模式,只返回选择列表的描述信息,而不执行语句 =OCI_COMMIT_ON_SUCCESS:自动提交模式,当执行成功后,自动提交。 =OCI_EXACT_FETCH:精确提取模式。 =OCI_BATCH_ERRORS:批错误执行模式:用于执行数组方式的操作,在此模式下,批量insert ,update,delete时,执行过程中任何一条记录错误不会导致整个insert ,update,delete失败,系统自动会收集错误信息,而在非批错误方式下,其中的任何一条记录错误,将会导致整个操作失败。 Eg: 执行一次 swResult = OCIStmtExecute(svchp, stmtp, errhp;, 1, 0, NULL, NULL, OCI_DEFAULT); 批量执行100次: swResult = OCIStmtExecute(svchp, stmtp, errhp;, 100, 0, NULL, NULL, OCI_DEFAULT);
10.定义输出变量 OCIDefineArrayOfStruct() Set additional attributes for static array define OCIDefineByPos() Define an output variable association OCIDefineDynamic() Sets additional attributes for define in OCI_DYNAMIC_FETCH mode OCIDefineObject() Set additional attributes for define of named data type
sword OCIDefineByPos ( OCIStmt *stmtp, //语句句柄 OCIDefine **defnpp,//定义句柄—用于数组变量 OCIError *errhp, ub4 position,//位置序号(从1 开始) dvoid *valuep, //输出的变量名 sb4 value_sz, //变量长度 ub2 dty, //数据类型 dvoid *indp, //指示器变量/指示器变量数组,如果此字段可能存在空值,则要指示器变量,否则单条处理时为NULL ub2 *rlenp, //提取的数据长度 ub2 *rcodep, //列级返回码数组指针 ub4 mode //OCI_DEFAULT );
sword OCIDefineArrayOfStruct ( OCIDefine *defnp,//由OCIDefineByPos定义的句柄 OCIError *errhp, ub4 pvskip, //下一列跳过的字节数,一般就是结构的大小 ub4 indskip,//下一个指示器或结构跳过的字节数,=0 ub4 rlskip, //下一个实际值跳过的字节数,=0 ub4 rcskip //下一个列列级返回值跳过的字节数,=0 );
sword OCIDefineDynamic ( OCIDefine *defnp, OCIError *errhp, dvoid *octxp, OCICallbackDefine (ocbfp)(/*_ dvoid *octxp, OCIDefine *defnp, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodep _*/) );
sword OCIDefineObject ( OCIDefine *defnp, OCIError *errhp, CONST OCIType *type, dvoid **pgvpp, ub4 *pvszsp, dvoid **indpp, ub4 *indszp );
eg: 单条查询 sql: select username,age from student where username=:p1; 如果此字段有可能有空值,则 hDefine = NULL; swResult = OCIDefineByPos(stmtp &hDefine, errhp, 1, tstd.username, sizeof(tstd.username), SQLT_CHR, & sb2aInd[0], NULL, NULL, OCI_DEFAULT); 如果此字段没有空值,则 hDefine = NULL; swResult = OCIDefineByPos(stmtp &hDefine, errhp, 1, tstd.username, sizeof(tstd.username), SQLT_CHR, NULL, NULL, NULL, OCI_DEFAULT);
批量查询 select username,age from student where age>;30; hDefine = NULL; swResult = OCIDefineByPos(stmtp, &hDefine, errhp, 1, &tstd[0].username, sizeof(tstd[0].usenmae), SQLT_CHR, NULL, NULL, NULL, OCI_DEFAULT);
swResult = OCIDefineArrayOfStruct(hDefine, errhp, sizeof(tstd[0]), 0, 0, 0); 11.提取结果 sword OCIStmtFetch ( OCIStmt *stmtp,//语句句柄 OCIError *errhp, ub4 nrows, //从当前位置处开始一次提取的记录数,对于数据变量,可以>;1,否则不能>;1 ub2 orientation,//提取的方向:OCI_FETCH_NEXT ub4 mode //OCI_DEFAULT )
eg while ((swResult=OCIStmtFetch stmtp errhp,1,OCI_FETCH_NEXT,OCI_DEFAULT)) != OCI_NO_DATA) { …… }
12.事务操作 开始一个事务 sword OCITransStart ( OCISvcCtx *svchp, OCIError *errhp, uword timeout, //** ub4 flags ); **注: 1. Timeout: 当flag=OCI_TRANS_RESUME:它表示还有多少秒事务将被激活 =OCI_TRANS_NEW: 事务响应的超时时间(秒) 2. Flags:指定一个新的事务还是已有事务 =OCI_TRANS_NEW:定义一个新的事务 =OCI_TRANS_RESUME 准备一个事务: sword OCITransPrepare ( OCISvcCtx *svchp, OCIError *errhp, ub4 flags );//OCI_DEFAULT
sword OCITransForget ( OCISvcCtx *svchp, OCIError *errhp, ub4 flags );//OCI_DEFAULT
断开一个事务: sword OCITransDetach ( OCISvcCtx *svchp, OCIError *errhp, ub4 flags );//OCI_DEFAULT
提交一个事务: sword OCITransCommit ( OCISvcCtx *svchp, //服务环境句柄 OCIError *errhp, ub4 flags ); //OCI_DEFAULT 回滚一个事务 sword OCITransRollback ( dvoid *svchp, OCIError *errhp, ub4 flags ); //OCI_DEFAULT
四. OCI数据类型与C语言数据类型对照表 表字段类型 OCI类型 C类型 备注 Number(N) SQLT_UIN int 无符号整型 Number(N) SQLT_INT int 有符号整型 Number(n,m) SQLT_FLT float 符点数 Varchar2(N) Sqlt_chr Char 字符串 Raw(N) Sqlt_BIN 具体看不同的定义 二进制类型,多用于一个结构字段 DATE SQLT_DAT 无 最好转换成字符串或数字
http://bbs.chinaunix.net/viewthread.php?tid=530742&extra=page%3D1
本例涉及两个站点. 主体定义站点:AVATAR.COOLYOUNG.COM.CN 主体站点:AUTHAA.COOLYOUNG.COM.CN 注:主体定义站点指配置复制工作的站点
本例涉及的用户. 复制管理员:repadmin 应用用户:hawa 本例复制的对象:hw_test 数据表 1.在主体定义站点复制用户下创建复制对象
SQL> select * from global_name;
GLOBAL_NAME
-----------------------------------------------------------
AVATAR.COOLYOUNG.COM.CN
SQL> connect hawa/password
Connected.
SQL> create table hw_test as select * from hw_online;
Table created.
SQL> select count(*) from hw_test;
COUNT(*)
----------
464
SQL> alter table hw_test add (constraint pk_userid primary key (numuserid));
Table altered.
|
2.在主体站点同样创建复制对象
SQL> select * from global_name;
GLOBAL_NAME
------------------------------------------------------------------------
AUTHAA.COOLYOUNG.COM.CN
SQL> connect hawa/password
Connected.
SQL> create table hw_test as select * from hw_online;
Table created.
SQL> select count(*) from hw_test;
COUNT(*)
----------
0
|
3.在主体站点手工同步数据
SQL> connect repadmin/password
Connected.
SQL> insert into hawa.hw_test select * from hawa.hw_test@avatar;
464 rows created.
SQL> commit;
Commit complete.
|
4.在主体定义站点开始操作 登陆主体定义站点
$ sqlplus repadmin/password
SQL*Plus: Release 9.2.0.4.0 - Production on Mon Jun 27 09:32:36 2005
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
SQL> select * from global_name;
GLOBAL_NAME
----------------------------------------------------------------------------
AVATAR.COOLYOUNG.COM.CN
|
创建复制组:
SQL> execute dbms_repcat.create_master_repgroup('rep_hh');
PL/SQL procedure successfully completed.
SQL> select gname,master,status from dba_repgroup where gname='REP_HH';
GNAME M STATUS
------------------------------ - ---------
REP_HH Y QUIESCED
|
在复制组里加入复制对象
SQL> execute dbms_repcat.create_master_repobject
(sname=>'hawa',oname=>'hw_test',
type=>'table',use_existing_object=>true,gname=>'rep_hh',copy_rows=>false);
PL/SQL procedure successfully completed.
SQL> select sname,oname,status,gname from dba_repobject where gname='REP_HH';
SNAME ONAME STATUS GNAME
------------------------------ ------------------------------ ---------- ------------------------------
HAWA HW_TEST VALID REP_HH
|
对复制对象产生复制支持
SQL> execute dbms_repcat.generate_replication_support('hawa','hw_test','table');
PL/SQL procedure successfully completed.
SQL> select gname, master, status from dba_repgroup where gname='REP_HH';
GNAME M STATUS
------------------------------ - ---------
REP_HH Y QUIESCED
SQL> select sname,oname,status,gname from dba_repobject where gname='REP_HH';
SNAME ONAME STATUS GNAME
------------------------------ ------------------------------ ---------- ------------------------------
HAWA HW_TEST VALID REP_HH
HAWA HW_TEST$RP VALID REP_HH
HAWA HW_TEST$RP VALID REP_HH
SQL>
|
添加主体复制节点
SQL> execute dbms_repcat.add_master_database
(gname=>'rep_hh',master=>'AUTHAA.COOLYOUNG.COM.CN',use_existing_objects=>true,
copy_rows=>false, propagation_mode => 'synchronous');
PL/SQL procedure successfully completed.
SQL> column masterdef format a10
SQL> column master format a10
SQL> column dblink format a25
SQL> column gname format a12
SQL> select gname, dblink, masterdef MASTERDEF, master MASTER from sys.dba_repsites where gname='REP_HH';
GNAME DBLINK MASTERDEF MASTER
------------ ------------------------- ---------- ----------
REP_HH AVATAR.COOLYOUNG.COM.CN Y Y
REP_HH AUTHAA.COOLYOUNG.COM.CN N Y
|
登陆主体站点,检查复制对象情况:
[oracle@www167 oracle]$ sqlplus repadmin/password
SQL*Plus: Release 9.2.0.4.0 - Production on Mon Jun 27 09:34:49 2005
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
AUTHAA.COOLYOUNG.COM.CN
SQL> set linesize 120
SQL> select sname,oname,status,gname from dba_repobject where gname='REP_HH';
SNAME ONAME STATUS GNAME
------------------------------ ------------------------------ ---------- ------------------------------
HAWA HW_TEST VALID REP_HH
HAWA HW_TEST$RP VALID REP_HH
HAWA HW_TEST$RP VALID REP_HH
|
在主体定义站点启动复制:
SQL> select * from global_name;
GLOBAL_NAME
-----------------------------------------------------------------------------
AVATAR.COOLYOUNG.COM.CN
SQL> execute dbms_repcat.resume_master_activity('rep_hh',true);
PL/SQL procedure successfully completed.
|
在主体定义站点删除数据测试:
SQL> connect hawa/password
Connected.
SQL> select count(*) from hw_test;
COUNT(*)
----------
464
SQL> delete from hw_test where rownum <20;
19 rows deleted.
SQL> commit;
Commit complete.
SQL> select count(*) from hw_test;
COUNT(*)
----------
445
|
在主体站点观察变化:
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
AUTHAA.COOLYOUNG.COM.CN
SQL> select count(*) from hw_test;
COUNT(*)
----------
445
SQL>
|
至此,同步复制配置完毕。 关于Advanced Replication 的初步研究Oracle 高级复制冲突解决机制Oracle 高级复制冲突解决机制的研究
一、主要配置参数说明示例
Oracle 高级复制,也称为对称复制。和 Oracle 的其他功能不同,Oracle 的高级复制不是即插即用的,用户必须深刻理解它们是如何工作的以及各种复制方案的优缺点。深刻理解复制的基本概念可以帮助你设计一个可靠的复制环境。 接下来主要介绍搭建 Oracle 高级复制环境时需要设置的一些系统参数。需要提醒注意的是,这里所给出的这些系统参数的具体配置数值只能保证可以成功的搭建出一个相对较好的高级复制环境,但并未对这些参数的优化配置进行进一步的深入探讨。
现在我们正式开始。假设有两个节点,节点名分别为 RLDBA 和 XJTU。 数据库名 Rldba Xjtu 数据库域名 Hr_group World 数据库SID Rep.world Xjtu.world Listener端口号 1521 1521 服务器IP地址 192.168.110.221 192.168.110.130
1. 实现数据库复制的前提条件 a 数据库支持高级复制功能:您可以用 system 身份登录数据库,查看 v$option 视图,如果其中 Advanced replication 为 TRUE,则支持高级复制功能;否则不支持。 b 数据库初始化参数要求: (1) db_domain = test.com.cn:指明数据库的域名(默认的是WORLD),这里可以用您公司的域名。 (2) global_names = true:它要求数据库链接(database link)和被连接的数据库名称一致。 现在全局数据库名:db_name+"."+db_domain c 数据库连接通畅: 运行 $tnsping hr_svr 与 $tnsping xjtu,出现以下提示符: Attempting to contact (ADDRESS=(PROTOCOL=TCP)(HOST=10.1.1.200)(PORT=1521)) OK(n毫秒)则表示数据库连接通畅,可以准备复制。
2. 系统环境参数(init.ora文件)设置(对于非缺省值) 如果要搭建Oracle高级复制环境,必须在初始化文件中设置下列参数,见表1所示。
表1:Oracle8高级复制环境初始化参数设置 |
参数名称 |
推荐值 |
备注 |
processes |
100 |
进程数,default=59如果进程数大于59数据库将可能发生死锁 |
shared_pool_size |
30000000 |
至少30M,如果有很多的复制对象的话,则需要更多的空间 |
large_pool_size |
500K |
|
db_block_buffers |
550 |
|
compatible |
8.0.5.0 |
该版本以上 |
db_file_multiblock_read_count |
16 |
|
dml_locks |
100 |
|
sequence_cache_entries |
30 |
|
sequence_cache_hash_buckets |
23 |
|
global_names |
TRUE |
|
distributed_lock_timeout |
300 |
|
distributed_transactions |
10 |
|
Open_links |
6 |
复制节点多的话,需要增加 |
Sort_area_size |
1000000 |
|
db_name |
ORA_BJ |
或者ORA_NB |
job_queue_processes |
6 |
定义SNP进程的启动个数为n。系统缺省值为0,正常定义范围为0~36,根据任务的多少,可以配置不同的数值。 |
job_queue_interval |
60 |
定义系统每隔N秒唤醒该进程一次。系统缺省值为60秒,正常范围为1~3600秒。事实上,该进程执行完当前任务后,就进入睡眠状态,睡眠一段时间后,由系统的总控负责将其唤醒。 |
parallel_max_servers |
10 |
只适用于并行传播 |
parallel_min_servers |
2 |
只适用于并行传播 |
PEPLICATION_DEPENDENCY_TRACKING |
true |
如果采用并行传播,必须设置为TRUE | 表1中各个参数的推荐值认为目前的复制环境只有两个节点,一个简单的高级复制环境,如果节点较多,且复制关系复杂,需要复制的表也很多,则需要相应增大一些参数的值,这可以通过修改不同的参数试验获得。如果修改了以上这几个参数,需要重新启动数据库以使参数生效。
将所有的 SNAPSHOT_ 或者是 JOB_QUEUE_KEEP_CONNECTIONS 参数都删除,因为 Oracle 以后已经不支持这些参数。
3.Net8参数文件
# SQLNET.ORA Network Configuration File: D:\Oracle\Ora81\network\admin\sqlnet.ora # Generated by Oracle configuration tools SQLNET.AUTHENTICATION_SERVICES= (NTS) NAMES.DIRECTORY_PATH= (TNSNAMES, ONAMES, HOSTNAME) automatic_ipc=off names.default_domain = world name.default_zone = world sqlnet.expire_time = 0 DISABLE_OOB = ON |
RLDBA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = hr_svr)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = rep.world) ) )
XJTU = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = xjtu)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = xjtu.world) ) ) | 上面Host为各个复制节点的IP地址,如果复制节点很多,则全部加入到tnsnames.ora文件中,本文作为用例中有两个节点。
4.表空间 如果搭建 Oracle 8 高级的高级复制环境,额外需要加大一些表空间,表2是建议的初始表空间。
表2:Oracle系统表空间大小设置 |
表空间 |
建议初始值 |
建议 |
SYSTEM |
至少20M |
|
ROLLBACK SEGMENTS |
至少20M |
建议回滚段的下一个区大小设置至少为100K |
TEMPORARY |
至少10M |
|
TOOLS |
至少20M |
| 上面这些建议的设置是一种较小复制环境下的空间设置。如果要复制的表很多,每天的变化量很大,复制节点复杂,则需要相应增大表空间的大小,具体数据依据具体情况而定。
二、复制应用实例
上面我们对复制基本概念及复制参数的作了说明,接下来主要介绍一个Oracle快照复制的实际例子及其技术实现细节。
(1) 业务需求描述 在一个实际的数据库应用中,如电信、人力资源管理等应用中通常都采用这样一种解决方案,在一个行政区域内,如一个省或者一个市,在不同的地理位置架设数台数据库服务器,这些不同地理位置的服务器具有同样的后台数据库。为了维护数据库系统的一致性,对于整个行政区域应用的基本数据表应该保持一致,如果不考虑数据复制,想维护同样的不冲突的代码表是很困难的。下面我们不考虑实际的业务应用,只从数据库复制角度来说明Oracle快照复制的应用。 为了维护整个系统基本数据表的一致性,比如有这样的业务需求,对RLDBA上的一些表采用统一维护,即在一台服务器上维护。而在其他位置(如数据库 XJTU,用户SNAP)可以直接使用这些表,也就是说在位置1具有对代码表插入、删除和更新的能力,而在其他地方具有同步查询应用的能力。
(2) 应用设计 针对上述的需求,现在提出了这样一种解决方案,也就是采用Oracle的快照复制。具体业务实现方案设计如下: 在位置1的数据库RLDBA维护所有的表,在其余数据库建立相对于位置1的所有表的快照。为了维护快照的方便,在位置2创建一个单独的快照表空间和一个模式(schema),也可以称为用户(USER),系统中的其他用户通过一个私有同义词来存取这些快照。这里私有同义词相对公共同义词要好,这是因为在位置1存在一个同样的系统,它的表是通过公共同义词来存取的。对于快照的刷新,采用Oracle系统包DBMS_REFRESH进行,并将该刷新过程的运行定时在每天早上2:00,这样可以减少网络流量。对于快照的刷新形式,由于对于表的维护不是很多而且表的数据量相对较少,所以在此选择了完全刷新,这样就避免了管理快照日志的麻烦。下面以一个节点2(XJTU)为例来说明具体的技术实现细节。
(3) 技术实现细节 除非特别说明,下面的SQL命令都是在数据库XJTU的SYSETM用户下运行的。
1. 在数据库2(XJTU)上增加数据库1(RLDBA)的services name,可以直接在tnsnames.ora文件中增加数据库1的services name,包括IP地址,SID以及端口号等。services name 命名为rep.world。
2. 创建一个用于连接数据库1(RLDBA)的数据库连接(dblink) DROP PUBLIC DATABASE LINK rep.hr_group@rldba; //删除Database link CREATE PUBLIC DATABASE LINK rep.hr_group@rldba CONNECT TO rldba IDENTIFIED BY admin USING 'rldba'; //Create Database link select * from cat@rep.hr_group@rldba; //Test the Database link 注:出于安全考虑,可以采用一个私有数据连接。
3. 创建一个名为snapshot_rldba的表空间来存放RLDBA快照,并创建一个和该表空间有关的名为Snap的用户。 CREATE TABLESPACE "snapshot_rldba" LOGGING DATAFILE 'D:\ORACLE\ORADATA\ORA8I\SNAPSHOT_RLDBA.ora'SIZE 30M DEFAULT STORAGE ( INITIAL 30K NEXT 15K MINEXTENTS 100 MAXEXTENTS UNLIMITED PCTINCREASE 0 ); //Create Table space
CREATE USER snap IDENTIFIED BY snap DEFAULT TABLESPACE "snapshot_rldba"; //Create User in the table space GRANT CONNECT, RESOURCE TO snap; //grant role to the user
4. 运行下面的脚本文件snapsql.sql来生成创建rldba数据库上rldba用户表的快照脚本: 注意如果所需生成快照的表中含有类型为long的列,"select *"在这里就不会起作用,上面的这个SQL脚本就不能自动建立生成所需快照的脚本,必须通过在select列表中显式地添加long型列名来创建表的快照。下面是一个例子,假如我们要创建快照依赖的表T_YGJBXX中有一个列ZP类型为long,就需要单独写出如下的创建快照的脚本: CREATE SNAPSHOT T_YGJBXX PCTFREE 10 PCTUSED 40 TABLESPACE "snapcost_rldba " STORAGE ( INITIAL 40960 NEXT 57344 PCTINCREASE 0 ) USING INDEX REFRESH WITH PRIMERY KEY FOR UPDATEAS select YGID, GZBH, FZJRLB, ZP, SXZY, XCSZY from T_YGJBXX@rep.hr_group@rldba; //Create snapshot
EXECUTE DBMS_SNAPSHOT.REFRESH ('snap.T_YGJBXX ') 运行脚本文件create_snapshot.sql后,就在模式snap中创建了所需要的快照。下一步就是考虑该如何刷新快照。对于快照的刷新,可以通过一些桌面DBA工具来刷新快照也可以通过系统包dbms_snapshot.refresh来刷新一个快照: 创建或选择实现数据库复制的用户和对象,给用户赋权,数据库对象必须有主关键字,如果数据库对象没有主关键字,可以运行以下SQL命令添加: alter table dept add (constraint dept_deptno_pk primary key (deptno));
5. 创建一个定时刷新过程来定时刷新快照: --sp_snapshot_refresh.sql CREATE OR REPLACE PROCEDURE sp_snapshot_refresh IS BEGIN DBMS_REFRESH.MAKE ( NAME=>' T_YGJBXX ', LIST=>'snap. T_YGJBXX', NEXT_DATE=>TRUNC (SYSDATE+1)+2/24, INTERVAL=>'(SYSDATE+1)', IMPLICIT_DESTROY=>FALSE, LAX=>TRUE); END sp_snapshot_refresh; --创建了一个定时任务来每天早晨2:00定时刷新快照 EXECUTE sp_snapshot_refresh; //Execute the procedure SELECT JOB, WHAT FROM DBA_JOBS; //查询刚刚加入的这个任务 CREATE SYNONYM system.T_YGJBXX FOR snap.T_YGJBXX;//在用户system下创建快照的私有同义词 GRANT SELECT ON dm_gy_rydm TO system;//以snap用户向system用户授与快照可以select的权限。
6. 同样的步骤在其它位置建立位置1(rldba)的表快照和定时刷新任务。这样就可实现在位置1统一维护代码表,在位置2和其它位置使用该表的目的。如下面的SQL语句,在位置2(xjtu)用户snap浏览在位置1(rldba)中的代码表。 SELECT * FROM T_YGJBXX;
(4) 日常维护及注意事项 无论任何时候只要出现网络连接问题,刷新就会失败。这些错误信息可以在alert.log文件中找到。下面简单介绍一下对这种问题的处理办法: 1.首先在任务队列中找到刷新快照的任务编号 SELECT JOB, what FROM DBA_JOBS; 2.删除该任务 EXECUTE DBMS_JOB.REMOVE (JOBNO); 3.删除快照组 EXECUTE DBMS_REFRESH.DESTROY ('tax_dmb_grp'); 4.重新创建快照组并且重新定时任务来定时刷新快照 EXECUTE sp_snapshot_refresh('snap.T_YGJBXX') 5.快照监视 SELECT NAME, TO_CHAR(last_refresh,'DD-MON-YY HH:MM:SS') FROM DBA_SNAPSHOTS;
http://www0.ccidnet.com/tech/guide/2001/09/03/58_3174.html http://www.linuxmine.com/3422.html
Oracle 8高级数据复制技术(上) (作者:石骁騑 2001年03月28日 13:45)
本文首先简单介绍和数据库复制有关的基本概念,然后探讨Oracle8数据复制技术中的几个重要模型,最后介绍Oracle8的数据复制管理器以及如何利用它来配置和维护复制环境。
在文章的开头,我想首先简单谈一下复制的基本概念,也就是什么是复制?复制简单地说就是在由两个或者多个数据库系统构成的一个分布式数据库环境中拷贝数据的过程。Oracle高级复制,也称为对称复制,第一次是在Oracle 7.1.6版本中出现的,在这之前的Oracle版本中,Oracle数据复制方法仅有只读快照形式的基本复制一种方法。随着Oracle版本的每一次升级,数据复制的功能、管理以及速度等方面都得到了很大的改进和完善。目前,由于对分布式数据环境需求的不断增长,越来越多的应用提出了数据复制的需求。
一、基本概念 1.分布式数据库技术
分布式数据库技术是目前我们经常提及的分布式计算的一个重要组成部分,该技术允许数据在多个服务器端共享。采用分布式数据库技术,一个本地服务器可以存取不同物理地点的远程服务器上的数据;也可以使所有的服务器均可以持有数据的拷贝/复制,这样分布式系统中的所有服务器均可进行本地存取。
设计一个分布式计算解决方案首先需要考虑的问题就是应用的完整性、复杂性、性能和可用性以及响应时间等,同时还需要考虑的是对于不同的应用需求是采用实时存取远程数据还是采用延迟存取远程数据。这对于数据复制来讲就是采取实时更新复制方案还是延迟数据复制方案。
2.同步和异步的概念
同步分发数据库技术是一种实时远程存取和实时更新数据的技术。这种技术可以保证应用的完整性降低了应用的复杂性,但是如果系统存在网络存取速度很慢这样的问题,相应响应时间就会很慢。
异步分发数据库技术是一种延迟远程存取和延迟传播对数据更新的技术。这种技术具有很高的可用性和很短的响应时间。相比同步分发数据库技术就显得复杂一些,为了确保应用的完整性需要仔细考虑和设计。
对于实际的商业问题,必须权衡这两种技术的利弊最终选择最佳的解决方案,有些问题选用同步技术比较适合,也有一些问题采用异步技术是比较好的解决方案,还有一些问题必须综合这两种技术。
3.复制的概念
复制,顾名思义就是将数据库中的数据拷贝到不同物理地点的数据库中以支持分布式应用,它是整个分布式计算解决方案的一个重要组成部分。上面介绍了同步和异步的概念,这里针对复制也存在同步复制和异步复制的问题。
同步复制,复制数据在任何时间在任何复制节点均保持一致。如果复制环境中的任何一个节点的复制数据发生了更新操作,这种变化会立刻反映到其他所有的复制节点。这种技术适用于那些对于实时性要求较高的商业应用中。
异步复制,所有复制节点的数据在一定时间内是不同步的。如果复制环境中的其中的一个节点的复制数据发生了更新操作,这种改变将在不同的事务中被传播和应用到其他所有复制节点。这些不同的事务间可以间隔几秒,几分种,几小时,也可以是几天之后。复制节点之间的数据临时是不同步的,但传播最终将保证所有复制节点间的数据一致。
4.更新冲突
在异步复制环境中,对于所有应用最关键的就是要确保数据的一致性。我们来看下面这种情况会有什么后果发生呢?在同一时间对同一个表的同一行数据的同一列在两个不同的地点作更新。这种情况就会发生称之为更新冲突的错误。为保证数据的一致性,更新冲突必须被检测到并且处理以确保在不同地点的数据元素保持同样的值。更新冲突可以通过限制"所有权" 到单一节点或者将更新某个特定数据元素的权利限制到某一具体节点的方法来避免。
二、Oracle 8数据复制应用模型(usage models) 为确保实际应用数据的一致性,必须在异步复制应用模型中考虑冲突避免或者冲突检测和消除的方法。例如,对于一个实际商业应用,首先必须在逻辑上了解该商业应用采取的冲突避免方法和在某个节点有那些数据以及这些数据中那些是可更新的,而那些又是不可更新的。在下面的这一部分中,我们首先将详细讨论两种常用的冲突避免方法:主站点所有权模型和动态所有权模型。然后,讨论共享所有权模型以及这种模型引起的冲突检测和处理问题,最后,讨论针对Fail-over的复制配置,这种复制方案同时考虑了冲突避免和冲突检测与消除两种情况。
1.主站点所有权
主站点所有权,异步复制数据被一个单一节点"所有",这些要复制的数据仅能被该节点更新,其他节点向拥有该数据的主节点订阅(subscribe)数据,这意味着他们在本地系统上只能够存取这些复制数据的只读拷贝。下面是一些这样的例子。
(1)决策支持系统(DSS)的联机事务处理数据的卸载。来自一个或者多个OLTP系统的数据可以被卸载到一个独立的局部DSS中,用于只读分析。
(2)中央信息的分发。产品信息,如价格列表等在总部节点上维护,然后将这些信息复制到远程销售办事处的只读产品目录系统中。
(3)远程信息的集中。许多远程节点上的产品目录数据复制到总部节点,这里总部节点只需要有数据只读的权限。
一个主节点拥有一个表的完全所有权,而其他节点只能订阅这个表的只读拷贝。也可以是多个主节点拥有同一个表的截然不同子集或者划分,而另一些节点则订阅这些子集或者划分的只读拷贝。如,一个分布的产品目录系统可以让不同的销售办事处拥有一个表的属于自己的一个"水平"部分,如在客户(CUSTOMERS)表, 订单(ORDERS)表和目录(ITEMS)这些表中含有每个销售办事处为之服务的客户和产品信息。中心总部节点可以通过订阅每个办事处拥有的数据来保持一个完整的所有产品和客户信息的只读拷贝。
2.动态所有权
动态所有权,异步更新将复制数据从一个节点移到另一个节点,而在该过程中,必须保证在同一时刻只有一个特定的节点可以对数据进行更新。一个典型实际应用就是"海关订单处理系统",订单处理的典型步骤是,报关→同意→装运→开单→收单→入帐等。应用模型可以执行其中的任何步骤,但必须保证各个不同模块的同一个数据应该在一个综合数据库中。在该系统中,当且仅当订单的状态表明前一个步骤已经完成时,下一个应用模块才可以执行更新订单数据的操作。例如,"装运"应用模块仅能在"报关"并且得到"同意"后才能被执行。
通过使用动态所有权复制模型,可以将一个系统分布在多个节点和数据库上,也就是说应用模型可以建立在不同的系统上。我们还是来看上面的例子,"报关"和"批准"这两部分可以运行在一个系统上,"装运"在另一个系统上,"开单"和"收单"等又可在一个系统上。在这个分布式系统中,数据可以被复制到不同的节点上,这些节点对复制的数据只要具有只读的权限即可。如,利用复制,"报关"节点可以监视已经报关的订单处理过程。
前面讨论的主节点所有权和动态所有权复制模型具有一个共同的特征:在任何一个给定的时间点,只允许一个节点有更新数据的权利,而其余节点对于复制的数据拷贝仅有只读权限。然而,还存在这样的情况,允许多个节点可以更新同一个数据,在极端情况下可以是在同一时刻,这就是所说的共享所有权。
3.共享所有权
共享所有权使用异步复制,这对于主节点和动态所有权模型来讲存在一些限制。在共享所有权情况下,整个系统可以存在暂时的不一致,同时必须使用冲突检测和消除。共享所有权模型相对于前面两种模型具有一些新的特点。
例如,对于前面我们讨论的那个采用具有水平划分主节点复制方案来的分布式"订单处理系统"的例子。采用共享所有权模型,每个销售办事处都有库表中不同的水平划分,该库表含有每一个办事处为之服务的一些订单信息和与消费者有关的顾客信息。每一个销售办事处只输入与自己有关的顾客订单情况,而不管其余顾客信息。
然而,在实际商业应用中,这个模型不是最佳的选择。例如,这种情况,一个零售集团在一个大城市中可以有好几个商场。顾客可能经常去离他们住的最近的那个商场,但是偶尔也可能到其他商场去购物。这时,如果多家商场执行更新同一个顾客和其订单数据的信息,更新冲突就会发生。所以在这种情况下必须要采用冲突检测和消除方案。
Oracle8高级复制支持同时既考虑冲突避免又考虑冲突检测和消除的复制模型。Oracle8高级复制之所以又称为对称复制,其原因之一就是支持对称复制模型,也就是可以在任何地方更新,即所有的复制节点都可以进行更新处理。为了避免冲突,一种方法就是将应用设计为将更新限制在一些特定的节点。对于共享所有权,Oracle 8提供了自动冲突检测和消除方案。
4.备用数据库(Fail-Over )
异步复制通过将一个主系统数据复制到另一系统,可以起到对主系统的崩溃提供保护的作用,这也就是所说的fail-over系统,如果主系统出现问题,业务依旧可以通过复制数据库进行。
Oracle 8高级复制支持这种fail-over配置。同时,Oracle也针对fail-over提供了另外两个可选的解决方案:Oracle并行服务器和备用数据库配置。用户可以根据吞吐量、可用性、事务损失的可能性和其他一些如数据一致性、方法的局限性等参考指标来权衡选择合适的fail-over方案。
Oracle 8高级数据复制技术(下) (作者:石骁騑 2001年03月28日 13:45)
三、Oracle 高级复制配置 Oracle 8高级复制即可支持基于整个表的复制也可支持基于部分表的复制两种复制方案。这两种复制方案主要是通过Oracle的两种复制机制来完成的,即多主复制和可更新快照复制,同时还可以将这两种复制机制结合起来以满足不断变化的业务需求。
1.多主复制
多主复制方案支持全表在各个主节点间的对称复制,允许所有主节点对主表都有更新操作的权利。任何一个主节点上的复制表的更新都会被传播并被直接应用到其他所有主表。一个主节点出现问题,不会对其他主节点之间变化的传播造成影响。
多主复制采用一种称为"延迟远程过程调用(deferred remote procedure calls RPCs)"的机制作为主要的传播和应用变化的机制。各节点之间变化的传播,既可以以基于事件的方式立即传播,也可以在某个特定的时间点,如在网络空闲时(如晚上)传播。在传播变化时,如果其中的一个远端系统没有准备好,传播变化的延迟远程过程调用(RPCs)就会保存在其本地队列中,等到系统准备好以后再执行。
2.可更新快照
Oracle 将最早Oracle 7上的只读快照机制扩展为一种允许快照可更新的对称复制机制。快照更新的传播方式和如何应用到快照主节点采用了和多主复制一样的延迟远程过程调用机制。
对于快照的定义,既可以是包含一个主表的完全拷贝,也可以是为满足基于值的选择标准的主表中行的子集。快照在主节点的刷新是按照一定的时间间隔或用户单独请求进行的。最后一次刷新后主表的任何变化也同样被传播并应用到快照。多个快照的刷新是在一个一致的事务中完成的,这就确保了数据和引用的完整性。
3.混合配置
可以将多主复制和可更新快照复制结合在一起,构成一种新的混合配置,这种配置可以完成对全表或者子表的复制。例如下面这种应用就是一个典型的混合配置方案,一个系统具有两个位于不同地理区域的中心节点,这两个不同的地理区域下面还有一些分支机构,两个中心节点可以彼此看做是自己的备份节点。采用多主复制方法在两个中心站点之间复制数据,同时采用只读或者可更新快照复制方法在每个区域范围中的主节点之间复制全表或者子表。这种配置的一个显著好处就是当其中的一个中心节点发生问题时,这些快照的主节点可以被重新定义到另一个运行良好的中心节点,从而提高了系统的可靠性。
4.其他复制机制
Oracle除了前面讨论的三种复制机制以外,还提供了另外两种复制机制:过程级复制和同步复制。
(1)过程级复制
这种复制方案主要应用在存在大量数据更新以及采取批处理方式操作数据时需要复制数据的情况。例如,下面这个应用,一个以年为单位管理客户订单的公司,对于老的订单数据不再需要在线保存,而需要卸载到某存储介质中。这时,如果在多个节点间复制每一独立的行级变化效率将是非常低的。对于这种情况,可以直接在每个复制节点执行一个过程来直接进行这种更新操作。Oralce8高级复制提供的分布式模式管理功能(将在下面详细讨论)可以非常方便地在多个节点上设置和维护过程级复制的远程过程。
(2)同步复制
一个采用同步复制方案的表发生变化时,Oracle会确保这种变化能够成功地作用在本地表和其他节点的复制表,如果失败则整个事务会被成功回滚。同步复制在网络的稳定性比较高的情况下是可行的,可以保证复制节点之间的复制数据一直保持同步。
四、Oracle 8管理工具 很显然,有效的管理工具对于成功的分布式应用是非常关键的,如果没有能力去操作它,再专业的复制功能也不能发挥很好的作用。Oracle 8高级复制提供了几个功能强大的管理工具,诸如复制目录,分布式模式管理以及其他的一些Oracle 复制管理工具。
1.复制目录
复制目录是一个包含定义复制环境原数据的一个单一综合库。复制目录本身也被复制到多个节点以确保高可用性和授权用户可以简单地实现本地存取管理。
复制目录定义了被复制的数据库对象,复制的节点以及用于复制的机制。数据库对象有需要复制的库表和其他一些相关的对象,如索引,视图,过程,触发器和同义词等等。这些原数据是开放的,用户可以通过标准SQL语句进行检索和查询。
2.分布式模式管理
Oracle 8高级复制的分布式模式管理功能允许在一个控制点就可进行复制环境的定义和改变。对复制环境的任何改变,都将自动复制并且应用这些数据定义语言(DDL)命令到其他复制环境节点,同时也利用数据库触发器和复制相关过程自动生成复制所需要的一些支持对象。
分布式模式管理在一个被称为主定义节点的地方进行控制。它自动将DDL推向其他所有主节点并且也允许快照节点"拉"回并且执行这些DDL命令。由于主定义节点使用并且维护着整个复制目录,该复制目录本身也被复制到其他节点,所以该主定义节点一旦出现问题,就必须用其他节点来代替。分布式模式管理可以通过一个图形用户界面管理工具(GUI)来配置。
3.Oracle复制管理器
Oracle复制管理器是Oracle提供的一个图形界面的复制管理工具,通过该工具可以配置,定时和通过一个节点来管理整个的复制环境。该管理工具可以单独运行也可以在Oracle企业管理器中通过一个applet来激活。
采用Oracle复制管理器,用于复制的对象组可以通过一些鼠标操作非常简单地定义。复制组可以包含表和其他相关的对象,如触发器,存储过程,索引,视图,同义词以及序列等。Oracle除了可以复制每个复制组的全部拷贝以外,还可以选择复制数据的子集。复制组的配置可以在任何时候修改,这种变化将自动应用到其他所有的复制节点。
一旦定义了对象组,可以通过Oracle复制管理器,简单进行拖拉操作,就可自动部署复制组到一个新的节点。这些快照节点既可以是只读的也可以是可更新的。复制节点配置完成以后,用户可以配置定时以使复制环境中的变化传播到其他节点,当然也可以选择采用同步复制。
4.选择冲突解决方案
如果选择采用一种可以在任何地方更新的复制方案,Oracle复制管理器提供了几个内建的冲突解决方案,诸如"最近时间戳"和"站点优先"等来解决潜在的冲突。对于不同的表可以选择不同的方法,甚至可以对一个表中的不同列选择不同的冲突消除方案。用户对于一些特殊的商业需求也可以创建自己的冲突解决方案。
5.实时管理
通过Oracle的复制管理器,复制环境中任何地方发生的错误均可以非常快速和简单地分离出来并且改正。通过一个单一的节点,用户就可以看到每个节点的延迟事务队列,也可以重新定时或者强制立即执行事务。另外,用户也可以利用Oracle企业管理器的事件管理功能来对复制环境进行监视,该事件管理器提供了对多个站点间的复制状态的主动监视功能,另外还提供了可以定义自动改正的选项等。
结论 和Oracle的其他功能不同,Oracle的高级复制不是即插即用的,用户必须深刻理解它们是如何工作的以及各种复制方案的优缺点。深刻理解复制的基本概念可以帮助你设计一个可靠的复制环境。
http://www0.ccidnet.com/tech/guide/2001/03/28/58_1900.html http://www0.ccidnet.com/tech/guide/2001/03/28/58_1901.html
一、 Oracle Data Guard
Oracle9i推出了一种功能强大,更能有效地实施灾难恢复的解决方案 Oracle Data Guard 。
Oracle Data Guard 采用主数据库正常运行,一或多个备用数据库进行备份的方式保护数据库,备用数据库的备份、管理和监视工作都是自动完成的,当主数据库宕机发生时,至少有一个备用数据库马上投入使用,使应用程序的运行不会间断,避免了系统的瘫痪。
(一)、Data Guard的功能简介
1.数据库的切换
允许DBA将主数据库切换到备用数据库,此备用数据库变为主数据库,响应用户的请求,而原主数据库变为备用数据库。Data Guard的这种特性保证了数据不会丢失,避免数据库恢复期间无法处理用户的请求。
2.通过分布式组态,增强数据库的可用性
Oracle Data Guard是由主数据库和一到多个备用数据库构成,这些在Data Guard的环境中称为站点,通常各个站点以松散的方式分布在各地,以网络连接,所以,即使遇到地震、火灾、洪水等自然灾害,数据库的数据也会得到很好地保护。Data Guard的结构由下图所示:

3.同步主站点与备用站点的数据
在Data Guard环境中,将一个站点设置为主站点,用来响应用户的请求,事务对数据库所做的修改,以归档日志的形式由日志传输服务自动从主站点传送到各个备用站点,以实现备用站点与主站点的同步。
4.防止数据库的物理损坏
由于主站点的物理损坏不可能通过归档日志文件传输到备用站点,所以降低了由物理损坏带给数据库的风险。
(二)、数据库的切换
将主数据库切换到备用数据库,此备用数据库变为主数据库,而原主数据库变为备用数据库。数据库的切换可以从主数据库角色切换到备用数据库角色,也可从备用数据库角色切换到主数据库角色。
1.主数据库的工作模式:
Guaranteed protection: 规定在修改主数据库时,至少有一个备用数据库有效。假如主备之间的连接中断,通过中断主实例来禁止数据的分歧,保证无数据丢失。这种模式对数据库性能的影响最大。
Instant protection : 规定在修改主数据库时,至少有一个备用数据库有效。与 Guaranteed protection 模式不同的是当主备之间的连接中断,允许数据分歧,并当恢复连接后,解决数据分歧的现象。无数据丢失,对主数据库的性能有较小的影响。
Rapid protection : 指出主数据库的修改在备用数据库上有效。有数据丢失,最小化对数据库性能的影响。
Delayed protection :
指出主数据库的修改最终在备用数据库上有效。 Rapid protection 和 Delayed protection 模式即使在网络连接有效时,也允许主数据库与所有的备用数据库有数据分歧,数据的丢失量等同于主数据库联机重做日志的未归档数。最小化对数据库性能的影响。
四种模式的区别详见下表:
主数据库
保护模式 |
保护策略 |
网络连接 |
主数据库
操作状态 |
Switchover |
Failover |
Guaranteed |
保护 |
连接 |
无数据分歧 |
无数据丢失 |
无数据丢失 |
|
|
未连接 |
关闭实例 |
不可能 |
无数据丢失 |
Instant |
未保护 |
连接 |
无数据分歧 |
无数据丢失 |
无数据丢失 |
|
|
未连接 |
Delayed
保护模式 |
不可能 |
数据丢失 |
Rapid |
未保护 |
连接 |
存在数据分歧 |
无数据丢失 |
数据丢失 |
|
|
未连接 |
Delayed
保护模式 |
不可能 |
数据丢失 |
Delayed |
未保护 |
连接 |
存在数据分歧 |
无数据丢失 |
数据丢失 |
|
|
未连接 |
存在数据分歧 |
不可能 |
数据丢失 |
2.备用数据库的工作模式:
Managed recovery mode : 最大化保护数据,主数据库将联机重做日志归档到备用数据库,备用数据库自动应用这些日志进行数据库的恢复。
Read-only mode : 备用数据库不能应用归档日志。在这种模式下,只能对备用数据库进行查询。当备用数据库重新处于mount方式,主数据库继续将日志归档到备用数据库上。
虽然备用数据库不能同时处于两种模式,但可在两种模式间进行切换。在大多数的Data Guard环境中,备用数据库应处于恢复管理模式。
3 . Failover 和 Switchover 的区别
Failover :
- 将主数据库offline,备用数据库online,这种操作由系统和软件失败引起。
- 即使在备用数据库上应用重做日志,也可能出现数据丢失的现象,除非备用数据库运行在 guaranteed protection 模式。
- 原主数据库重新使用时必须重新启动实例。
- 其它的备用数据库也需重新启动实例。
Switchover :
- 故意将主数据库offline,而将另一备用数据库online,它能够切换到备用数据库而不需同步操作。如:可使用 Switchover 完成系统的平滑升级。
- 即使在备用数据库上不应用重做日志,也不会造成数据的丢失。
- 数据库不需重新启动实例。这使主数据库几乎能立即在备用数据库上恢复它的功能,因此可经常进行定期维护而不需中断操作。
Failover和Switchover的区别为:当Failover发生,备用数据库切换为主数据库之后,它丢失了备用数据库的所有能力,也就是说,不能再返回到备用模式;而Switchover可以,备用数据库可切换为主数据库,也可从主数据库再切换回备用数据库。
4.主数据库与备用数据库的切换
当主数据库操作在 Guaranteed protection 和 Instant protection 两种模式下,可保证数据库在切换的过程中不丢失数据,这意味着主数据库的所有归档日志都必须应用在备用数据库上。假如归档日志没有完全应用,或主数据库工作在 Rapid 和 Delayed protection 模式,数据库的切换将导致数据的丢失,数据丢失的总量可由主数据库归档日志路径属性和备用数据库归档日志的应用来决定。
二、 ORACLE 的高级复制技术
1.基本概念
复制,顾名思义就是将数据库中的数据拷贝到不同物理地点的数据库中以支持分布式应用,它是整个分布式计算解决方案的一个重要组成部分。
2.高级复制技术的基本结构
实体化视图在以前的Oracle 版本中叫做“快照”。它被用来复制数据到复制环境中的非主站点。
实体化视图可以是只读的、可更新的或者是可写的。
(1) 只读实体化视图
在一个基础结构中,实体化视图可以提供只读的访问表数据,这个表数据来源于一个主体站点或者一个主实体化视图站点。应用程序可以避免访问主体站点和不考虑网络是否可用,它可直接向只读实体化视图请求数据。下图表示只读实体化视图

(2) 可更新的实体化视图
在一个更高级的结构中,可以创建一个可更新的实体化视图,它允许用户通过在这个可更新的实体化视图上的插入、更新和删除行的操作,来进行同样的插入、更新和删除主表或者主实体化视图上的行。下图表示使用可更新实体化视图

3.实现多主体复制的选择
同步复制,复制数据在任何时间在任何复制节点均保持一致。如果复制环境中的任何一个节点的复制数据发生了更新操作,这种变化会立刻反映到其他所有的复制节点。这种技术适用于那些对于实时性要求较高的商业应用中。
异步复制,所有复制节点的数据在一定时间内是不同步的。如果复制环境中的其中的一个节点的复制数据发生了更新操作,这种改变将在不同的事务中被传播和应用到其他所有复制节点。这些不同的事务间可以间隔几秒,几分种,几小时,也可以是几天之后。复制节点之间的数据临时是不同步的,但传播最终将保证所有复制节点间的数据一致。
过程化复制,成批的处理应用可以在一个单独的事务中改变大量的数据。典型的行层次复制把许多数据改变加载到网络上,为了避免这种问题,一个在复制环境中的批处理应用操作可以使用过程化复制,它只用单一复制存储的过程调用来聚集数据复制品。
三、Oracle9i数据库:应用集群技术
Oracle9i针对互联网上日益增长的在线应用市场进行了许多关键的改进,它最特别的技术就在于Oracle9i真正应用集群(Oracle9i Real Application )。作为Oracle的新一代群集技术,Oracle9i真正应用集群基于Oracle获得专利的高速缓存熔合体系结构,它能够迅速、有效地在群集的所有计算机上共享那些经常被访问的数据,以提供透明的应用可伸缩性。这一突破性技术,使Oracle9i真正应用集群能够提供超过四个节点的直线性可伸缩性。另一方面,借助Cache Fusion体系结构能够独立处理每个节点的特性,Oracle9i真正应用集群能够为电子商务应用提供令人振奋的可靠性。与其它厂商提供的集群技术相比,Oracle9i真正应用集群是利用独立的计算机专门处理特殊的计算任务,管理数据的特殊“分段”。这种集群技术能够使系统的可伸缩性、性能和可靠性获得最大程度的平衡。因此,在用户集群系统中增加计算机时,既不需要重新分配数据,也不需要重新编写应用程序,Oracle9i真正应用集群能够以透明的方式进行修改,以利用这些新的资源。
1.Real Application Clusters的体系结构
Real Application Clusters 是由多个节点中能同时访问一个共享数据库的多个组件构成。如图:

Real Application Clusters 由下面组件构成:
- Cluster Manager
- The Global Cache Service and Global Enqueue Service
- Cluster Interconnect and Interprocess Communication (Node-to-Node)
- Disk Subsystems
在Real Application Clusters环境中,所有的节点可在同一数据库上并发执行事务,Real Application Clusters保证每个节点访问共享数据的一致性和完整性。可以把大的事务分解为多个小事务,在不同的节点执行。它适合DSS、OLTP及混合系统。
2.Oracle9iRealApplicationClusters的特点:
- “开箱即用”,近线性的透明缩放
- 与其它程序的良好兼容性,无需重新设计
- 快速增长的集群,可快速增添节点和磁盘
3.硬件组成
采用集群数据库技术,最大程度节约硬件投资并保证企业信息存在于一个单一的数据库中。硬件与数据库的数据容量瓶颈曾经困扰企业的信息化建设。企业旧式的解决方法是不断添加成堆成堆的服务器,并让应用分散运行在多个服务器上的多个数据库上。现在的办法有所不同,比如Oracle 9i数据库采用了"集群技术"(Real Application Clusters),它能够让单一数据库同时在多台服务器上运行,而不需要对应用代码或体系结构做出任何修改,此特性极大地改善了系统可靠性:如果数据容量增大,企业可以通过增加小型服务器进行扩充;而在任何一个服务器出现故障时不会对系统造成损害,因为其他服务器可以十分轻松地分担起一部分新增加的负载。此特性还能够缩短数据库访问时间,从而改善应用性能。并使得由多台较便宜的计算机组成的IT数据中心取代昂贵的大型机成为可能,这随着CPU需求的增加能够节省近80%的硬件(在某些情况下,就是数百万美元)。Oracle数据库至今占据了Unix开放系统之下66%以上的份额,它提供了卓越的开放性能,并引领当今数据库技术标准。
高速缓存成亮点:
Oracle9i Real Application Clusters采用了新的Cache Fusion(高速缓存熔接)技术,Cache Fusion是群集数据库技术的重大突破。在群集中,用户的请求可以被群集数据库的任何高速缓存所响应。当数据正在更新时,Cache Fusion能在各个服务器上的高速缓存之间进行协调,从而保证数据的正常读取和更新。
如果一个查询请求由一个远程高速缓存所响应,数据块将在从一个节点到另一个节点之间的高速群集中传递,"缓存熔接"过程将自动发生。该过程对于应用是透明的,大大提高了群集的可伸缩性。
Oracle9i Real Application Clusters几乎和已有的所有网络应用兼容,它支持群集功能,利用它可快速增加网络节点。Oracle9i Real Application Clusters为群集里的所有服务器提供透明的应用可伸缩性,从而解决了一个进程中服务器之间的争端问题。
Oracle9i设置了一套新的标准,用以防止系统停机导致网络中断,保证系统的高可用性。这些新的功能包括灾难防止、系统错误快速恢复和人为错误的透明恢复等
研究了好几天,终于有了一个比较完整查看oracle的数据日志方法,oracle 没有想sqlserver那样有sqlE工具来辅助查询。只能利用oracle自己的工具。
一、如何分析即LogMiner解释
从目前来看,分析Oracle日志的唯一方法就是使用Oracle公司提供的LogMiner来进行, Oracle数据库的所有更改都记录在日志中,但是原始的日志信息我们根本无法看懂,而LogMiner就是让我们看懂日志信息的工具。从这一点上看,它和tkprof差不多,一个是用来分析日志信息,一个则是格式化跟踪文件。通过对日志的分析我们可以实现下面的目的:
1、查明数据库的逻辑更改;
2、侦察并更正用户的误操作;
3、执行事后审计;
4、执行变化分析。
不仅如此,日志中记录的信息还包括:数据库的更改历史、更改类型(INSERT、UPDATE、DELETE、DDL等)、更改对应的SCN号、以及执行这些操作的用户信息等,LogMiner在分析日志时,将重构等价的SQL语句和UNDO语句(分别记录在V$LOGMNR_CONTENTS视图的SQL_REDO和SQL_UNDO中)。这里需要注意的是等价语句,而并非原始SQL语句,例如:我们最初执行的是“delete a where c1 <>'cyx';”,而LogMiner重构的是等价的6条DELETE语句。所以我们应该意识到V$LOGMNR_CONTENTS视图中显示的并非是原版的现实,从数据库角度来讲这是很容易理解的,它记录的是元操作,因为同样是“delete a where c1 <>'cyx';”语句,在不同的环境中,实际删除的记录数可能各不相同,因此记录这样的语句实际上并没有什么实际意义,LogMiner重构的是在实际情况下转化成元操作的多个单条语句。
另外由于Oracle重做日志中记录的并非原始的对象(如表以及其中的列)名称,而只是它们在Oracle数据库中的内部编号(对于表来说是它们在数据库中的对象ID,而对于表中的列来说,对应的则是该列在表中的排列序号:COL 1, COL 2 等),因此为了使LogMiner重构出的SQL语句易于识别,我们需要将这些编号转化成相应的名称,这就需要用到数据字典(也就说LogMiner本身是可以不用数据字典的,详见下面的分析过程),LogMiner利用DBMS_LOGMNR_D.BUILD()过程来提取数据字典信息。
LogMiner包含两个PL/SQL包和几个视图:
1、dbms_logmnr_d包,这个包只包括一个用于提取数据字典信息的过程,即dbms_logmnr_d.build()过程。
2、dbms_logmnr包,它有三个过程:
add_logfile(name varchar2, options number) - 用来添加/删除用于分析的日志文件;
start_logmnr(start_scn number, end_scn number, start_time number,end_time number, dictfilename varchar2, options number) - 用来开启日志分析,同时确定分析的时间/SCN窗口以及确认是否使用提取出来的数据字典信息。
end_logmnr() - 用来终止分析会话,它将回收LogMiner所占用的内存。
与LogMiner相关的数据字典。
1、v$logmnr_dictionary,LogMiner可能使用的数据字典信息,因logmnr可以有多个字典文件,该视图用于显示这方面信息。
2、v$logmnr_parameters,当前LogMiner所设定的参数信息。
3、v$logmnr_logs,当前用于分析的日志列表。
4、v$logmnr_contents,日志分析结果。
二、Oracle9i LogMiner的增强:
1、支持更多数据/存储类型:链接/迁移行、CLUSTER表操作、DIRECT PATH插入以及DDL操作。在V$LOGMNR_CONTENTS的SQL_REDO中可以看到DDL操作的原句(CREATE USER除外,其中的密码将以加密的形式出现,而不是原始密码)。如果TX_AUDITING初始化参数设为TRUE,则所有操作的数据库账号将被记录。
2、提取和使用数据字典的选项:现在数据字典不仅可以提取到一个外部文件中,还可以直接提取到重做日志流中,它在日志流中提供了操作当时的数据字典快照,这样就可以实现离线分析。
3、允许对DML操作按事务进行分组:可以在START_LOGMNR()中设置COMMITTED_DATA_ONLY选项,实现对DML操作的分组,这样将按SCN的顺序返回已经提交的事务。
4、支持SCHEMA的变化:在数据库打开的状态下,如果使用了LogMiner的DDL_DICT_TRACKING选项,Oracle9i的LogMiner将自动对比最初的日志流和当前系统的数据字典,并返回正确的DDL语句,并且会自动侦察并标记当前数据字典和最初日志流之间的差别,这样即使最初日志流中所涉及的表已经被更改或者根本已经不存在,LogMiner同样会返回正确的DDL语句。
5、在日志中记录更多列信息的能力:例如对于UPDATE操作不仅会记录被更新行的情况,还可以捕捉更多前影信息。
6、支持基于数值的查询:Oracle9i LogMiner在支持原有基于元数据(操作、对象等)查询的基础上,开始支持基于实际涉及到的数据的查询。例如涉及一个工资表,现在我们可以很容易地查出员工工资由1000变成2000的原始更新语句,而在之前我们只能选出所有的更新语句。
三、Oracle8i/9i的日志分析过程
LogMiner只要在实例起来的情况下都可以运行,LogMiner使用一个字典文件来实现Oracle内部对象名称的转换,如果没有这个字典文件,则直接显示内部对象编号,例如我们执行下面的语句:
delete from "C"."A" where "C1" = ‘gototop’ and ROWID = 'AAABg1AAFAAABQaAAH'; 如果没有字典文件,LogMiner分析出来的结果将是: delete from "UNKNOWN"."OBJ# 6197" where "COL 1" = HEXTORAW('d6a7d4ae') and ROWID = 'AAABg1AAFAAABQaAAH';
如果想要使用字典文件,数据库至少应该出于MOUNT状态。然后执行dbms_logmnr_d.build过程将数据字典信息提取到一个外部文件中。下面是具体分析步骤:
1、确认设置了初始化参数:UTL_FILE_DIR,并确认Oracle对改目录拥有读写权限,然后启动实例。示例中UTL_FILE_DIR参数如下:
SQL> show parameter utl NAME TYPE VALUE ------------------------ ----------- ------------------------------ utl_file_dir string /data6/cyx/logmnr
这个目录主要用于存放dbms_logmnr_d.build过程所产生的字典信息文件,如果不用这个,则可以不设,也就跳过下面一步。
2、生成字典信息文件:
exec dbms_logmnr_d.build(dictionary_filename =>' dic.ora',dictionary_location => '/data6/cyx/logmnr');
其中dictionary_location指的是字典信息文件的存放位置,它必须完全匹配UTL_FILE_DIR的值,例如:假设UTL_FILE_DIR=/data6/cyx/logmnr/,则上面这条语句会出错,只因为UTL_FILE_DIR后面多了一个“/”,而在很多其它地方对这一“/”是不敏感的。
dictionary_filename指的是放于字典信息文件的名字,可以任意取。当然我们也可以不明确写出这两个选项,即写成:
exec dbms_logmnr_d.build('dic.ora','/data6/cyx/logmnr');
如果你第一步的参数没有设,而直接开始这一步,Oracle会报下面的错误:
ERROR at line 1: ORA-01308: initialization parameter utl_file_dir is not set ORA-06512: at "SYS.DBMS_LOGMNR_D", line 923 ORA-06512: at "SYS.DBMS_LOGMNR_D", line 1938 ORA-06512: at line 1
需要注意的是,在oracle817 for Windows版中会出现以下错误:
14:26:05 SQL> execute dbms_logmnr_d.build('oradict.ora','c:\oracle\admin\ora\log'); BEGIN dbms_logmnr_d.build('oradict.ora','c:\oracle\admin\ora\log'); END; * ERROR at line 1: ORA-06532: Subscript outside of limit ORA-06512: at "SYS.DBMS_LOGMNR_D", line 793 ORA-06512: at line 1
解决办法:
编辑"$ORACLE_HOME/rdbms/admindbmslmd.sql"文件,把其中的 TYPE col_desc_array IS VARRAY(513) OF col_description; 改成: TYPE col_desc_array IS VARRAY(700) OF col_description;
保存文件,然后执行一遍这个脚本:
15:09:06 SQL> @c:\oracle\ora81\rdbms\admin\dbmslmd.sql Package created. Package body created. No errors. Grant succeeded.
然后重新编译DBMS_LOGMNR_D包:
15:09:51 SQL> alter package DBMS_LOGMNR_D compile body; Package body altered. 之后重新执行dbms_logmnr_d.build即可: 15:10:06 SQL> execute dbms_logmnr_d.build('oradict.ora','c:\oracle\admin\ora\log'); PL/SQL procedure successfully completed.
3、添加需要分析的日志文件
SQL>exec dbms_logmnr.add_logfile( logfilename=>' /data6/cyx/rac1arch/arch_1_197.arc', options=>dbms_logmnr.new); PL/SQL procedure successfully completed.
这里的options选项有三个参数可以用:
NEW - 表示创建一个新的日志文件列表
ADDFILE - 表示向这个列表中添加日志文件,如下面的例子
REMOVEFILE - 和addfile相反。
SQL> exec dbms_logmnr.add_logfile( logfilename=>' /data6/cyx/rac1arch/arch_2_86.arc', options=>dbms_logmnr.addfile); PL/SQL procedure successfully completed.
4、当你添加了需要分析的日志文件后,我们就可以让LogMiner开始分析了:
SQL> exec dbms_logmnr.start_logmnr(dictfilename=>'/data6/cyx/logmnr/dic.ora'); PL/SQL procedure successfully completed.
如果你没有使用字典信息文件(此时我们只需要启动实例就可以了),那么就不需要跟dictfilename参数:
SQL> exec dbms_logmnr.start_logmnr(); PL/SQL procedure successfully completed.
当然dbms_logmnr.start_logmnr()过程还有其它几个用于定义分析日志时间/SCN窗口的参数,它们分别是:
STARTSCN / ENDSCN - 定义分析的起始/结束SCN号,
STARTTIME / ENDTIME - 定义分析的起始/结束时间。
例如下面的过程将只分析从 '2003-09-21 09:39:00'到'2003-09-21 09:45:00'这段时间的日志:
SQL> exec dbms_logmnr.start_logmnr(dictfilename=>'/data6/cyx/logmnr/dic.ora' , - starttime => '2003-09-21 09:39:00',endtime => '2003-09-21 09:45:00'); PL/SQL procedure successfully completed.
上面过程第一行结尾的“-”表示转行,如果你在同一行,则不需要。我们可以看到有效日志的时间戳:
SQL> select distinct timestamp from v$logmnr_contents; TIMESTAMP ------------------- 2003-09-21 09:40:02 2003-09-21 09:42:39
这里需要注意的是,因为我之前已经设置NLS_DATE_FORMAT环境变量,所以上面的日期可以直接按这个格式写就行了,如果你没有设,则需要使用to_date函数来转换一下。
SQL> !env grep NLS NLS_LANG=american_america.zhs16cgb231280 NLS_DATE_FORMAT=YYYY-MM-DD HH24:MI:SS ORA_NLS33=/oracle/oracle9/app/oracle/product/9.2.0/ocommon/nls/admin/data 使用to_date的格式如下: exec dbms_logmnr.start_logmnr(dictfilename=>'/data6/cyx/logmnr/dic.ora',- starttime => to_date('2003-09-21 09:39:00','YYYY-MM-DD HH24:MI:SS'),- endtime => to_date('2003-09-21 09:45:00','YYYY-MM-DD HH24:MI:SS'));
STARTSCN 和ENDSCN参数使用方法类似。
5、好了,在上面的过程执行结束之后,我们就可以通过访问与LogMiner相关的几个视图来提取我们需要的信息了。其中在v$logmnr_logs中可以看到我们当前分析的日志列表,如果数据库有两个实例(即OPS/RAC),在v$logmnr_logs中会有两个不同的THREAD_ID。
而真正的分析结果是放在v$logmnr_contents中,这里面有很多信息,我们可以根据需要追踪我们感兴趣的信息。后面我将单独列出来讲常见的追踪情形。
6、全部结束之后,我们可以执行dbms_logmnr.end_logmnr过程退出LogMiner分析过程,你也可以直接退出SQL*PLUS,它会自动终止。
This page is an archive of entries from December 2005 listed from newest to oldest.
November 2005 is the previous archive.
January 2006 is the next archive.
Find recent content on the main index or look in the archives to find all content.
|