飞 的个人资料二月飞雪日志列表留言簿 工具 帮助

日志


12月20日

WebDAV打开Office文档后无法保存

采用WebDAV技术,以编辑模式打开远程Word文档后,保存时总是弹出另存为窗口,并且保存时提示文档只读,无法保存。检查了IIS的设置每发现问题,干脆又把目录设置为完全共享,还是不行,网上也查了,没有发现实质性的解答,只说目录应该是NTFS格式的,我琢磨着是不是目录安全方面的设置不对,于是打开目录安全设置,赋予Users用户完全权限,再试一下终于可以了,然后又把原先的目录完全共享给取消,回头一试仍然可以,看来只要赋予Users用户完全权限就可以了。
11月10日

一次RMAN异地恢复试验中的问题

今天基本成功地试验了一次RMAN备份异地恢复过程,遭遇四点疑问或者问题:
1、RMAN自动备份control files和archive log files,备份后删除archive log files,在恢复时control files似乎并不知道archive log files已经被删除,还在访问完全备份时的最新archive log file,当然是报错,虽然实际上已经成功还原了;我想可能要在RMAN备份完后再进行control files的备份,准备修改备份脚本进行尝试
2、异地恢复成功后,执行alter database open resetlogs;系统中设立的job立刻run起来,应该是db open会自动把过期没有执行的job重新跑一遍,因此在RMAN备份前需要将所有的job都置为broken
3、联机重做日志如何恢复呢?是不是只能恢复到最后归档的状态呢?询问了一个从事DBA工作的同事,答案是难以恢复或者无法恢复的,我想下面进一步进行研究
4、异地恢复成功后,异地DB上的Temp表空间为空,ORA-25153: Temporary Tablespace is Empty。经了解,原来RMAN恢复后需要手动重建TEMP表空间的数据文件:如果数据库做过resetlogs方式的打开数据库,确认表空间管理为local,需要手工创建tempfile

关于OracleDbType.Int32,Integer,Int的问题

今天同事遇到一个非常奇怪的问题,对于一个Oracle Procedure,用同样的入参值,通过Microsoft.ApplicationBlocks.Data.dll调用的时候没有返回记录,而通过Sql Navigator调试是有返回记录的,实际上也是应该有返回值的。于是我猜想可能是入参的数据类型问题,对照了一下,发现Procedure中有一个入参的数据类型是Integer,而我们从.Net中调用时设定的数据类型是OracleDbType.Decimal,于是我试着把OracleDbType.Decimal改成OracleDbType.Int32还是不行,进一步分析一下,这个Integer类型入参所对应的其实是一个Table的一个类型为Int的栏位,于是我把Integer改成Int,.Net中改成OracleDbType.Int32,跑一边终于成功了!然后我再将Int改成Number,.Net中改成OracleDbType.Decimal,跑一下也成功了,因此还是尽量少用Integer,用Int或者Number就够了,Int对应OracleDbType.Int16,OracleDbType.Int32,OracleDbType.Int64,而Number比Int更大,可以对应OracleDbType.Decimal
11月9日

ORA-07217: sltln: environment variable cannot be evaluated.

今天使用rman连接备用数据库,rman target / ,返回以下错误:
Recovery Manager: Release 9.2.0.6.0 - 64bit Production
Copyright (c) 1995, 2002, Oracle Corporation.  All rights reserved.
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-00554: initialization of internal recovery manager package failed
RMAN-04005: error from target database:
ORA-07217: sltln: environment variable cannot be evaluated.
网上查了一下,很多人在启动/关闭数据库时遇到ORA-07217错误,有解答说是因为没有输出ORACLE_SID环境变量,但是我在启动/关闭数据库时一切正常,因此我相信我这里不是这个原因,突然想起我还没设置备用数据库为自动归档日志,因此想象可能是这个原因,于是赶紧设置,但是不管用,依旧报ORA-07217这个异常,还是去看看.profile吧,一看果然,输出ORACLE_SID的命令行被#了:
# ORACLE_SID="HISDB";
# export ORACLE_SID;
奇怪了,绞尽脑汁都不知道什么时候#了这两条命令,除非我脑子坏掉,不然不会做这种傻事的……
改回来吧,不报异常,一切OK了
11月8日

SQL中的INTERSECT关键字

和UNION 指令类似,INTERSECT也是对两个SQL语句所产生的结果做处理的。不同的地方是,UNION 基本上是一个OR(如果这个值存在于第一句或是第二句,它就会被选出),而INTERSECT则比较像 AND(这个值要存在于第一句和第二句才会被选出)。UNION是联集,而INTERSECT是交集。 INTERSECT的语法如下:
[SQL Segment 1]
INTERSECT
[SQL Segment 2]

注意在INTERSECT指令下,不同的记录只会被列出一次经过我的测试,发现INTERSECT的效率似乎不如IN,针对两个表,made_order共23万笔记录,charge_detail共17万笔记录,执行时间如下:SELECT order_id FROM made_order
INTERSECT
SELECT order_id FROM charge_detail
1.05 sec

SELECT a.order_id FROM made_order a
WHERE exists (
    SELECT 1
    FROM charge_detail
    WHERE order_id = a.order_id
    )
9.74 sec

SELECT order_id FROM made_order
WHERE order_id in (
    SELECT order_id
    FROM charge_detail
    )
0.63 sec

SQL中的MINUS关键字

SQL中有一个MINUS关键字,它运用在两个SQL语句上,它先找出第一条SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果中。如果有的话,那这一笔记录就被去除,而不会在最后的结果中出现。如果第二个SQL语句所产生的结果并没有存在于第一个SQL语句所产生的结果内,那这笔资料就被抛弃,其语法如下:
[SQL Segment 1]
MINUS
[SQL Segment 2]
其实简单的一句话就是找出第一条SQL查询的不在第二条SQL语句查询结果中的那些记录,并且要注意最后返回的结果集中,不同的记录只会被列出一次!
下面是我做的实验,很明显能够看出MINUS的效率,made_order共23万笔记录,charge_detail共17万笔记录
SELECT order_id FROM made_order
MINUS
SELECT order_id FROM charge_detail
1.14 sec
 
SELECT a.order_id FROM made_order a
WHERE NOT exists (
    SELECT 1
    FROM charge_detail
    WHERE order_id = a.order_id
    ) 
18.19 sec
 
SELECT order_id FROM made_order
WHERE order_id NOT in (
    SELECT order_id
    FROM charge_detail
    )
20.05 sec
11月3日

在Oracle中实现数据库的复制-续

试验多次发现《在Oracle中实现数据库的复制》讲得不是很清楚,而且有一些错误,后来从网上找到了一个比较全面讲解Oracle Advanced Replication的电子书《Advanced Replication Research》,通篇看完以后终于对Oracle的高级复制有了一个比较系统的了解,现摘要几个要点:
一、Replication 中的几个概念:
1) replication object:复制对象,指需要作复制的对象(object),包括表,索引,存储过程等等。复制对象的更新遵循事务一致性规则(transactionally consistent manner)。
2) replication groups:复制组,是复制对象(replication object)的集合称为group,oracle 以replication group 的形式来管理复制。一个组可以包含多个模式的object,一个模式也可以有多个组中的object,但是每个replication object 都只能属于一个replication group。
3) replication sites:复制站点,包含两种类型,主体站点(master sites)和实体化视图站点(materialized view sites)。一个site 可以担任一个replication group 中的mater site 同时又担任另外一个replication group 中的materialized view site,注意必须是另外一个组,而不能是同一个replication group。
4) scheduled links:一个数据库链接(database link),包含一个由用户定义的计划,来将需要更新的事务推到其它的master sites,当创建scheduled link 的时候,oracle将在本地任务队列中创建一个任务。
5) master definition site:主体定义站点,大部分的高级复制配置都需要在一个站点上作,这个站点就是maserdef site。
二、Replication 环境的几种类型
1) Multimaster Replication
2) Materialized View Replication(也可以称为是Single Master Replication)
3) Multimaster and Materialized View Hybrid Configurations
Multimaster Replication 和Materialized View Replication 的区别在于:
前者必须是全表复制而后者可以是master 表的一部分
前者允许在每一个transaction 之后都进行复制,而后者是属于批处理复制
两者都使用scheduled links 进行数据同步操作。
Materialized View Replication 中的materialized view 可能有以下几种类型:
1) Read-Only Materialized Views:只读的实体化视图
2) Updatable Materialized Views:允许更新,同时允许将更新复制到master site
3) Writeable Materialized Views:允许更新,但是每次refresh 的时候,更新都会丢失
三、Multimaster Replication 中的复制方式
1) Asynchronous replication
在一个master 上发生的变化将在推后的时间内更新到其他的master 上
2) Synchronous replication
在一个master 上发生的变化将立刻更新到其他的master 上
3) Procedural replication
必须给每个site 上的包都生成一个wrapper,所有的数据变化应该通过包中的存储过程完成,当某个master 上的procedure 被调用,wapper 将保证其他site 中的存储过程也被调用(同步或者不同步)。将大量的数据操作放到一个procedure 中,然后对于procedure 的调用将被同步,用处在于在于有大数据量操作的时候可以减少网络负载。
 
最后按照里面所提供的多主体复制站点的配置步骤,终于成功实现了多主体复制站点的高级复制技术
11月2日

在Oracle中实现数据库的复制-续

继续昨天的郁闷,我又开始上网google解决方案,在itpub里面找到一个帖子,说如果两边的Compatible参数设置一致的话,那问题应该是出在创建repadmin用户的时候缺少了几个授权的命令,奇怪了,我是严格按照那边文章上的步骤一步一步地赋权的,怎么可能漏呢?于是我又核对了一下这个帖子里所列出的步骤,发现一个那片文章上没有给出的步骤:
execute dbms_repcat_admin.grant_admin_any_schema(username => 'REPADMIN');
而且作者还强调这里一定要注明参数名username,否则操作会被中断!郁闷终于消除了,原来是我参照的文章遗漏了一个步骤。好了,可以继续试验Oracle数据库高级复制的功能了……
11月1日

在Oracle中实现数据库的复制

这两天参照一篇《在Oracle中实现数据库的复制》来试验Oracle的高级复制功能
数据库1:HISDEV(9.2.0.6.0),windows2003
数据库2:HISTST(9.2.0.6.0),hp-unix
按部就班地逐步进行配置,在创建主复制节点的时候报
ORA-23375 feature is incompatible with database version at string.
根据提示,我再一次校验了HISDEV和HISTST的初始化参数项compatible,原来都是9.2.0.0.0,而后我改成真实的版本号9.2.0.6.0,但是仍然报同样的错误,非常奇怪,上网google了一下,绝大部分人都没有给出实际的解答,其中有人说可能是没有赋予复制管理员帐号以SELECT ANY DICTIONARY的权限,但我赋了后仍然没有解决问题,持续郁闷中……
9月5日

RMAN在Oracle 9i中的配置情况

CONFIGURE RETENTION POLICY TO REDUNDANCY 1; # default
CONFIGURE BACKUP OPTIMIZATION OFF; # default
CONFIGURE DEFAULT DEVICE TYPE TO DISK; # default
CONFIGURE CONTROLFILE AUTOBACKUP OFF; # default
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '%F'; # default
CONFIGURE DEVICE TYPE DISK PARALLELISM 1; # default
CONFIGURE DATAFILE BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE ARCHIVELOG BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE MAXSETSIZE TO UNLIMITED; # default
CONFIGURE SNAPSHOT CONTROLFILE NAME TO ‘C:ORACLE..SNCFTEST.ORA’; #default

1.configure retention policy to redundancy 1:
是用来决定那些备份不再需要了,它一共有三种可选项,分别是
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
CONFIGURE RETENTION POLICY TO REDUNDANCY 5;
CONFIGURE RETENTION POLICY TO NONE;
第一种recover window是保持所有足够的备份,可以将数据库系统恢复到最近七天内的任意时刻。任何超过最近七天的数据库备份将被标记为obsolete。

第二种redundancy 是为了保持可以恢复的最新的5份数据库备份,任何超过最新5份的备份都将被标记为redundancy。它的默认值是1份。

第三种不需要保持策略,clear将恢复回默认的保持策略。

一般最安全的方法是采用第二种保持策略。

2.CONFIGURE BACKUP OPTIMIZATION OFF
默认值为关闭,如果打开,rman将对备份的数据文件及归档等文件进行一种优化的算法。
3.Configure default device type to disk:
是指定所有I/O操作的设备类型是硬盘或者磁带,默认值是硬盘
磁带的设置是CONFIGURE DEFAULT DEVICE TYPE TO SBT;

4.CONFIGURE CONTROLFILE AUTOBACKUP OFF
强制数据库在备份文件或者执行改变数据库结构的命令之后将控制文件自动备份,默认值为关闭。这样可以避免控制文件和catalog丢失后,控制文件仍然可以恢复。

5.CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '%F'
是配置控制文件的备份路径和备份格式

6.CONFIGURE DEVICE TYPE DISK PARALLELISM 1;
是配置数据库设备类型的并行度。

7.CONFIGURE DATAFILE BACKUP COPIES FOR DEVICE TYPE DISK TO 1;
是配置数据库的每次备份的copy数量,oracle的每一次备份都可以有多份完全相同的拷贝。

8.CONFIGURE ARCHIVELOG BACKUP COPIES FOR DEVICE TYPE DISK TO 1
是设置数据库的归档日志的存放设备类型

9.CONFIGURE SNAPSHOT CONTROLFILE NAME TO 'C:ORACLE… SNCFTEST.ORA'
是配置控制文件的快照文件的存放路径和文件名,这个快照文件是在备份期间产生的,用于控制文件的读一致性。

10.CONFIGURE CHANNEL DEVICE TYPE DISK FORMAT 'C:...%d_DB_%u_%s_%p';
是配置备份文件的备份路径和备份格式

CONFIGURE CHANNEL DISK CLEAR; 用于清除上面的通道配置

CONFIGURE EXCLUDE FOR TABLESPACE <tablespace> [CLEAR]; 此命令用于将指定的表空间不备份到备份集中, 此命令对只读表空间是非常有用的。

8月28日

Unix shell编成中如何让FTP自动上传/下载

计划Unix上Oracle编写脚本导出数据,并通过ftp上传至另外一台windows2003服务器上,但是面临一个问题就是如何让ftp完成连接、登陆、上传和退出这一系列动作呢?本人是shell编程新手,只能上网狂陶答案了,功夫不负有心人,终于找到了答案:
[Q]FTP怎么在脚本中自动上传/下载
[A]可以把FTP写到shell脚本中,如
ftp -n -i 主机IP <<EOF
user username pass
cd 目标目录
put file
get file
#查询文件
ls
#退出
bye
EOF
8月21日

Imp正常,但Exp却无法完成

前日晚上准备对刚刚启用的Unix环境Oracle数据库做一次Exp逻辑备份,报如下错误:
EXP-00056: ORACLE error 942 encountered
ORA-00942: table or view does not exist
EXP-00000: Export terminated unsuccessfully
感觉很奇怪,因为数据库中的数据就是通过Imp转移来的,怎么这里的Exp不能用了呢?上网搜了一下,发现这个问题还并不鲜见,找到一篇文章解释为Oracle本身的一个bug,发生在从920升级到9206以后,因此建议在升级后用Exp命令来检验升级是否真正成功,但事已至此,我又检查了测试环境和开发环境,发现都有这样的我问题,于是根据作者提供的方法,执行了/rdbms/admin/catpatch.sql脚本,然后手动编译了sys schema下的所有package,再使用Exp命令导出数据就可以了,具体命令如下:
SQL>shutdown immediate;
SQL>startup migrate;
SQL>@?/rdbms/admin/catpatch.sql
SQL>shutdown immediate;
SQL>startup;
8月18日

ORA-20: 超出最大进程数 (%s)

ORA-20: 超出最大进程数 (%s)通常是由于设置的processes和sessions过低造成的,修改这两个参数,然后重启db就可以了。
如果数据库正在on line,可以先编辑pfile,将processes和sessions维护进去,待数据库重启后,自然会将其应用到spfile中去。但是我今天犯了一个大错,我直接在console中修改这两个参数,然后保存的时候提示我重启,我选择了第一个选项,即等待所有连线关闭后再重启!犹豫了半天,还是傻傻地确定了,接着弹出了正在关闭数据库的窗口,我后悔了,赶忙点取消按钮,但是系统提示不能关闭,我又去unix下用sqlplus试图关闭重启,提示无法完成,灾难发生了,所有新的连线被拒绝,现场乱成一团,我干吗求救总部DBA,他要求我先将console任务结束,然后去unix下修改pfile,然后动手帮我重启了db,使用的命令如下:
a) run "ipcs -b" to find the remaining IPC facilities, owned by the same user, and remove them.
b) To remove a shared memory segment or semaphores, the commands are
ipcrm -m <ID> - for shared memory
ipcrm -s <ID> - for semaphores
8月14日

declare...begin...end;中必须包含DML语句

今天同事发来一段pl/sql,看起来没有问题,但一运行就报错:PLS-00428: an INTO clause is expected in this SELECT statement。完整的语句如下:
DECLARE 
 p_begin_date NVARCHAR2(10);
 p_end_date NVARCHAR2(10);
 p_order_code NVARCHAR2(20); 
BEGIN
 p_begin_date := N'2006-07-26';
 p_end_date :=N'2006-07-26';
 p_order_code :=N'1470701';
SELECT r.room_name,a.*
FROM STOREROOM_TAKEOUT_ERP a,STOREROOM_INFO r
WHERE a.stock_code=p_order_code
    AND (to_char(get_date,'yyyy-mm-dd') BETWEEN  p_begin_date AND p_end_date)
    AND a.hospital_id=r.hospital_id AND a.hospital_id=1
    AND a.room_sn=r.room_sn;
END;
仔细分析了一下语法,确实没有错误啊,那为什么会报这种错呢?边猜边想,select放在declare...begin...end;根本没有意义,是不是因为这个原因?于是我删去了select语句,加了一句select * from dual;执行报同样的错误,确定了,declare...begin...end;只有select语句的话不能也没必要采用这种语法结构,并且即时包含了select语句,也不能使用declare中所定义的变量.
7月20日

HP Unix修改系统时间

HP Unix如何修改时间,有两种格式:
date mmddyyyy和date mmddhhmm
晚上说Linux和Unix的时间每个11分钟会跟CMOS同步,要彻底修改时间,就要将修改后的时间强行写入CMOS,但是我经过试验,经过11分钟后,修改后的时间依然没有自动改回去……
7月19日

HPUX里查看进程杀进程

ps -ef|grep oracle查看oracle帐号所开启的进程,然后用kill -9 pid来杀掉编号为pid的进程

清空/tmp目录

昨天打算在一台HP-Unix机器上安装一个Oracle,但刚启动安装就报错,说tmp目录已满,打个bdf一看,乖乖,tmp目录使用率已经100%,要赶紧清空了,但是翻来找去居然没有找到清空一个目录的命令,因为里面有很多的多层子目录,网上倒是有说,只要重启Unix,tmp就会自动清空,但是今天上午重启了一下后发现依然是100%,害得同事忙了半天,无奈之下,计划一个一个手动删,但是目录实在太多了,于是随手打起命令来,最后碰到一个:rm -R *,居然成功清空了一个文件夹,除了以.打头的目录都删除了,这下一定要记好了,呵呵
7月11日

刚刚完成了一个批处理

作为一个Oracle DBA新手,总有一种置身汪洋,不知如何横渡的感觉。我最常做的事情就是导入导出数据,还没有深入到真正的数据库管理工作中去。前一段时间从网上查查找找,完成了一个自动导出数据库的批处理;但是导入就麻烦了,特别是要将线上数据库在开发机器上重新创建一份的时候,由于相关的User较多,赋权,创建对象,调整基础数据等工作,往往最快都要耗时15分钟时间才能在开发机器上重新复制一份真实的数据库环境,于是又花了一天时间,整理完成了一份批处理程序,完成三大步骤地工作:

删除旧的User和Schema,并进行重建

导入数据库对象及数据内容,由于导出的时候已经导出赋权,因此省去赋权动作

调整基础数据内容,以适应开发使用,比如修改权限表的密码等

在一些相关帐号下创建同义词等设置

在这个过程中,有几点知识需要记录的:

sqlplus "user/pwd@dbservice" @ script.sql

即以指定帐号登入sqlplus,并执行script.sql中的pl/sql

另外script.sql中可以写declare..begin..end结构的语句,但是最后要以/结束

详细的程序结构就不多说了,没时间写,呵呵