fjmingyang - by - 25 十二月, 2007 16:31

以9.2.0.1升级到9.2.0.8为例

1、下载

到metalink.oracle.com -〉Patches&Updates-〉Bug Database-〉Product or Family-〉输入RDBMS Server-〉Release选Oracle 9.2.0.8-〉Patch Type选Patchset/MiniPack-〉Platform选欲安装的OS类型-〉Go

2、安装

用Oracle安装帐号登陆

先设置下DISPLAY变量

unzip解压,进入解压目录运行./runInstaller,其他默认

最后运行root.sh脚本,提示选y



fjmingyang - by - 29 十一月, 2007 15:18

1、什么是审计

简单来讲,就是把对数据库的操作记录下来。不管你是否打开数据库的审计功能,以下这些操作系统会强制记录。

l 用管理员权限连接Instance

l 启动数据库

l 关闭数据库

2、和审计相关的两个主要参数

Audit_sys_operations

默认为false,当设置为true时,所有(注意是所有!)sys用户(包括以sysdba,sysoper身份登录的用户)的操作都会被记录,audit trail不会写在aud$表中,这个很好理解,如果数据库还未启动aud$不可用,那么像conn /as sysdba这样的连接信息,只能记录在其它地方。如果是windows平台,audti trail会记录在windows的事件管理中,如果是linux/unix平台则会记录在audit_file_dest参数指定的文件中

Audit_trail

有三个取值

None :默认值,不做审计

DB :将audit trail 记录在数据库的审计相关表中,如aud$

OS :将audit trail 记录在操作系统文件中,文件名由audit_file_dest参数指定

注:这两个参数是static参数,需要重新启动数据库才能生效。

 查看全文


fjmingyang - by - 28 十一月, 2007 22:27

SQL> show user
USER is "SYS"
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Prod
PL/SQL Release 10.1.0.2.0 - Production
CORE 10.1.0.2.0 Production
TNS for 32-bit Windows: Version 10.1.0.2.0 - Production
NLSRTL Version 10.1.0.2.0 - Production

SQL> show parameter audit

NAME TYPE VALUE
------------------------------------ ----------- ---------------
audit_sys_operations boolean FALSE
audit_trail string DB
SQL> audit table ;

Audit succeeded.

SQL> delete from aud$;

5 rows deleted.

SQL> commit;

SQL> conn cmy/cmy;
Connected.
SQL> drop table t;

Table dropped.

SQL> select count(*) from user_audit_trail;

COUNT(*)
----------
1 --------审计成功


偶然发现如果drop table t这句放在toad 8.6版 里面执行,不会生成审计记录!不知道是不是toad的bug.



fjmingyang - by - 27 十一月, 2007 15:38

本文对一些基本概念只是一带而过甚至略过,更多的请参考官方文档。

What is Lock

Oracle的锁机制用于管理对共享资源的并发访问。锁由Oracle自动管理,当事务(Transaction)结束后,自动释放。

锁可分为两个基本类型:Share(共享锁)Exclusive(排它锁)

What is Deadlock?

当两个或多个用户等待彼此之间的资源时发生死锁(Deadlock,避免死锁的办法就是使事务按照一定的顺序对表加锁,同时考虑先加最昂贵(排它性最强)的锁。

 查看全文


fjmingyang - by - 21 十一月, 2007 11:32

假设有一个表t,

select * fromt t;

x

----

1

4

5

我们在sqlplus/toad/developer2000执行select avg(x) from t;都不会报错,但在Asp.net却会报:OCI-22053: 溢出错误
解决的办法: select round(avg(x),2) from t;

 查看全文


fjmingyang - by - 11 十一月, 2007 22:47

From: http://tolywang.itpub.net/post/48/287344

dbms_stats包问世以后,Oracle专家可通过一种简单的方式来为CBO收集统计数据。目前,已经不再推荐你使用老式的分析表和dbms_utility方法来生成CBO统计数据。那些古老的方式甚至有可能危及SQL的性能,因为它们并非总是能够捕捉到有关表和索引的高质量信息。CBO使用对象统计,为所有SQL语句选择最佳的执行计划。

 查看全文


fjmingyang - by - 02 十一月, 2007 11:27

ORA-25153: Temporary Tablespace is Empty

想起前几天重建了控制文件,才导致tempfile丢失,重新把tempfile加进去就可以了

SYS>select * from v$tempfile;

no rows selected

SYS>alter tablespace temp2 add tempfile 'd:oracleoradatatestdbtemp01.dbf' reuse

Tablespace altered.



fjmingyang - by - 02 十一月, 2007 10:45

C:Documents and Settingsmingyang_chen>exp userid=cmy/cmy file=g:test.dmp log=
g:test.log rows=n indexes=y direct=y recordlength=65535

遇到如下错误>>

 查看全文


fjmingyang - by - 28 十月, 2007 22:59

情况描述

客户报告数据库故障,新来的系统管理员误操作。删掉了一些文件。具体情况是:删掉了所有重要数据文件、所有控制文件。数据库原来是归档模式,用rman备份数据,而rman 使用控制文件。幸运的是,最后一次 rman full 备份是包括了控制文件在内。系统没有设定自动备份控制文件。现在状况是数据库无法启动。

不用说,客户的备份方案不够完善,但是这时候再去说这些话责备用户有事后诸葛亮之嫌,"用户是上帝,不要去得罪他"。还有,客户有Full备份(虽然不是自动备份控制文件,这样无法用常规的恢复步骤来进行恢复)。这对我们来说是个绝对的好消息。

下面我们通过一次模拟操作来演示这个问题的解决办法。

 查看全文


fjmingyang - by - 28 十月, 2007 22:00

SQL> alter database mount;
alter database mount
*
ERROR at line 1:
ORA-00201: controlfile version 10.1.0.2.0 incompatible with ORACLE version
10.0.0.0.0
ORA-00202: controlfile: 'E:ORACLEPRODUCT10.1.0ORADATAORCLCONTROL01.CTL' 查看全文


fjmingyang - by - 26 十月, 2007 19:41

From: http://logzgh.itpub.net/post/3185/42513

scn号与oracle数据库恢复过程有着密切的关系,只有很好地理解了这层关系,才能深刻地理解恢复的原理,从而才能很好地解决这方面的问题。

一。SCN与CHECKPOINT
CKPT进程在checkpoint发生时,将当时的SCN号写入数据文件头和控制文件,同时通知DBWR进程将数据块写到
数据文件。
CKPT进程也会在控制文件中记录RBA(redo block address),以标志Recovery需要从日志中哪个地方开始。

与checkpoint相关的SCN号有四个,其中三个存在控制文件中,一个存放在数据文件头中。
这四个分别是:
1.System Checkpoint SCN
当checkpoint完成后,ORACLE将System Checkpoint SCN号存放在控制文件中。
我们可以通过下面SQL语句查询:
select checkpoint_change# from v$database;

2.Datafile Checkpoint SCN
当checkpoint完成后,ORACLE将Datafile Checkpoint SCN号存放在控制文件中。
我们可以通过下面SQL语句查询所有数据文件的Datafile Checkpoinnt SCN号。
select name,checkpoint_change# from v$datafile;

3.Start SCN号
ORACLE将Start SCN号存放在数据文件头中。
这个SCN用于检查数据库启动过程是否需要做media recovery.
我们可以通过以下SQL语句查询:
select name,checkpoint_change# from v$datafile_header;

4.End SCN号
ORACLE将End SCN号存放在控制文件中。
这个SCN号用于检查数据库启动过程是否需要做instance recovery.
我们可以通过以下SQL语句查询:
select name,last_change# from v$datafile;

在数据库正常运行的情况下,对可读写的,online的数据文件,该SCN号为NULL.

 查看全文


fjmingyang - by - 26 十月, 2007 18:10

1. Read the Data Block.

2. Read the Row Header.

3. Check the Lock Byte to determine whether there's an ITL entry.

4. Read the ITL entry to determine the Transaction ID (Xid).

5. Read the Transaction Table using the Transaction ID. If the transaction has been committed and has a System Commit Number less than the query's System Change Number, update the status of the block (block cleanout) and start over at step 1.

6. Read the last undo block (Uba).

7. Compare the block transaction ID with the transaction table transaction ID. If the Transaction ID in the undo block doesn't equal the Transaction ID from the Transaction Table, then issue ORA-1555, Snapshot Too Old.

8. If the Transaction IDs are identical, make a copy of the data block in memory. Starting with the head undo entry, apply the changes to the copied data block.

9. If the tail undo entry (the actual first undo entry in the chain, or the last in the chain going backwards!) indicates another data block address, read the indicated undo block into memory and repeat steps 7 and 8 until the undo entries don't contain a value for the data block address.

10. When there's no "previous data block address," the transaction has been completely undone.

11. If the undo entry contains:

a. a pointer to a previous transaction undo block address, read the Transaction ID in the previous transaction undo block header and read the appropriate Transaction Table entry. Return to step 5.

b. an ITL record, restore the ITL record to the data block. Return to step 4.
 查看全文


fjmingyang - by - 04 九月, 2007 09:25

在itpub上看到一个帖子,清楚介绍了raid1+0 与raid0+1的区别,摘录如下

http://www.itpub.net/845548,2.html

RAID 0+1: We stripe together drives 1, 2, 3, 4 and 5 into RAID 0 stripe set "A", and drives 6, 7, 8, 9 and 10 into RAID 0 stripe set "B". We then mirror A and B using RAID 1. If one drive fails, say drive #2, then the entire stripe set "A" is lost, because RAID 0 has no redundancy; the RAID 0+1 array continues to chug along because the entire stripe set "B" is still functioning. However, at this point you are reduced to running what is in essence a straight RAID 0 array until drive #2 can be fixed. If in the meantime drive #9 goes down, you lose the entire array.
RAID 1+0: We mirror drives 1 and 2 to form RAID 1 mirror set "A"; 3 and 4 become "B"; 5 and 6 become "C"; 7 and 8 become "D"; and 9 and 10 become "E". We then do a RAID 0 stripe across sets A through E. If drive #2 fails now, only mirror set "A" is affected; it still has drive #1 so it is fine, and the RAID 1+0 array continues functioning. If while drive #2 is being replaced drive #9 fails, the array is fine, because drive #9 is in a different mirror pair from #2. Only two failures in the same mirror set will cause the array to fail, so in theory, five drives can fail--as long as they are all in different sets--and the array would still be fine.
Clearly, RAID 1+0 is more robust than RAID 0+1. Now, if the controller running RAID 0+1 were smart, when drive #2 failed it would continue striping to the other four drives in stripe set "A", and if drive #9 later failed it would "realize" that it could use drive #4 in its stead, since it should have the same data. This functionality would theoretically make RAID 0+1 just as fault-tolerant as RAID 1+0. Unfortunately, most controllers aren't that smart. It pays to ask specific questions about how a multiple RAID array implementation handles multiple drive failures, but in general, a controller won't swap drives between component sub-arrays unless the manufacturer of the controller specifically says it will.

The same impact on fault tolerance applies to rebuilding. Consider again the example above. In RAID 0+1, if drive #2 fails, the data on five hard disks will need to be rebuilt, because the whole stripe set "A" will be wiped out. In RAID 1+0, only drive #2 has to be rebuilt. Again here, the advantage is to RAID 1+0.



fjmingyang - by - 15 八月, 2007 11:58

analyze table t compute statistics = analyze table t compute statistics for table for all indexes for all columns

for table的统计信息存在于视图:user_tables 、all_tables、dba_tables

for all indexes的统计信息存在于视图: user_indexes 、all_indexes、dba_indexes

for all columns的统计信息存在于试图:user_tab_columns、all_tab_columns、dba_tab_columns

当analyze table t delete statistics 会删除所有的statistics

 查看全文


fjmingyang - by - 18 六月, 2007 14:34

ORACLE UPDATE 语句语法与性能分析的一点看法

----选择自 aceplus 的 Blog

http://blog.csdn.net/aceplus/archive/2005/07/02/410786.aspx

为了方便起见,建立了以下简单模型,和构造了部分测试数据:
在某个业务受理子系统BSS中,
--客户资料表
create table customers
(
customer_id number(8) not null, -- 客户标示
city_name varchar2(10) not null, -- 所在城市
customer_type char(2) not null, -- 客户类型

...
)
create unique index PK_customers on customers (customer_id)
由于某些原因,客户所在城市这个信息并不什么准确,但是在
客户服务部的CRM子系统中,通过主动服务获取了部分客户20%的所在
城市等准确信息,于是你将该部分信息提取至一张临时表中:
create table tmp_cust_city
(
customer_id number(8) not null,
citye_name varchar2(10) not null,
customer_type char(2) not null
)

1) 最简单的形式
--经确认customers表中所有customer_id小于1000均为'北京'
--1000以内的均是公司走向全国之前的本城市的老客户:)
update customers
set city_name='北京'
where customer_id<1000

2) 两表(多表)关联update -- 仅在where字句中的连接
--这次提取的数据都是VIP,且包括新增的,所以顺便更新客户类别
update customers a -- 使用别名
set customer_type='01' --01 为vip,00为普通
where exists (select 1
from tmp_cust_city b
where b.customer_id=a.customer_id
)

3) 两表(多表)关联update -- 被修改值由另一个表运算而来
update customers a -- 使用别名
set city_name=(select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id)
where exists (select 1
from tmp_cust_city b
where b.customer_id=a.customer_id
)
-- update 超过2个值
update customers a -- 使用别名
set (city_name,customer_type)=(select b.city_name,b.customer_type
from tmp_cust_city b
where b.customer_id=a.customer_id)
where exists (select 1
from tmp_cust_city b
where b.customer_id=a.customer_id
)
注意在这个语句中,
=(select b.city_name,b.customer_type
from tmp_cust_city b
where b.customer_id=a.customer_id
)

(select 1
from tmp_cust_city b
where b.customer_id=a.customer_id
)
是两个独立的子查询,查看执行计划可知,对b表/索引扫描了2篇;
如果舍弃where条件,则默认对A表进行全表
更新,但由于(select b.city_name from tmp_cust_city b where where b.customer_id=a.customer_id)
有可能不能提供"足够多"值,因为tmp_cust_city只是一部分客户的信息,
所以报错(如果指定的列--city_name可以为NULL则另当别论):

01407, 00000, "cannot update (%s) to NULL"
// *Cause:
// *Action:

一个替代的方法可以采用:
update customers a -- 使用别名
set city_name=nvl((select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id),a.city_name)
或者
set city_name=nvl((select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id),'未知')
-- 当然这不符合业务逻辑了

4) 上述3)在一些情况下,因为B表的纪录只有A表的20-30%的纪录数,
考虑A表使用INDEX的情况,使用cursor也许会比关联update带来更好的性能:

set serveroutput on

declare
cursor city_cur is
select customer_id,city_name
from tmp_cust_city
order by customer_id;
begin
for my_cur in city_cur loop

update customers
set city_name=my_cur.city_name
where customer_id=my_cur.customer_id;

/** 此处也可以单条/分批次提交,避免锁表情况 **/
-- if mod(city_cur%rowcount,10000)=0 then
-- dbms_output.put_line('----');
-- commit;
-- end if;
end loop;
end;

5) 关联update的一个特例以及性能再探讨
在oracle的update语句语法中,除了可以update表之外,也可以是视图,所以有以下1个特例:
update (select a.city_name,b.city_name as new_name
from customers a,
tmp_cust_city b
where b.customer_id=a.customer_id
)
set city_name=new_name
这样能避免对B表或其索引的2次扫描,但前提是 A(customer_id) b(customer_id)必需是unique index
或primary key。否则报错:

01779, 00000, "cannot modify a column which maps to a non key-preserved table"
// *Cause: An attempt was made to insert or update columns of a join view which
// map to a non-key-preserved table.
// *Action: Modify the underlying base tables directly.

6)oracle另一个常见错误
回到3)情况,由于某些原因,tmp_cust_city customer_id 不是唯一index/primary key
update customers a -- 使用别名
set city_name=(select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id)
where exists (select 1
from tmp_cust_city b
where b.customer_id=a.customer_id
)
当对于一个给定的a.customer_id
(select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id)
返回多余1条的情况,则会报如下错误:

01427, 00000, "single-row subquery returns more than one row"
// *Cause:
// *Action:

一个比较简单近似于不负责任的做法是
update customers a -- 使用别名
set city_name=(select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id and rownum=1)

如何理解 01427 错误,在一个很复杂的多表连接update的语句,经常因考虑不周,出现这个错误,
仍已上述例子来描述,一个比较简便的方法就是将A表代入 值表达式 中,使用group by 和
having 字句查看重复的纪录
(select b.customer_id,b.city_name,count(*)
from tmp_cust_city b,customers a
where b.customer_id=a.customer_id
group by b.customer_id,b.city_name
having count(*)>=2
)



fjmingyang - by - 15 六月, 2007 16:58

在网上看到一小段procedure可以用来发mail,测试了一下没问题,贴上来备忘

CREATE OR REPLACE PROCEDURE send_email (
p_recipient IN VARCHAR2,
p_message IN VARCHAR2,
p_subject IN VARCHAR2 default '',
p_sender IN VARCHAR2 default 'TestingDB@163.com')
IS
crlf varchar2(2) := chr(13) || chr(10);
v_mailhost varchar2(30) := '192.168.199.34';
mail_conn utl_smtp.connection;
msg varchar2(4000) := 'Date:' ||
to_char(sysdate,'dd mon yy hh24:mi:ss') || crlf ||
'From: ' || p_sender || '<'||p_sender||'>' ||crlf ||
'Subject: '||p_subject || crlf||
'To: '|| p_recipient || '<' || p_recipient || '>' ||crlf||
p_message;
begin
mail_conn := utl_smtp.open_connection(v_mailhost,25);
utl_smtp.helo(mail_conn,v_mailhost);
utl_smtp.mail(mail_conn,p_sender);
utl_smtp.rcpt(mail_conn,p_recipient);
utl_smtp.data(mail_conn,msg);
utl_smtp.quit(mail_conn);
exception
when others then
dbms_output.put_line(dbms_utility.format_error_stack);
dbms_output.put_line(dbms_utility.format_call_stack);
end;

调用如下:

exec send_email(收件人,内容,主题,发件人);



fjmingyang - by - 07 六月, 2007 11:00

在ITPUB上有一则非常巧妙的SQL技巧,学习一下,记录在这里。

最初的问题是这样的:

我有一个表结构,
fphm,kshm
2014,00000001
2014,00000002
2014,00000003
2014,00000004
2014,00000005
2014,00000007
2014,00000008
2014,00000009
2013,00000120
2013,00000121
2013,00000122
2013,00000124
2013,00000125

(第二个字段内可能是连续的数据,可能存在断点。)

怎样能查询出来这样的结果,查询出连续的记录来。
就像下面的这样?
2014,00000001,00000005
2014,00000009,00000007
2013,00000120,00000122
2013,00000124,00000125

ITPUB上的朋友给出了一个非常巧妙的答案:

SELECT b.fphm, MIN (b.kshm) Start_HM, MAX (b.kshm) End_HM
FROM (SELECT a.*, TO_NUMBER (a.kshm - ROWNUM) cc
FROM (SELECT *
FROM t
ORDER BY fphm, kshm) a
) b
GROUP BY b.fphm, b.cc

from : http://blog.csdn.net/annicybc/archive/2007/02/25/1514147.aspx



fjmingyang - by - 24 五月, 2007 11:49

工作中碰到一条set define off语句不知道何意,google一下,发现如下解释:http://tag.csdn.net/Article/014564c7-41af-459b-bfd5-56addeab9bdc.html

在plsql里边执行:update userinfo set pageurl='myjsp?page=1&pagesize=10' where id='test'这条sql语句往数据库的pageurl字段放进去了一个url地址,但是执行的时候却并非那么理想,因为这其中有一个oracle的特殊字符,需要进行转义,那就是字符'&'.怎么处理上例中的特殊字符?

3个办法:

1) update userinfo set pageurl='myjsp?page=1'||'&'||'pagesize=10' where id='test'

2) update userinfo set pageurl='myjsp?page=1'||chr(38)||'pagesize=10' where id='test'其中||是连字符, chr(38)跟ASCII的字符转码是一致的。

3)plsql中还可以set define off来关闭特殊字符,还可以用show define来查看有些特殊定义的字符。 Oracle中的转义字符分类:默认栏目 如果向Oracle中插入带有单引号或者&



fjmingyang - by - 15 五月, 2007 16:50

首先,这并不是一篇十分详尽的安装dataguard文章,因为这样的文章网上很多,写这篇文章的初衷在于证实个人的一些想法,同时希望能对那些没有Unix环境而又想做dataguard测试的朋友有所帮助。整个过程只是一个简单的描述,把需要注意的地方用我的理解注释一下而已。其中某些章节piner在《Oracle 9i备用数据库配置使用参考手册》中描述得很清楚,我就不再螯述了,直接引用,在此感谢。

Platform: Windows2003(physical standby),WindowsXP(primary)

Oracle: physical standbyprimary 都是9.2.0.6

整个过程大体分为以下几个步骤:

1、 建立备用库的controlfile

在主库中 SQLalter database create standby controlfile as ‘e:backupstdctl01.ctl’

2、 配置备用库的tnsnames.ora文件

PRIMARYDB =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.1)(PORT = 1521))

)

(CONNECT_DATA =

(SID = testdb)

(SERVER = DEDICATED)

)

)

STANDBYDB =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.1)(PORT = 1521))

)

(CONNECT_DATA =

(SID = testdb)

(SERVER = DEDICATED)

)

)

tnsping测试以上tnsname.

3、 配置备用库的parameter file inittestdb.ora

备用库的参数文件需要改动地方很少,

*.control_files='e:oracleoradatatestdbstdctl01.CTL','e:oracleoradatatestdbstdctl02.CTL','e:oracleoradatatestdbstdctl03.CTL' (指向1步骤建立的standby controlfile)

*.db_file_name_convert='d:oracleoradata','e:oracleoradata'(如果两数据库的目录结构不一样)

*.log_file_name_convert=='d:oracleoradata','e:oracleoradata'(如果两数据库的目录结构不一样)

其余参数按照默认亦可,几个比较重要的参数如下(建议修改)

*.log_archive_dest_1='location=e:oracleora92databasearchive'

*.log_archive_dest_2='service=standbydb LGWR REOPEN=300'

(设定这两个参数是为了当主库switchover为备用库,备用库switchover为主库,仍然可以进行日志的传输,这样新的主库仍旧可以切回备用库,新的备用库仍旧可以切回主库)

*.remote_archive_enable=TRUE (默认值)

*.standby_archive_dest='e:oracleora92databasearchive'

*.fal_server='PRIMARYDB' (连接主库的tnsname

*.fal_client='STANDBYDB' (连接备用库的tnsname

备注:不配置fal_serverfal_client也是可以的,Oracle9i具有自动补齐archivelog缺失(gap)的功能

*.DB_FILE_NAME_CONVERT

db_file_name_convert 主库和备用库的数据文件转换目录对映,如果有多个对映,逐一指明对映关系。

格式:*.db_file_name_convert=主库数据文件目录,备用库数据文件目录

例如:

一对一映射设定

*.db_file_name_convert='d:oracleoradata','e:oracleoradata'

多对多映射设定时,所有相对应路径都一一写出来

LOG_FILE_NAME_CONVERT

指明主库和备用库的log文件转换目录对映。

格式为:*. log_file_name_convert=主库log目录,备用库目录

例如:

*.log_file_name_convert=='d:oracleoradata','e:oracleoradata'

standby_file_management

这个参数也是9i的新参数,可以自动同步数据文件。

例如:

standby_file_management =auto

如果用到了该参数,将有如下限制

ALTER DATABASE RENAME

ALTER DATABASE ADD/DROP LOGFILE

ALTER DATABASE ADD/DROP STANDBY LOGFILE MEMBER

ALTER DATABASE CREATE DATAFILE AS

4、 建立物理备用库

有两种方法:

方法一 使用主库的冷备份

1) 把冷备份拷贝到备用库服务器上

2) 在备用库服务器上建立与主库服务器相同的目录结构

3) 在备用库服务器上定义ORACLE_SID环境变量 set ORACLE_SID=testdb

4) 在备用库服务器上用oradim建立serviceoradim –new –sid %ORACLE_SID%

(备注:SID可以和主库不一样,SID只是用于在操作系统上标识Instance,而一个Instance可以打开任意一个数据库,所以只要备用库的db name和主库一样就可以)

5) 在备用库服务器上生成密码文件:

orapwd file=%ORACLE_HOME%databasepwd<sid>.ora password=sys

方法二 使用主库的热全备份(若使用这种方法1步骤中的standby controlfile要在做完热备后创建,因为此时才会有记录热备文件信息

1) 在主库服务器上使用rman热全备主库,e.g.

RMAN>connect taget /

RMAN>backup database format=’e:backupbackup.bak’

2) 在主库服务器上 SQLalter database create standby controlfile as ‘e:backupstdctl01.ctl’,并拷贝到备用库服务器上inittestdb.oracontrol_files指定的路径下.并复制多份

3) 在主库服务器上拷贝热备文件到备用库服务器上相同的路径下,本例为e:backup

4) 在备用库服务器上set ORACLE_SID=testdb

5) 在备用库服务器上用oradim建立serviceoradim –new –sid %ORACLE_SID%

6) 在备用库服务器上生成密码文件:

orapwd file=%ORACLE_HOME%databasepwd<sid>.ora password=sys

7) 在备用库服务器上使用standby controlfile恢复数据库

启动到mount

SQL> connect / as sysdba

Connected to an idle instance.

SQL>startup nomount pfile=e:oracleora92databaseinittestdb.ora

SQL>alter database mount standby database;

RMAN

RMAN> connect target /

RMAN> restore database;此时数据会恢复到e:oracleoradatatestdb下,因为我们在inittestdb.ora中指定了db_file_name_convert参数

SQL> recover standby database;(如果有需要恢复的日志可以运行此命令,本例可以跳过)

到此我们的物理备用库已经创建完毕,就差启动了,那么主库如何知道备用库的位置及又以什么方式(保护模式)传递redo的呢?请接着往下看

5、 配置主库的tnsnames.ora文件

STANDBYDB =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.2)(PORT = 1521))

)

(CONNECT_DATA =

(SID = testdb)

(SERVER = DEDICATED)

)

)

6、 配置主库的参数文件:inittestdb.ora

*.log_archive_dest_1='location=d:oracleora92databasearchive' (指定主库日志的归档路径)

*.log_archive_dest_2='service=standbydb LGWR REOPEN=300' (指定主库日志的第二归档路径,即通过主库tnsnames.ora文件中定义的standbydb连接指向备用库)

7、 启动物理备用库

在备用库服务器上

SQL> connect / as sysdba

Connected to an idle instance.

SQL>startup nomount pfile=e:oracleora92databaseinittestdb.ora

SQL>alter database mount standby database;

SQL>alter database recover managed standby database disconnect from session;(启动MRP进程,把归档日志应用到备份库上,注意:不管采用什么保护模式,在备用日志或者当前正在归档的日志中的内容是不能马上被应用的,必须当归档完成后才由MRPn进程应用到备用数据库)

8、 启动主库

主库的启动和一般数据库的启动没有区别,在主库服务器上

SQL> connect / as sysdba

Connected to an idle instance.

SQL>startup pfile=e:oracleora92databaseinittestdb.ora

 查看全文


fjmingyang - by - 14 五月, 2007 09:42

[oracle@standby oradata]$ rman target /

Recovery Manager: Release 9.2.0.4.0 - Production

Copyright (c) 1995, 2002, Oracle Corporation. All rights reserved.

connected to target database (not started)

首先启动数据库到nomount状态

RMAN> startup nomount;

Oracle instance started

Total System Global Area 135337420 bytes

Fixed Size 452044 bytes
Variable Size 109051904 bytes
Database Buffers 25165824 bytes
Redo Buffers 667648 bytes

尝试从自动备份中恢复控制文件

RMAN> restore controlfile to '/opt/oracle/oradata/control01.ctl' from autobackup;

Starting restore at 09-MAR-05

using target database controlfile instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=11 devtype=DISK
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of restore command at 03/09/2005 10:15:05
RMAN-06495: must explicitly specify DBID with SET DBID command

此时提示,必须显示的指定DBID,Oracle才能正确定位备份文件

RMAN> set DBID=1367687269

executing command: SET DBID

RMAN> restore controlfile to '/opt/oracle/oradata/control01.ctl' from autobackup;

Starting restore at 09-MAR-05

using channel ORA_DISK_1
channel ORA_DISK_1: looking for autobackup on day: 20050309
channel ORA_DISK_1: autobackup found: c-1367687269-20050309-00
channel ORA_DISK_1: controlfile restore from autobackup complete
Finished restore at 09-MAR-05

借用下eygle的例子:),这里谈谈为什么需要set dbid? 从字面上很容易理解,就是指定数据库的ID,(每个数据库的ID都是不同的,这里指定的是你要恢复的数据库的ID)。我们知道,Oracle startup nomount是需要parameter file的,而parameter file有指定db_name ,那为什么还需要set dbid呢?其实RMAN是可以使用一个dummy parameter file启动instance到nomount状态的,即虚拟一个db name为DUMMY的DB,故

restore controlfile to '/opt/oracle/oradata/control01.ctl' from autobackup;

RMAN无法判定你要从哪个DB的autobackup恢复

BTW:DBID可以在RMAN连接时得到

[oracle@standby oradata]$ rman target /

Recovery Manager: Release 9.2.0.4.0 - Production

Copyright (c) 1995, 2002, Oracle Corporation. All rights reserved.

connected to target database: PRIMARY (DBID=1367687269)

也可以从v$database得到

SQL> select dbid from v$database;

DBID
----------
3152029224

实际上每个数据文件和控制文件上也都包含dbid信息,可以自己写程序从数据文件文件中读取出来



fjmingyang - by - 13 五月, 2007 14:31

简单描述如下

expired : 如果备份文件在操作系统一级被删除,我们称这个文件expired(过期的),但是此时catalog或controlfile却仍然纪录着被删除备份文件的信息,我们可以用delete expired bakcup这样的命令来删除信息

obsolete:备份文件超过rman中设置的redundancy值,都称之为obsolete,看到有些人把它也翻译为“过期”,个人感觉容易和expired混淆,我的翻译是:“陈旧的”,其实这个备份文件和其他备份文件没什么两样,照样可以用来恢复,只是它过于“陈旧”(>redundancy)而已.我们可以用delete noprompt obsolete在操作系统级别删除它们



fjmingyang - by - 11 五月, 2007 15:50

临时文件(临时表空间)主要用于排序。对它的修改并不成生redo,换句话说当oracle出现故障后,它上面的数据是不可再现的(也没必要,因为它存储的只是一些临时数据或者叫中间结果),故controlfile并没有有关于tempfile的纪录,在做备份的时候也不需要备份临时文件。但是tempfile会生成undo ,而在oracle中undo总是受redo“保护”的,所以tempfile也会生成针对undo的少量redo。

为什么要对undo生成redo呢?我们来举一个关于临时表的例子。我们知道临时表是创建在tempfile上的,所以它同样也具有只生成“少量redo”的特性,假设一个修改表的Transaction 还未提交,此时Instance故障,当Oracle恢复的时候是先根据redo前滚到失败点,再对未提交的Transaction回滚。倘若没有对undo生成redo,前滚就无法生成Transaction Rollback所需的undo block,事务就无法回滚。

PS:查看谁在使用tempfile

Select t.Name, s.Sid, s.Serial#, q.Sql_Text, u.*
From V$sort_Usage u, V$tempfile t, V$session s, V$sql q
Where u.Segfile# =
t.File# + (Select Value From V$parameter Where Name = 'db_files')
And s.Saddr = u.Session_Addr
And u.Sqladdr = q.Address

当tempfile变得很大时,可以

1、kill session

2、create a new temporary tablespace

3、drop the old temporary tablespace



fjmingyang - by - 08 五月, 2007 11:05

在更改数据库归档模式时碰到ORA-00265错误

SQL> alter database archivelog;
alter database archivelog
*
ERROR 位于第 1 行:
ORA-00265: 要求例程恢复,无法设置 ARCHIVELOG 模式

查阅资料,解决方法如下:

 查看全文


fjmingyang - by - 24 四月, 2007 10:48

从meatlink下载了9.2..0.6的Path Set ,大小227M。在自己的win xp上打试试,结果到处报错,很多是orasql9.dll,orancrypt9.dll等dll文件正在被其他进程使用,无法写入的错误...

 查看全文


fjmingyang - by - 28 二月, 2007 09:51

SQL> @ %oracle_home%rdbmsadminutlxplan.sql

表已创建。---这个脚本只是创建一张plan_table表

SQL> @ %oracle_home%sqlplusadminplustrce.sql
SQL>
SQL> drop role plustrace;

角色已丢弃

SQL> create role plustrace;

角色已创建

SQL>
SQL> grant select on v_$sesstat to plustrace;

授权成功。

SQL> grant select on v_$statname to plustrace;

授权成功。

SQL> grant select on v_$session to plustrace;

授权成功。

SQL> grant plustrace to dba with admin option;

授权成功。

SQL>

SQL> conn test/test
已连接。

SQL> set autotrace on
SP2-0613: 无法验证 PLAN_TABLE 格式或实体
SP2-0611: 启用EXPLAIN报告时出错

 查看全文


fjmingyang - by - 26 二月, 2007 17:07

select * from dba_dependencies where referenced_name='T'


fjmingyang - by - 26 二月, 2007 17:02

SQL> select * from v$license
2 ;

SESSIONS_MAX SESSIONS_WARNING SESSIONS_CURRENT SESSIONS_HIGHWATER USERS_MAX
------------ ---------------- ---------------- ------------------ ----------
0 0 27 48 0

SQL> select * from v$resource_limit where resource_name='sessions';

RESOURCE_NAME CURRENT_UTILIZATION
------------------------------------------------------------ -------------------
MAX_UTILIZATION
---------------
INITIAL_ALLOCATION
--------------------------------------------------------------------------------
LIMIT_VALUE
--------------------------------------------------------------------------------
sessions 39
60
170
170

 查看全文


fjmingyang - by - 26 二月, 2007 14:18

Windows + Oracle9.2 测试环境突然无法 conn /as sysdba 提示:ERROR: ORA-01031: insufficient privileges

之前sqlnet.ora没有动过,怀疑是password file 损坏了,

关闭instance,重建密码文件

orapwd file=d:oracleora92databasepwdtestdb.ora password=sys

问题解决



fjmingyang - by - 22 十二月, 2006 13:31

今天查询要排序的时候突然报ORA-25153错误,SQL> Select * From v$bh b, dba_objects o Where b.ts#<>0 And b.objd=o.object_id
2 ;
Select * From v$bh b, dba_objects o Where b.ts#<>0 And b.objd=o.object_id
*
ERROR 位于第 1 行:
ORA-25153: 临时表空间为空

看了下v$tempfile发现为空,而实际的物理文件却存在,想来是因为前不久做RMAN试验所致

 查看全文


fjmingyang - by - 09 十二月, 2006 11:43

打开oem发现temp表空间的利用率达到99.99%,心中一紧,赶忙查下v$sort_usage,发现并没有使用记录,于是接着查了下v$sort_segment发现free_blocks并没有近于0,而是等于total_segment,看来temp表空间是正常,是OEM显示有误,因为oem是从v$temp_extent_pool统计的!

另外关于释放temp表空间的做法有不少,上网搜了一下,hrb_qiuyb作了很好的总结,引用原文如下

http://qiuyb.itpub.net/post/8049/61672

 查看全文


fjmingyang - by - 05 十二月, 2006 09:34

RESETLOGS | NORESETLOGS This clause determines whether Oracle Database resets the current log sequence number to 1, archives any unarchived logs (including the current log), and discards any redo information that was not applied during recovery, ensuring that it will never be applied. Oracle Database uses NORESETLOGS automatically except in the following specific situations, which require a setting for this clause:

  • You must specify RESETLOGS:

    • After performing incomplete media recovery or media recovery using a backup controlfile

    • After a previous OPEN RESETLOGS operation that did not complete

    • After a FLASHBACK DATABASE operation

  • If a created controlfile is mounted, then you must specify RESETLOGS if the online logs are lost, or you must specify NORESETLOGS if they are not lost.

from: http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_1004.htm



fjmingyang - by - 28 十一月, 2006 11:24

crosscheck archivelog all; 验证的是DB的归档日志即log_archive_dest参数指定位置的文件,当手工删除了归档日志以后,Rman备份会检测到日志缺失,从而无法进一步继续执行。
所以此时需要手工执行crosscheck过程,之后Rman备份可以恢复正常。

RMAN> crosscheck archivelog all;

释放的通道: ORA_DISK_1
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=18 devtype=DISK
对归档日志的验证失败
存档日志文件名 =D:ORACLEORA92DATABASEARCHIVEARC00026.001 记录 ID=28 时间戳
=607690515
对归档日志的验证失败
存档日志文件名 =D:ORACLEORA92DATABASEARCHIVEARC00027.001 记录 ID=29 时间戳
=607690586
已交叉检验的 2 对象

crosscheck backup of archivelog all;验证的是用rman 备份归档日志的备份文件,执行完这个命令后可用delete expired archivelog;删除状态为expired的备份文件

RMAN> crosscheck backup of archivelog all;

使用通道 ORA_DISK_1
交叉校验备份段: 找到为 'EXPIRED'
备份段 handle=D:ORACLEBACKUPARC39_TESTDB_39_1 recid=38 stamp=607690347
交叉校验备份段: 找到为 'EXPIRED'
备份段 handle=D:ORACLEBACKUPARC%E_TESTDB_41_1 recid=40 stamp=607690481
交叉校验备份段: 找到为 'EXPIRED'
备份段 handle=D:ORACLEBACKUPARC_%E_TESTDB_43_1 recid=42 stamp=607690517
交叉校验备份段: 找到为 'AVAILABLE'
备份段 handle=D:ORACLEBACKUPARC_%E_TESTDB_45_1 recid=44 stamp=607690588
交叉校验备份段: 找到为 'AVAILABLE'
备份段 handle=D:ORACLEBACKUPARC_%E_TESTDB_46_1 recid=45 stamp=607690590
交叉校验备份段: 找到为 'AVAILABLE'
备份段 handle=D:ORACLEBACKUPARC_%E_TESTDB_47_1 recid=46 stamp=607690592
已交叉检验的 6 对象

 查看全文


fjmingyang - by - 28 十一月, 2006 09:25

今天碰到了一个怪问题,明明archivelog 备份成功,可是crosscheck的时候去显示 对归档日志的验证失败,到网上搜了一下,发现是NLS_LANG的问题,set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK 即可。

tahiti关于crosscheck 的说明

Purpose

To verify the status of backups and copies recorded in the RMAN repository against media such as disk or tape. The CROSSCHECK command only processes files created on the same device type as the channels running the crosscheck.

Status of RMAN Backups

The CROSSCHECK command checks only objects marked AVAILABLE or EXPIRED by examining the files on disk for DISK channels or by querying the media manager for sbt channels. Table 2-2 describes the meaning of each status.

Table 2-2 Meaning of Crosscheck Status

StatusDescription

EXPIRED

Object is not found either in file system (for DISK) or in the media manager (for sbt). Note that for a backup set to be EXPIRED, all backup pieces in the set must be EXPIRED.

Note: EXPIRED does not mean the same as OBSOLETE.

个人注释:obsolete:当备份或者副本根据保存策略而被丢弃的时候,就会被标记为该状态。
expired:使用crosscheck对备份进行校验,当备份或者副本被存储在rman目录中,但是并没有物理存在于备份介质上时,就会被标记为该状态

AVAILABLE

Object is available for use by RMAN. For a backup set to be AVAILABLE, all backup pieces in the set must have the status AVAILABLE.

UNAVAILABLE

Object is not available for use by RMAN. For a backup set to be UNAVAILABLE, all backup pieces in the set must have the status UNAVAILABLE.

The CROSSCHECK command does not delete any files that it is unable to find, but updates their repository records to EXPIRED. Then, you can run DELETE EXPIRED to remove the repository records for all expired files as well as any existing physical files whose records show the status EXPIRED.

If some backup pieces or copies were erroneously marked as EXPIRED, for example, because the media manager was misconfigured, then after ensuring that the files really do exist in the media manager, run the CROSSCHECK BACKUP command again to restore those files to AVAILABLE status.

网上关于这个问题的原文如下

 查看全文


fjmingyang - by - 13 十一月, 2006 15:16

摘自http://yangtingkun.itpub.net/post/468/20584,很不错的文章,摘录到此,做个备忘。

Oracle物化视图的快速刷新机制是通过物化视图日志完成