ODU命令详解 PartI
Posted by 老熊 on 2月 12th, 2009本文将介绍ODU支持的命令,以v2.3.0为基础详细描述ODU的命令。
odu的命令以回车为结束,而不是像SQLPLUS那样的使用“;”号
1. help命令
help命令,显示ODU支持的命令列表,每个命令后面有简短描述:
ODU> help
help ---- get command list
exit ---- exit from odu
spool ---- spool information to file
host ---- enter os terminal
load config ---- load config information from file
open ---- load database filename list from file
osdump ---- dump file format hex
dump ---- dump oracle datafile block
rowid ---- decode rowid components
unload ---- unload data
scan ---- scan extent or segment
list ---- list schema object,partition,datafile
charset ---- get or list supported charset name
在执行一个命令时,如果输入的命令格式不对,将会提示那个命令的命令格式。
2. load config命令
load config命令用于载入ODU的配置文件。命令格式如下:
load config [filename]
缺省的文件名是config.txt
ODU在启动时,会自动载入名为config.txt的配置文件。我将撰文专门介绍ODU的配置文件。
ODU启动后,也可以重新载入配置文件,载入新配置后,会立即生效。
下面是一个示例:
ODU> load config
byte_order little
block_size 8192
db_timezone -7
client_timezone 8
data_path data
lob_path lob
charset_name ZHS16GBK
ncharset_name AL16UTF16
output_format text
lob_storage infile
clob_byte_order little
trace_level 4
delimiter |load control file ‘config.txt’ successful
ODU在Linux和Unix平台下的使用
Posted by 老熊 on 2月 9th, 2009在ODU网页下载到的ODU for Linux (Unix)版本,一般是以“odu_版本号_操作系统_平台.tar.gz”为文件名的文件。上传到你的机器后,使用gunzip和tar解压后,进行少许的配置即可使用。下面举例说明如何在Linux上的使用。
操作系统:Redhat Linux AS 5.0
将odu_210_linux_x86.tar.gz上传到oracle用户的home目录,这里为/export/home/oracle,输入命令:tar xzvf odu_210_linux_x86.tar.gz,即可解开压缩包。解开生成的所有文件和目录在/export/home/oracle/odu目录下。
如果这时候输入命令:./odu,则可能会报下面的错误:
./odu: error while loading shared libraries: libiconv.so.2: cannot open shared object file: No such file or directory
这是由于需要的库文件没有在搜索路径中。执行下面的命令:export LD_LIBRARY_PATH=/export/home/oracle/odu/lib:$LD_LIBRARY_PATH,再运行命令:./odu则会正常运行。
在Solaris平台下,这个环境变量也是LD_LIBRARY_PATH,但在AIX下,这个环境变量则是LIBPATH。
odu压缩包里面所包含的库文件或其不同的版本可能已经存在于系统中。为避免不同版本库文件引起问题,可在设置环境变量时将odu所在的lib目录放到环境变量中的前面部分。
为避免反复设置LD_LIBRARY_PATH和LIBPATH环境变量,可将此环境变量的设置,加入到用户的profile文件中。
UPDATE:
从3.0.7版本开始,各版本的不再需要设置环境变量,因为程序采用静态链接。
--EOF
ODU快速上手
Posted by 老熊 on 2月 8th, 2009本文将以ODU 2.1.0 for Windows版,介绍如何使用ODU。本文只是一个快速上手指南,以后将详细介绍ODU的使用。
在本网站下载到ODU的Windows版本,是一个ZIP压缩文件,解压缩到一个目录,比如解压到d:\,将会看到d:\odu目录下有如下的文件和目录:
D:\odu>dir
驱动器 D 中的卷没有标签。
卷的序列号是 045E-00DED:\odu 的目录
2009-02-08 22:12 <DIR> .
2009-02-08 22:12 <DIR> ..
2009-02-08 01:16 218 config.txt
2009-02-08 01:16 99 control.txt
2009-02-08 22:12 <DIR> data
2004-10-14 00:08 978,432 libiconv2.dll
2009-02-08 19:00 135,168 odu.exe
4 个文件 1,113,917 字节
3 个目录 1,738,174,464 可用字节D:\odu>
如果没有data目录,请手工新建一个。
config.txt文件是ODU的配置文件,默认的配置数据如下:
byte_order little
block_size 8192
data_path data
lob_path lob
charset_name ZHS16GBK
ncharset_name AL16UTF16
output_format text
lob_storage file
clob_byte_order little
trace_level 1
file_header_offset 0
delimiter |
默认的配置基本能满足大部分的需求。
control.txt文件是ODU的数据文件信息文件。你可以理解为类似于Oracle数据库的控制文件,存放了ODU导出数据时需要的Oracle数据文件信息。
control.txt文件中的数据格式为:
表空间号 文件号 相对文件号 文件名 块大小 是否大文件表空间
每列之间用空白分隔,可以只需要前四列,即块大小和是否大文件表空间可省略,块大小省略时,数据文件的默认块大小为config.txt中block_size的大小。下面是一个示例的数据:
#ts #fno #rfno filename block_size bigfile
0 1 1 D:\ORACLE\ORADATA\XJ\SYSTEM01.DBF 4096
1 2 2 D:\ORACLE\ORADATA\XJ\UNDOTBS01.DBF 4096
3 3 3 D:\ORACLE\ORADATA\XJ\DRSYS01.DBF 4096
4 4 4 D:\ORACLE\ORADATA\XJ\EXAMPLE01.DBF 4096
5 5 5 D:\ORACLE\ORADATA\XJ\INDX01.DBF 4096
6 6 6 D:\ORACLE\ORADATA\XJ\ODM01.DBF 4096
7 7 7 D:\ORACLE\ORADATA\XJ\TOOLS03.DBF 4096
7 8 8 D:\ORACLE\ORADATA\XJ\TOOLS02.DBF 4096
9 9 9 D:\ORACLE\ORADATA\XJ\XDB01.DBF 4096
11 10 10 D:\ORACLE\ORADATA\XJ\TEST01.DBF 2048
14 11 11 D:\ORACLE\ORADATA\XJ\K16.DBF 16384
如果数据文件头是完好的,则ODU会自动从文件头里面获取表空间号,文件号,相对文件号,文件块大小等。表空间号,文件号和相对文件号可以写为0。
注意:ODU将检查control.txt文件中的第一个数据文件是否为SYSTEM表空间文件,所以要将SYSTEM表空间的第1个文件放在control.txt文件中的第一行。否则将不能自动获得数据字典数据。
Read the rest of this entry »
发布ODU v2.0.1版
Posted by 老熊 on 2月 8th, 2009ODU是一个类似Oracle DUL的软件。目前发布的是V2.0.1版。
访问本网站的ODU页面,可以得到更详细,最新的信息,也可以在那里下载到最新版本的ODU。
有任何问题可与我联系。详细的联系信息,参见本网站的关于页面。
记一个SQL优化案例
Posted by 老熊 on 2月 6th, 2009某省电信在做批扣(批销)时,出现严重的性能问题,发现下面这一条SQL性能非常低下:
SELECT A.ACCT_BALANCE_ID,
A.BALANCE_TYPE_ID,
A.ACCT_ID,
NVL(A.SERV_ID, -1) SERV_ID,
NVL(A.ITEM_GROUP_ID, -1) ITEM_GROUP_ID,
A.OBJECT_TYPE_ID,
F.PRIORITY,
A.BALANCE,
NVL(A.CYCLE_UPPER, -1) CYCLE_UPPER,
NVL(A.CYCLE_LOWER, -1) CYCLE_LOWER,
NVL(A.CYCLE_UPPER_TYPE, ’ ’) CYCLE_UPPER_TYPE,
NVL(A.CYCLE_LOWER_TYPE, ’ ’) CYCLE_LOWER_TYPE,
B.ADJUST_FLAG ADJUST_FLAG,
B.ALLOW_TRANS ALLOW_TRANS,
B.CORPUS_FLAG,
NVL(TO_CHAR(A.EFF_DATE, ’YYYYMMDDHH24MISS’), ’ ’) EFF_DATE,
NVL(TO_CHAR(A.EXP_DATE, ’YYYYMMDDHH24MISS’), ’ ’) EXP_DATE,
A.STATE,
TO_CHAR(A.STATE_DATE, ’YYYYMMDDHH24MISS’) STATE_DATE,
B.BALANCE_TYPE_NAME,
NVL(C.ACCT_NAME, ’ ’) ACCT_NAME,
NVL(D.ACC_NBR, ’ ’) SERV_NAME,
NVL(E.ITEM_GROUP_NAME, ’ ’) ITEM_GROUP_NAME
FROM (SELECT ACCT_BALANCE_ID,
BALANCE_TYPE_ID,
ACCT_ID,
NVL(SERV_ID, -1) SERV_ID,
NVL(ITEM_GROUP_ID, -1) ITEM_GROUP_ID,
OBJECT_TYPE_ID,
BALANCE,
NVL(CYCLE_UPPER, -1) CYCLE_UPPER,
NVL(CYCLE_LOWER, -1) CYCLE_LOWER,
NVL(CYCLE_UPPER_TYPE, ’ ’) CYCLE_UPPER_TYPE,
NVL(CYCLE_LOWER_TYPE, ’ ’) CYCLE_LOWER_TYPE,
EFF_DATE,
EXP_DATE,
STATE,
STATE_DATE,
0 SHARE_RULE_PRIORITY
FROM ACCT_BALANCE
WHERE ACCT_ID = :LACCTID
AND BALANCE > 0
AND BALANCE_TYPE_ID != 1
AND STATE = ’10A’
UNION
SELECT A1.ACCT_BALANCE_ID,
A1.BALANCE_TYPE_ID,
B1.ACCT_ID,
NVL(B1.SERV_ID, -1) SERV_ID,
NVL(B1.ITEM_GROUP_ID, -1) ITEM_GROUP_ID,
A1.OBJECT_TYPE_ID,
A1.BALANCE,
NVL(B1.UPPER_AMOUNT, -1) CYCLE_UPPER,
NVL(B1.LOWER_AMOUNT, -1) CYCLE_LOWER,
NVL(A1.CYCLE_UPPER_TYPE, ’ ’) CYCLE_UPPER_TYPE,
NVL(A1.CYCLE_LOWER_TYPE, ’ ’) CYCLE_LOWER_TYPE,
A1.EFF_DATE,
A1.EXP_DATE,
A1.STATE,
A1.STATE_DATE,
B1.PRIORITY SHARE_RULE_PRIORITY
FROM ACCT_BALANCE A1, BALANCE_SHARE_RULE B1
WHERE A1.ACCT_BALANCE_ID = B1.ACCT_BALANCE_ID
AND B1.ACCT_ID = :LACCTID
AND A1.BALANCE > 0
AND A1.BALANCE_TYPE_ID != 1
AND A1.STATE = ’10A’
AND NVL(B1.EFF_DATE, SYSDATE) < = SYSDATE
AND NVL(B1.EXP_DATE, SYSDATE) >= SYSDATE) A,
BALANCE_TYPE B,
ACCT C,
SERV D,
A_BALANCE_ITEM_GROUP E,
A_BALANCE_OBJECT_TYPE F
WHERE A.BALANCE_TYPE_ID = B.BALANCE_TYPE_ID
AND A.OBJECT_TYPE_ID = F.OBJECT_TYPE_ID
AND A.ACCT_ID = C.ACCT_ID
AND A.SERV_ID = D.SERV_ID(+)
AND A.ITEM_GROUP_ID = E.ITEM_GROUP_ID(+)
ORDER BY F.PRIORITY,
B.PRIORITY,
A.SHARE_RULE_PRIORITY ASC,
A.EXP_DATE ASC,
A.EFF_DATE ASC,
A.BALANCE ASC
查看执行计划:
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2723G| 696T| | 7776M| | |
| 1 | SORT ORDER BY | | 2723G| 696T| 1503T| 7776M| | |
|* 2 | HASH JOIN | | 2723G| 696T| 59M| 39355 | | |
|* 3 | HASH JOIN | | 228K| 56M| | 23918 | | |
| 4 | TABLE ACCESS FULL | BALANCE_TYPE | 8 | 184 | | 7 | | |
|* 5 | HASH JOIN | | 228K| 51M| | 23907 | | |
| 6 | TABLE ACCESS FULL | A_BALANCE_OBJECT_TYPE | 4 | 16 | | 7 | | |
|* 7 | HASH JOIN OUTER | | 228K| 50M| 43M| 23896 | | |
|* 8 | HASH JOIN OUTER | | 228K| 40M| 38M| 23199 | | |
| 9 | VIEW | | 228K| 36M| | 2043 | | |
| 10 | SORT UNIQUE | | 228K| 11M| 38M| 2043 | | |
| 11 | UNION-ALL | | | | | | | |
|* 12 | TABLE ACCESS BY GLOBAL INDEX ROWID | ACCT_BALANCE | 228K| 11M| | 50 | ROWID | ROW L |
|* 13 | INDEX RANGE SCAN | IDX_ACCT_BALANCE_ACCT_ID42 | 121K| | | 3 | | |
| 14 | NESTED LOOPS | | 1 | 146 | | 4 | | |
|* 15 | TABLE ACCESS FULL | BALANCE_SHARE_RULE | 1 | 109 | | 2 | | |
|* 16 | TABLE ACCESS BY GLOBAL INDEX ROWID| ACCT_BALANCE | 1 | 37 | | 2 | ROWID | ROW L |
|* 17 | INDEX UNIQUE SCAN | PK_P_ACCT_BALANCE2 | 1 | | | 1 | | |
| 18 | PARTITION RANGE ALL | | | | | | 1 | 63 |
| 19 | TABLE ACCESS FULL | SERV | 12M| 258M| | 14070 | 1 | 63 |
| 20 | TABLE ACCESS FULL | A_BALANCE_ITEM_GROUP | 244 | 11224 | | 7 | | |
| 21 | PARTITION RANGE ALL | | | | | | 1 | 63 |
| 22 | TABLE ACCESS FULL | ACCT | 11M| 239M| | 8505 | 1 | 63 |
------------------------------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - access(”A”.”ACCT_ID”=”C”.”ACCT_ID”)
3 - access(”A”.”BALANCE_TYPE_ID”=”B”.”BALANCE_TYPE_ID”)
5 - access(”A”.”OBJECT_TYPE_ID”=”F”.”OBJECT_TYPE_ID”)
7 - access(”A”.”ITEM_GROUP_ID”=”E”.”ITEM_GROUP_ID”(+))
8 - access(”A”.”SERV_ID”=”D”.”SERV_ID”(+))
12 - filter(”ACCT_BALANCE”.”BALANCE”>0 AND “ACCT_BALANCE”.”BALANCE_TYPE_ID”<>1 AND “ACCT_BALANCE”.”STATE”=’10A’)
13 - access(”ACCT_BALANCE”.”ACCT_ID”=TO_NUMBER(:Z))
15 - filter(”B1″.”ACCT_ID”=TO_NUMBER(:Z) AND NVL(”B1″.”EFF_DATE”,SYSDATE@!)< =SYSDATE@! AND
NVL("B1"."EXP_DATE",SYSDATE@!)>=SYSDATE@!)
16 - filter(”A1″.”BALANCE”>0 AND “A1″.”BALANCE_TYPE_ID”<>1 AND “A1″.”STATE”=’10A’)
17 - access(”A1″.”ACCT_BALANCE_ID”=”B1″.”ACCT_BALANCE_ID”)
祝新年快乐
Posted by 老熊 on 1月 24th, 2009鼠年将去,牛年将至。祝愿我的朋友们,在新的一年里,身体健康最重要,工作顺心,家庭幸福。
过去的一年,是不平凡的一年,我们经历了很多如雪灾,地震这样让人悲痛的灾难,也经历了奥运这样让人激动和兴奋的盛会。我希望在新的一年里,我的朋友们,能够在经济危机的影响下,依然能够快乐生活每一天。
怎样修改oracle的sysdba用户组
Posted by 老熊 on 1月 10th, 2009在安装oracle时,oracle会提示输入sysdba用户组名,凡是以操作系统认证方式的连接,如果连接的用户在这个指定的用户组中,就可以用sysdba用户登陆。一般情况下,也是建议的sysdba用户组为dba。
有的时候,也存在这样一种情况,安装oracle软件的时候,输入了错误的sysdba用户组名(主要是由于创建oracle用户时指定到了错误的其他用户组中,现实中这种情况曾经出现过)。这样一来,就会导致不规范的安装,或者oracle后来修改回正确的用户组(dba),将导致oracle用户不能以sysdba权限连接数据库,甚至不能启动数据库)。不规范的安装,如果将安装的oracle软件tar到其他机器,会导致那个机器的oracle也出现oracle不能以sysdba连接的问题(有的人安装oracle时,如果有现成的,他就喜欢用tar的方式)。
如果指定了错误的sysdba用户组名,怎么样快捷修改而又不用重新安装oracle软件呢?既然在安装时可以指定,那么一定会有一个地方,存储了这个配置,这个存储的文件就是$ORACLE_HOME/rdbms/lib/config.c。
我们看看config.c这个文件的内容:
[oracle@xty lib]$ cat config.c
/* SS_DBA_GRP defines the UNIX group ID for sqldba adminstrative access. */
/* Refer to the Installation and User’s Guide for further information. */#define SS_DBA_GRP “dba”
#define SS_OPER_GRP “dba”char *ss_dba_grp[] = {SS_DBA_GRP, SS_OPER_GRP};
从这个文件中,可以看到SYSDBA的用户组为”dba”,而SYSOPER的用户组也为”dba”。如果我们把#define SS_DBA_GRP “dba”这一行改为#define SS_DBA_GRP “adm”,然后执行下面的命令:relink all,再用oracle用户连接数据库时:
[oracle@xty ~]$ sqlplus /nolog
SQL*Plus: Release 10.2.0.3.0 - Production on Sat Jan 10 15:30:17 2009
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
SQL> connect / as sysdba
ERROR:
ORA-01031: insufficient privilegesSQL> connect / as sysoper
Connected to an idle instance
可以看到,oracle用户已经不能够用sysdba权限连接到数据库,也就更谈不上启动数据库了。但是由于sysoper的用户组没有改变,所以oracle仍然是可以用sysoper权限连接数据库并启动数据库的。(不过如果我们不使用操作系统认证,比如通过网络连接的方式用SID连接,并提供sys用户的密码,使用密码文件认证,也一样能够使用sysdba权限连接)
如果修改用户oracle的用户组为adm,则可以使用sysdba用户连接了。
[root@xty ~]# usermod -G adm oracle
oracle用户重新登陆到服务器上
[root@xty ~]# su - oracle
[oracle@xty ~]$ sqlplus “/ as sysdba”SQL*Plus: Release 10.2.0.3.0 - Production on Sat Jan 10 15:42:47 2009
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to an idle instance.
最后,我们把config.c修改回原来的值(”dba”),再relink all,再把oracle的用户组修改回dba,oracle也就恢复了原状。
在数据库服务器上,如果采用操作系统认证,而oracle用户又不能以sysdba权限连接(ORA-01031错误),在其他可能都排除后,有必要检查一下config.c,以确认sysdba用户组是正确的。
我的2009年计划
Posted by 老熊 on 1月 7th, 2009虽然说计划没有变化快,但我还是愿意列一个2009年的计划,或者说是2009年的目标。
人活着,总是离不开生活,工作和学习。学习是为了更好地工作,工作是为了生活得更好。所以我老熊的2009年计划(目标),对于工作、生活和学习都会有所涉及。
首先是关于学习了,主要是Oracle,《Cost Based Oracle Fundamentals》这本书,需要反复研究。《Troubleshooting Oracle Perforamnce》和《Oracle Database 10g Performance Tuning Tips and Techniques》这两本书,至少要看一遍,希望有所收获。Oracle的官方文档《Oracle10g Database Performance Tuning Guide And Reference》和《Oracle10g Database Administrator’s Guide》也要经常翻翻。对于RAC、Partition、Dataguard等内容,需要进一步深入。
花一点时间,更深入地研究一下Oracle内部的东西,虽然由于资料的匮乏,这个有些难度。不过,研究一个东西,是相当有意思的一件事情,不是吗?
如果有时间,涉足一下Oracle 11g的新功能。
除了Oracle,在操作系统及存储上,能够掌握更多的知识,当然主要是性能方面。
每周在这个网站上发表一篇原创的技术文章。虽然有时很忙,但个人认为,忙不是理由。写这些文章,我收获良多,并且把我所知道的东西共享出去,也是一件乐趣。所以,这是一件非常值得坚持做下去的事情。
在2008年初的时候,为了更好地研究oracle的块格式,也曾打算写一个类似于DUL的工具(我自己取名叫ODU),并最终付诸实施,只不过,个人对这个兴趣不是特别大,必竟已经有那么多同类型的工具了。不过,通过ODU这个程序的编写,掌握了Oracle的各种表,字段类型和索引的存储格式,收获还是很大的,我打算在2009年全部写完。这个话题,我会另外撰文详述。
2009年,希望能够站在更高的层面上,思考Oracle、操作系统、存储,甚至是IT系统上的整体架构。不再仅限于具体的技术细节。
谈完学习,再谈工作。根据目前的工作性质,能够保持工作热情,更有效率和更有质量地完成工作,是2009年的目标。
至于生活,我个人其实欲望并不高。只希望一家人,开开心心在一起生活,就足够了。天天陪着儿子玩一会儿,就已经感到非常满足。
一年的时间很快就会过去,2009年底的时候,我们再回头看看,上面的计划和目标到底有没有实现。计划先列在这里,也算是对我的一种鞭策,让我找到目标。
别了,2008
Posted by 老熊 on 12月 31st, 2008再过1小时,2008年就要过去了。
别了,2008
这一年里,发生了太多的事。
咱平民小百姓,不谈国家大事。谈谈自己的就好了。
2008年,在成都安定了下来。上班搞自己喜欢搞的ORACLE,下班回家陪陪父母、老婆和孩子。这日子,挺不错。
2009年,我会干什么呢?大家都会说计划没有变化快。看起来,我不用计划那么多事情了。唯一计划的是,为以后的发展储备更多的能量吧。
别了,2008
欢迎你,2009


Recent Comments