Oracle数据库的global_name,在Database Link与GLOBAL_NAMES参数一文中提到了,设置global_names初始化参数为true后,本地的数据库链接名称必须与远程数据库的global_name相同,才能正常使用数据库链接。那么怎么查询数据库的global_name呢?

SQL> col global_name for a30
SQL> select * from global_name;

GLOBAL_NAME
------------------------------
DMDB

那么怎么样修改global_name?

ALTER DATABASE
RENAME GLOBAL_NAME TO NEW_NAME;

注意不要直接用update global_name set global_name=''将global_name设置为空,否则数据库不能启动,会报ORA-00600[18061] 或 ORA-00600[18062]这样的错误。 只有用备份进行恢复后才能打开。(参见metalink note 743676.1)。

那么global_name到底是个什么对象呢?

SQL> select owner,object_name,object_type from dba_objects where object_name='GLOBAL_NAME';

OWNER OBJECT_NAME OBJECT_TYPE
---------- -------------------- --------------------
SYS GLOBAL_NAME VIEW
PUBLIC GLOBAL_NAME SYNONYM

SQL> select text from dba_views where view_name='GLOBAL_NAME';

TEXT
----------------------------------------------------------------
select value$ from sys.props$ where name = 'GLOBAL_DB_NAME'

Read the rest of this entry

如果一个表的外键引用的是另一个用户的表,需要特别的权限吗?答案就是refrences权限。虽然一个schema(用户)下表的外键引用的是其他schema(用户)的表,是一种不太好的设计。但现实中仍然会有这种情况。下面来看看reference的作用:

测试环境:
Oracle 10.2.0.1
Redhat Linux AS4
数据库里用于测试的两个用户test1和test2,只有connect角色权限和表空间使用权限。

SQL> connect / as sysdba
Connected.
SQL> create table test1.t1 as select * from dba_objects where rownum< =1000; Table created. SQL> create table test2.t2 as select * from dba_objects where rownum< =1000; Table created. SQL> alter table test1.t1 add constraint pk_t1 primary key(object_id);

Table altered.

现在,我们用用户test2连接到数据库,在表test2.t2的object_id字段上增加一个外键,外键引用test1.t1表的object_id字段:

SQL> connect test2/test
Connected.
SQL> alter table t2 add constraint fk_t2 foreign key (object_id) references test1.t1(object_id);
alter table t2 add constraint fk_t2 foreign key (object_id) references test1.t1(object_id)
*
ERROR at line 1:
ORA-00942: table or view does not exist

我们将test1.t1表的查询权限赋给test2:

SQL> grant select on test1.t1 to test2;

Grant succeeded.

再次增加外键:

SQL> alter table t2 add constraint fk_t2 foreign key (object_id) references test1.t1(object_id);
alter table t2 add constraint fk_t2 foreign key (object_id) references test1.t1(object_id)
*
ERROR at line 1:
ORA-01031: insufficient privileges

可以看到报权限不足。我们再看看如果将DBA权限给test2会怎么样:

Read the rest of this entry

今天是2008年10月22日,农历戊子年九月二十四。

今天是我的法律意义上的生日。虽然很早以前在办户籍时把我的出生日期给搞错了,提前了一个月。但到如今只有将错就错了。

今天是我儿子农历两岁生日,看着儿子一天天长大,那种快乐实不足以用言语来表达。祝福他永远快乐地成长下去。

三年前的今天,我正在当新郎官。

今天是个有意义的日子。

环境:HP-UX 11.31
Oracle 9.2.0.8

数据库异常崩溃,询问维护人员之前有大量数据操作。查看alert日志:

Thu Oct 9 02:20:18 2008
Errors in file /oracle/OraHome1/rdbms/log/acct_ora_11361.trc:
ORA-00600: internal error code, arguments: [ktprhtnew6], [], [], [], [], [], [], []
Thu Oct 9 02:20:19 2008
Fatal internal error happened while SMON was doing active transaction recovery.
Thu Oct 9 02:20:19 2008
Errors in file /oracle/OraHome1/rdbms/log/acct_ora_11361.trc:
ORA-00600: internal error code, arguments: [ktprhtnew6], [], [], [], [], [], [], []
SMON: terminating instance due to error 600
Instance terminated by SMON, pid = 11361

检查trace文件,没有发现有用的信息。

重启数据库,数据库能打开,但不到一分钟实例就crash。在alert日志中的错误信息均如上所示。
在网上及在metalink中以ktprhtnew6为关键字搜索,没有找到相似的BUG和案例。同时当时手边是用的163拨号上网,速度非常慢,只有通过分析来解决问题。

仔细分析alert日志可以发现是在做事务恢复时SMON出错,导致实际中止:

Fatal internal error happened while SMON was doing active transaction recovery.

我们知道ORA-600错误后面参数,如果像ktprhtnew6这样的均表示出错的函数。这里可以看出是在做并行恢复:

[K]enerl [T]ransaction [P]arallel [R]ecovery

设置fast_start_parallel_rollback参数为false,关闭数据库的并行恢复功能,重启数据库,数据库正常,故障消失。
看起来这应该又是一个BUG。

Oracle的监听(Listener)在缺省情况下,会在文件中记录日志,记录数据库实例注册操作、客户端的连接等。缺省(没有设置log_file参数时)的文件是$ORACLE_HOME/network/log/listener.log。对于一些使用短连接的,频繁的连接数据库的应用,listener.log增长很快。有的可以在比较短的时间内(十几天)就可以超过2GB。对于一些平台的某些版本的Oracle,在监听日志增大到2GB以后会导致监听不能正常工作(我没遇到过,不过感兴趣的朋友可以在网上搜索一下,有这样的案例)。

对于这种listener.log增长非常迅速的系统,可以关闭监听日志,不让监听写日志到文件。也可以写个job定期清理。本文主要描述怎么样关闭监听日志:

可以在监听命令行接口中使用命令:
D:\>lsnrctl

LSNRCTL for 32-bit Windows: Version 9.2.0.1.0 - Production on 15-10月-2008 20:52:11

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

欢迎来到LSNRCTL,请键入"help"以获得信息。

LSNRCTL> set log_status off
正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dreamf)(PORT=1521)))
LISTENER 参数 \log_status\ 被设为 OFF
命令执行成功
LSNRCTL> save_config
正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dreamf)(PORT=1521)))
未保存对LISTENER所作的更改
命令执行成功
LSNRCTL>

我们可以在listener.ora文件中可以看到增加了下面的内容:

#----ADDED BY TNSLSNR 15-10月-2008 10:05:43---
LOGGING_LISTENER = OFF
#---------------------------------------------

所以我们也可以在listener.ora文件增加上面的内容来关闭监听日志。但是只有在监听重启后才会生效,而通过lsnrctl 这个命令接口设置,可以立即生效,Windows平台上的文件会立即关闭。因此可以利用这个特性,用来删除WINDOWS平台上的监听日志文件,因为不这样,在监听运行时监听日志是不能删除的。