充当了一回DBA
杭州出差,作为唯一在项目现场的集成人员,遇到的问题虽说不少,但基本都是小问题,直到昨晚遇见ORACLE 错误942和ORA-04020前。
首先介绍一下环境,Windows 2003 64位的标准版上安装的Oracle 9.2.0.1,安装软件后升级补丁到9.2.0.7然后再建库。安装过程一切顺利,不过就在开发人员用exp备份数据时出错。提示如下:
连接到: Oracle9i Enterprise Edition Release 9.2.0.7.0 – Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.7.0 – Production即将导出指定的用户…
. 正在导出 pre-schema 过程对象和操作
. 正在导出用户 BJIC 的外部函数库名称
. 导出 PUBLIC 类型同义词
. 导出私有类型同义词
. 正在导出用户 BJIC 的对象类型定义EXP-00008: 遇到 ORACLE 错误 942
ORA-00942: 表或视图不存在
EXP-00024: 未安装导出视图,请通知您的 DBA
EXP-00000: 导出终止失败
通过ORA-00942搜索,得知出现该错误的原因是:由于exp的版本与数据库的版本不相同,
虽然9.2.0.7的安装包已经安装成功,但是数据字典表中的相关信息并未更新,
执行如下语句验证了这一说法
SQL> select comp_id,version from dba_registry;
COMP_ID VERSION
CATALOG 9.2.0.1.0
CATPROC 9.2.0.1.0
OWM 9.2.0.1.0
JAVAVM 9.2.0.1.0
XML 9.2.0.2.0
CATJAVA 9.2.0.1.0
ORDIM 9.2.0.1.0
SDO 9.2.0.1.0
CONTEXT 9.2.0.1.0
XDB 9.2.0.1.0
WK 9.2.0.1.0
ODM 9.2.0.1.0
APS 9.2.0.1.0
XOQ 9.2.0.1.0
AMD 9.2.0.1.0
然后按照如下步骤进行操作:
- set ORACLE_SID=数据库SID
- SQL> sqlplus "/as sysdba"
已连接。
SQL> shutdow immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。 - SQL> startup migrate
ORACLE 例程已经启动。
……
数据库装载完毕。
数据库已经打开。 - SQL> spool d:\catpatch.log \\记录一下等下的升级日志
SQL> @d:\oracle\ora92\rdbms\admin\catpatch.sql \\执行catpatch脚本,在catpatch中会调用catexp来修改exp
SQL> spool off - SQL> shutdow immediate
- SQL> startup
照理按照上述步骤,应该就没问题,最后会看到各组件版本都为9.2.0.7了。可事实是
执行完成重启后,用户登录极慢,
过了很久登录成功后显示
SQL> connect username/password@sid
ERROR:
ORA-04020: 尝试锁定对象 SYS.DBMS_STANDARD 时检测到死锁ERROR:
ORA-04020: 尝试锁定对象 SYS.DBMS_STANDARD 时检测到死锁访问程序包 DBMS_APPLICATION_INFO 时出错
已连接。
SQL>
一开始没在意,重启服务器,可依旧无效。这下有点慌,这可是马上要上线的准生产环境了。于是联系上海同事,领导也打来电话,帮忙找了一个在杭州的同事赶来现场。
在等待同事来现场的路上,首先把数据文件做了一个冷备,又google了一把,得知:
在没有停业务的情况下,直接打数据库的补丁catpatch.sql,结果打到中间的时候出错ORA-04020,导致业务登陆用户无法登陆进数据库。其实,这个补丁升级说明中,明确要停止DML操作,防止数据字典deadlock.
其实在正常启动的情况下,执行catpatch.sql会直接报错,提示你需要在migarite模式下执行。回想我之前的操作,在执行catpatch.sql时中间曾长时间“类卡死”状态,导致我第一次中断了执行,查看升级不成功又继续执行了一次,估计错误就发生在这里。
之后杭州同事赶到现场,又让上海的资深DBA远程操作,解决ORA-04020倒也很简单:
ALTER SYSTEM SET _system_trig_enabled=FALSE SCOPE=MEMORY;
alter package standard compile;
alter package DBMS_standard compile;
执行$ORACLE_HOME/rdbms/admin/utlrp.sql包,该包会重新编译由于升级导致状态不一致的数据字典对象。
然后登录就正常了,再次执行上面的catpatch步骤,问题解决。虽然现在说起来很简单,但其实搞了4小时才全部完成。
总结昨天的经验:最重要的是在做操作前要做好备份,冷备是最好的选择,否则直接在生产环境上操作,一旦失败太被动了。然后是执行sql脚本时卡住不动很正常,看看资源管理器里进程好好的就可以了。最后一点是oracle升级前需要详细查阅升级步骤,如果不是当时少做一步,也没后面的这些麻烦了。


很完整的一次记录,学习了。
再次说明备份很重要的。