NinGoo.net --- Oracle DBA|MySQL DBA|数据库管理,架构,监控与性能优化

如何获得Oracle用户创建和授权语句

有时候,我们需要在不同的库中复制用户定义,比如需要在一个测试库中创建和产品库中同名的用户,并且拥有同样的权限。或者在同一个库中创建一个不同名的用户,但是和另外一个用户拥有同样的权限等。换句话说,就是需要获得某个用户的创建和授权语句。

可以通过SQL从一些数据字典中查询到授权信息,生成授权语句:

undefine user_name
set pagesize 1000
select 'grant '||tt.granted_role||' to '||tt.grantee||';' as SQL_text
from dba_role_privs tt where tt.grantee=(upper('&&user_name'))
union all
select 'grant '||tt.privilege||' to '||tt.grantee||';'
from dba_sys_privs tt where tt.grantee=(upper('&&user_name'))
union all
select 'grant '||tt.privilege||' on '||owner||'.'||table_name||' to '||tt.grantee||';'
from dba_tab_privs tt where tt.grantee=(upper('&&user_name'))
union all
select 'alter user '||tt.user_name||' quota '||maxblocks*blocksize||' on '||ts_name||';'
from KU$_TSQUOTA_VIEW tt where tt.user_name=(upper('&&user_name'));

[继续阅读全文]

Redhat Linux上Oracle如何启用AIO

从Oracle9iR2开始支持Linux上的异步IO,但是Oracle9iR2和Oracle10gR1中的AIO模块默认是disable的,如果要启用必须relink一下

cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk async_on
make -f ins_rdbms.mk ioracle

当然,如果要关闭AIO支持,只需要使用async_off选项进行relink即可。在Oracle10gR2中AIO默认已经是开启的了。可以通过ldd或者nm来检查oracle是否已经启用了AIO支持,有输出代表已经启用

/usr/bin/ldd $ORACLE_HOME/bin/oracle | grep libaio
        libaio.so.1 => /usr/lib64/libaio.so.1 (0x0000003ca9800000)

/usr/bin/nm $ORACLE_HOME/bin/oracle | grep io_getevent
                 w io_getevents@@LIBAIO_0.4

当然,Linux也必须已经安装了AIO相关的package

rpm -qa | grep aio
libaio-0.3.105-2
libaio-devel-0.3.105-2

可以通过查看slabinfo统计信息查看操作系统中AIO是否运行,slab是Linux的内存分配器,AIO相关的内存结构已经分配的话(第二列和第三列非0)说明AIO已经启用

cat /proc/slabinfo | grep kio
kioctx 102 170 384 10 1 :tunables 54   27 8 : slabdata 17 17 0
kiocb 488 495 256 15 1 :tunables 120 60 8 : slabdata 33 33 120

最后,还需要在Oracle中设置相关的初始化参数来使用AIO

disk_asynch_io = true
filesystemio_options = asynch #文件系统才需要

实时获得最耗CPU资源的SQL语句

在Oracle性能诊断和日常监控中,最耗CPU的语句通常也是我们最需要关心的语句。所以在Oracle10g的awr中,将cpu time和elapsed time最高的语句加入到了报表,并且放到了SQL语句部分的前两位。那么在平时的监控中,也可以通过shell脚本实时捕获系统中CPU耗用最多的进程中正在执行的SQL,以更加有效和及时的诊断和发现问题。

首先写一个根据spid来或者其SQL的脚本get_by_spid.sql

#!/bin/ksh
# creator:NinGoo
# function: get sql statement by spid
# parameter: spid
# useage: get_by_spid.sh spid

sqlplus -S /nolog <<EOF     
 connect / as sysdba;
 col SERIAL# format 999999
 col sid format 99999
 col username format a10
 col machine format a12
 col program format a32
 col sql_text format a81
 set lines 1000
 set pages 1000
 set verify off
 col sql_hash_value new_value hash_value  head hash_value
select sid,serial#,username,program,sql_hash_value,
         to_char(logon_time,'yyyy/mm/dd hh24:mi:ss') as login_time
  from v\$session
 where paddr in ( select addr from v\$process where spid=$1);

select sql_text
  from v\$sqltext_with_newlines
  where hash_value = &hash_value
 order by piece;
exit;
EOF

然后再在另外一个shell脚本topsql.sh中获得系统中CPU耗用最多的oracle server process的spid,循环调用第一个脚本获得SQL

#!/bin/ksh
# creator:NinGoo
# function: get top cpu sql
# parameter: N
# useage: topsql.sh N

if [ $# -eq 0 ]; then
   echo "Usage: `basename $0` N"
   exit 1
fi

topcpu=`ps auxw|grep LOCAL|sort -rn +2 |head -$1|awk '{print $2}'`
i=0

for spid in $topcpu
do
i=`expr $i + 1`
echo "\033[32;1m===============top $i cpu sql=============\033[0m"
. /home/oracle/worksh/get_by_spid.sh $spid
done

那么调用就很简单了,假如我们要看系统top 3的sql语句,只需要执行topsql.sh 3即可。当然,如果我们自己通过top/topas等工具已经获得spid了,那么只要执行get_by_spid.sh spid就能获得该进程正在执行的sql语句了。

夏令时与Oracle PatchSet 10.2.0.4

Oracle10.2.0.4发布有一段时间了,在Metailink上搜索Patch Number:6810189,即可获得下载,目前已经发布了Linux X86/Linux X86_64/windows(32)三个版本,据说Solaris版本也已经发布,但是到今天Metalink上还是没有看到。

10.2.0.4中包含了DSTv4(Daylight Saving Time,也就是所谓的夏令时)的更新,所以如果你原有的系统中有使用Time Zone相关数据类型的(主要是TIMESTAMP WITH LOCAL TIME ZONE (TSLTZ)和TIMESTAMP WITH TIME ZONE (TSTZ)两种),升级之前需要检查系统的DST版本,然后做出相应的处理。

执行以下SQL,看数据库中是否使用了受影响的数据类型:

select c.owner || '.' || c.table_name || '(' || c.column_name || ') -' || c.data_type || ' ' col
  from dba_tab_cols c, dba_objects o
 where c.data_type like '%TIME ZONE'
    and c.owner=o.owner
   and c.table_name = o.object_name
   and o.object_type = 'TABLE'
order by col
/

如果没有,恭喜你,不用管啥DST了。如果有记录,那么根据现有的DST和Oracle版本的不同,需要做不同的处理。具体请参考Metalink(Note:553812.1)

如果是10g,可以通过如下SQL查询目前的DST版本:

select * from v$timezone_file;

如果是9i,是没有视图可以直接查的,Metalink上提供了一个utltzver.sql的脚本可以查询。

关于夏令时和Oracle,还可以参考Fenng的文章


常用标签:

最新评论 | Recent comments