埃里森,甲骨文公司CEO,是当今仅次于盖茨的第二富翁。不过,也有人网上和他开玩笑,以下是网上流传的他在耶鲁大学2000年毕业典礼上的致词(可以肯定这不是真的)。
耶鲁的毕业生们,我很抱歉一一如果你们不喜欢这样的开场。我想请你们为我做一件事。请你一一好好看一看周围,看一看站在你左边的同学,看一看站在你右边的同学。请你设想这样的情
况:从现在起5年之后,10年之后,或30年之后,今天站在你左边的这个人会是一个失败者
右边的这个人,同样,也是个失败者。而你,站在中间的家伙,你以为会怎样?一样是失败者。失败的经历。失败的优等生
说实话,今天我站在这里,并没有看到一千个毕业生的灿烂未来。我没有看到一千个行业的一千名卓越领导者。我只看到了一千个失败者。你们感到沮丧。这是可以理解的。为什么,我,埃里森,一个退学生,竟然在美国最具声望的学府里这样厚颜地散布异端?我来告诉你原因。因为,
我,埃里森,这个行星上第二富有的人,是个退学生,而你不是。因为比尔·盖茨,这个行星上最富有的人一一就目前而言一一是个退学生,而你不是。因为艾伦,这个行星上第三富有的人,也退了学,而你没有。再来一点证据吧,因为戴尔,这个行星上第九富有的人一一他的排位还在不断上升,也是个退学生。而你,不是。
……你们非常沮丧。这是可以理解的。
现在,让我打击你一下。我要相当诚挚地指出:你们的文凭不是白拿的。你们中的大多数,我猜,已经在这里花费了四五年时光,你们将以各种方式在未来使用你所学的东西。你们已经确立了好的工作习惯。你们已经建立了能帮你沿这条路前进的人际网。你们已经将自己这辈子与“治疗”这个词建立了一种联系。一切很好。因为事实上,你们需要这些。
你们将来需要这些有用的工作习惯。你将来需要这种“治疗”。你需要它们,因为你没辍学,所以你永远不会成为世界上最富有的人。哦,当然,你可以,也许,以你的方式进步到第10位,第 11位,就像史蒂夫·鲍尔默,但,我没有告诉你他在为谁工作,是吧?根据记载,他是研究生时辍的学,开化得稍晚了些。
现在,我猜想你们中间很多人,也许是绝大多数人,正在琢磨,“我能做什么?我究竟有没有前途?”当然没有。太晚丁,你们已经吸收了太多东西,以为自己懂得太多。你们再也不是19岁了。你们有了“内置”的帽子,哦,我指的可不是你们脑袋上的学位帽。
嗯……你们已经非常沮丧啦。这是可以理解的。所以,现在可能是讨论实质的时候啦一一绝不是为了你们,2000年毕业生。你们已经被报销,不予考虑了。我想,你们就偷偷摸摸去干那年薪20万的可怜工作吧,在那里,工资单是由你两年前辍学的同班同学签字开出来的。事实上,我是寄希望于眼下还没有毕业的同学。我要对他们说,离开这里。收拾好你的东西,带着你的点子,别再回来。退学吧,开始行动。我要告诉你,一顶帽子一套学位服必然要让你沦落……就像这些保安马上要把我从这个讲台上撵走一样必然……(此时,Oracle CEO被带离了讲台)
人物介绍:
姓名:拉里.埃里森(Larry·Ellison),俄罗斯移民的美国犹太人后裔
年龄:57岁,出生于1944年曼哈顿
婚史:曾经历过3次婚姻
学历:读过三所大学,伊利诺斯大学、芝加哥大学、西北大学,后辍学
人生目标:击败微软,成为世界最大的软件企业是我的一大目标。我成功并不重要,重要的是其他所有人都失败了,那时我才是真正的成功。
惊人手笔:
1、他曾经想花2000万美元购买一架俄罗斯米格战斗机,令美国海关手足无措。
2、开着一架意大利产战斗机在太平洋上空和别人进行模拟空战。
3、因冒险玩命多次住进医院:上大学踢球时弄断过鼻梁骨,在夏威夷冲浪时扭伤过颈骨,还有一次因骑车摔断过肘骨。
4、拥有一架拆除武器的意大利产‘马尔切蒂S.211’型战斗机。
2007年2月9日星期五
| [+/-] |
二十世纪最狂妄的演讲 |
2007年2月8日星期四
| [+/-] |
如何判断一个字符串是否为数字或日期? |
转自Eygle大侠的一篇文章,感受颇深:
这就是区别.
高手遇到问题,总是说:自己写一个吧!
新手遇到问题,总是问:这个怎么实现?
昨天有一个朋友在MSN上问,如何判断一个字符串是否为数字?
我说,写一个函数吧。于是给出了一个例子:
SQL> CREATE OR REPLACE FUNCTION is_number (parmin VARCHAR2)
2 RETURN NUMBER
3 IS
4 val NUMBER;
5 BEGIN
6 val := TO_NUMBER (NVL (parmin, 'a'));
7 RETURN 1;
8 EXCEPTION
9 WHEN OTHERS
10 THEN
11 RETURN 0;
12 END;
13 /Function created.
SQL> select is_number('a') from dual;
IS_NUMBER('A')
--------------
0SQL> select is_number('0.998') from dual;
IS_NUMBER('0.998')
------------------
1SQL> select is_number('9999999999999999') from dual;
IS_NUMBER('9999999999999999')
-----------------------------
1
今天,这个朋友在MSN上又问:如何判断一个字符是否是日期?
我说,再写一个函数吧。
补注:由于session的语言设置会影响日期的输出格式,所以时间被转换为字符可能有多种形式。
以下这个函数只能满足部分情况,仅供参考。
SQL> CREATE OR REPLACE FUNCTION is_date (parmin VARCHAR2)
2 RETURN NUMBER
3 IS
4 val DATE;
5 BEGIN
6 val := TO_DATE (NVL (parmin, 'a'), 'yyyy-mm-dd hh24:mi:ss');
7 RETURN 1;
8 EXCEPTION
9 WHEN OTHERS
10 THEN
11 RETURN 0;
12 END;
13 /
Function created.
SQL> select is_date('a') from dual;
IS_DATE('A')
------------
0SQL> select is_date('2004-05-05') from dual;
IS_DATE('2004-05-05')
---------------------
1SQL> select is_date('2004/01/01') from dual;
IS_DATE('2004/01/01')
---------------------
1SQL> select is_date('01/01/04') from dual;
IS_DATE('01/01/04')
-------------------
1SQL> select is_date('01-jan-04') from dual;
IS_DATE('01-JAN-04')
--------------------
1
这两者是何其相似啊!
参考原文--end
2007年1月20日星期六
| [+/-] |
Oracle Database 10g为数据库管理员提供的20个最重要的特性(四) |
第 4 周
高速的导出/导入:Oracle Data Pump
利用 Oracle Database 10g 实用工具数据移动得到了很大的提高。
迄今为止,导出/导入工具集仍是跨多个平台转移数据所需劳动强度最小的首选实用工具,尽管人们常常抱怨它速度太慢。导入只是将每条记录从导出转储文件中读出来,然后使用常见的 INSERT INTO 命令将其插入到目标表中,因此导入可能是个很慢的过程,这一点并不让人感到吃惊。
进入 Oracle Data Pump,Oracle Database 10g 中的导出/导入工具包的更新更快的同类工具,它被设计来成倍地加速这个过程。
Data Pump 反映了整个导出/导入过程的彻底革新。它不是使用常见的 SQL 命令,而是应用专用 API 来以更快得多的速度加载和卸载数据。在我的测试中,我看到导出性能比在直接模式下提高了 10-15 倍,导入过程性能提高了 5 倍。此外,与使用导出实用工具不同,它还能够只取出特定类型的对象(如过程)。
Data Pump 导出
这 个新的实用工具称为 expdp,以和原来的导出 exp 区分开。在本例中,我们将用 Data Pump 来导出一个大表 CASES,大小约为 3GB。Data Pump 在服务器端使用文件处理来创建和读取文件;因此,目录作为位置使用。在这种情况下,我们将使用文件系统 /u02/dpdata1 来保存转储文件。
create directory dpdata1 as '/u02/dpdata1';
grant read, write on directory dpdata1 to ananda;
接下来,我们将导出数据:
expdp ananda/abc123 tables=CASES directory=DPDATA1
dumpfile=expCASES.dmp job_name=CASES_EXPORT
让我们来分析该命令的各个部分。用户 ID/口令组合、表和转储文件参数的意义是显而易见的。与原来的导出不同,文件是在服务器(不是客户端)上创建的。位置由目录参数值 DPDATA1 指定,它指向之前创建的 /u02/dpdata1。这个进程还在目录参数指定的位置上创建一个日志文件(同样在服务器上)。默认地,这个进程使用一个名称为 DPUMP_DIR 的目录;因此可以创建它来代替 DPDATA1。
注 意上面的参数 job_name,这是个特殊的参数,在原来的导出中没有。所有的 Data Pump 工作都通过作业来完成。Data Pump 作业 — 与 DBMS 作业不同 — 只是服务器进程,它代表主进程处理数据。主进程(称为主控制进程)通过高级队列 (AQ) 来协调这项工作;它通过在运行期内创建的一个特殊的表(称为主表)来实现这个目的。在我们的例子中,如果您在 expdp 运行时检查用户 ANANDA 的模式 ,您将注意到一个表 CASES_EXPORT 的存在(对应参数 job_name)。当 expdp 结束时,这个表被丢弃。
导出监控
当 Data Pump Export (DPE) 运行时,按 Control-C;它将阻止消息在屏幕上显示,但不停止导出进程本身。相反,它将显示 DPE 提示符(如下所示)。进程现在被认为处于“交互式”模式:
Export>
这种方法允许在这个 DPE 作业上输入几条命令。要查看概要,在提示符下使用 STATUS 命令:
Export> status
Job:CASES_EXPORT
Operation:EXPORT
Mode:TABLE
State:EXECUTING
Degree: 1
Job Error Count: 0
Dump file:/u02/dpdata1/expCASES.dmp
bytes written = 2048
Worker 1 Status:
State:EXECUTING
Object Schema:DWOWNER
Object Name:CASES
Object Type:TABLE_EXPORT/TBL_TABLE_DATA/TABLE/TABLE_DATA
Completed Objects: 1
Total Objects: 1
Completed Rows: 4687818
记住,这只是状态显示。导出在后台工作。要继续在屏幕上查看消息,从 Export> 提示符下使用命令 CONTINUE_CLIENT。
并行操作
您可以通过 PARALLEL 参数为导出使用一个以上的线程来显著地加速作业。每个线程创建一个单独的转储文件,因此参数 dumpfile 应当拥有和并行度一样多的项目。您可以指定通配符作为文件名,而不是显式地输入各个文件名,例如:
expdp ananda/abc123 tables=CASES directory=DPDATA1
dumpfile=expCASES_%U.dmp parallel=4 job_name=Cases_Export
注意 dumpfile 参数拥有一个通配符 %U,它指示文件将按需要创建,格式将为 expCASES_nn.dmp,其中 nn 从 01 开始,然后按需要向上增加。
在并行模式下,状态屏幕将显示四个工作进程。(在默认模式下,只有一个进程是可见的。)所有的工作进程同步取出数据,并在状态屏幕上显示它们的进度。
分离访问数据文件和转储目录文件系统的输入/输出通道是很重要的。否则,与维护 Data Pump 作业相关的开销可能超过并行线程的效益,并因此而降低性能。并行方式只有在表的数量多于并行值并且表很大时才是有效的。
数据库监控
您 还可以从数据库视图获得关于运行的 Data Pump 作业的更多信息。监控作业的主视图是 DBA_DATAPUMP_JOBS,它将告诉您在作业上有多少个工作进程(列 DEGREE)在工作。另一个重要的视图是 DBA_DATAPUMP_SESSIONS,当它与上述视图和 V$SESSION 结合时将给出主前台进程的会话 SID。
select sid, serial#
from v$session s, dba_datapump_sessions d
where s.saddr = d.saddr;
这条指令显示前台进程的会话。更多有用的信息可以从警报日志中获得。当进程启动时,MCP 和工作进程在警报日志中显示如下:
kupprdp:master process DM00 started with pid=23, OS id=20530 to execute -
SYS.KUPM$MCP.MAIN('CASES_EXPORT', 'ANANDA');
kupprdp:worker process DW01 started with worker id=1, pid=24, OS id=20532 to execute -
SYS.KUPW$WORKER.MAIN('CASES_EXPORT', 'ANANDA');
kupprdp:worker process DW03 started with worker id=2, pid=25, OS id=20534 to execute -
SYS.KUPW$WORKER.MAIN('CASES_EXPORT', 'ANANDA');
它显示为数据泵操作启动的会话的 PID。您可以用以下查询找到实际的 SID:
select sid, program from v$session where paddr in
(select addr from v$process where pid in (23,24,25));
PROGRAM 列将对应警报日志文件中的名称显示进程 DM (为主进程)或 DW (为工作进程)。如果一个工作进程使用了并行查询,比如说 SID 23,您可以在视图 V$PX_SESSION 中看到它,并把它找出来。它将为您显示从 SID 23 代表的工作进程中运行的所有并行查询会话:
select sid from v$px_session where qcsid = 23;
从视图 V$SESSION_LONGOPS 中可以获得其它的有用信息来预测完成作业将花费的时间。
select sid, serial#, sofar, totalwork
from v$session_longops
where opname = 'CASES_EXPORT'
and sofar != totalwork;
列 totalwork 显示总工作量,该列的 sofar 数量被加和到当前的时刻 — 因而您可以用它来估计还要花多长时间。
Data Pump 导入
不过,数据导入性能是 Data Pump 真正出色的地方。要导入先前导出的数据,我们将使用
impdp ananda/abc123 directory=dpdata1 dumpfile=expCASES.dmp job_name=cases_import
导入进程的默认行为是创建表和所有相关的对象,然后在表已存在时产生一个错误。如果您想把数据添加到一个现有的表中,您可以在上述命令行中使用 TABLE_EXISTS_ACTION=APPEND。
和使用 Data Pump 导入一样,在进程中按 Control-C 将进入 Date Pump Import (DPI) 的交互模式;同样,提示符是 Import>。
处理特定对象
您是否有过只需要从一个用户导出特定的过程,以在一个不同的数据库或用户中重新创建这些过程的情况?与传统的导出实用工具不同,Data Pump 允许您只导出特定类型的对象。例如,以下命令让您只导出过程,而不导出其它任何东西 — 不导出表、视图、甚至函数:
expdp ananda/iclaim directory=DPDATA1 dumpfile=expprocs.dmp include=PROCEDURE
要只导出一些特定的对象 — 比如说,函数 FUNC1 和过程 PROC1 — 您可以使用
expdp ananda/iclaim directory=DPDATA1 dumpfile=expprocs.dmp
include=PROCEDURE:"='PROC1'",FUNCTION:"='FUNC1'"
这个转储文件充当了源对象的一个备份。您甚至可以用它来创建 DDL 脚本,以供之后使用。一个称为 SQLFILE 的特殊参数允许创建 DDL 脚本文件。
impdp ananda/iclaim directory=DPDATA1 dumpfile=expprocs.dmp sqlfile=procs.sql
该指令在 DPDATA1 指定的目录中创建一个名称为 procs.sql 的文件,并将对象的脚本包含在导出转储文件中。这种方法帮助您快速地在另一个模式中创建源对象。
利用参数 INCLUDE 允许您从转储文件中定义要包含或排除的对象。您可以使用子句 INCLUDE=TABLE:"LIKE 'TAB%'" 来仅导出那些名称以 TAB 开头的表。类似地,您可以使用结构 INCLUDE=TABLE:"NOT LIKE 'TAB%'" 来排除所有名称以 TAB 开头的表。作为另一种选择,您可以使用 EXCLUDE 参数来排除特定的对象。
通过外部表,Data Pump 还可以用来传输表空间;它非常强大,能够即时地重定义并行方式,将更多的表添加到一个现有的进程中等等(这超出了本文的范围;关于更多详细信息,请参考 Oracle Database Utilities 10g Release 1 10.1)。以下命令显示Data Pump 导出实用工具提供的所有参数的列表:
expdp help=y
类似地,impdp help=y 将显示 DPI 中的所有参数。
当 Data Pump 作业在运行时,您可以通过在 DPE 或 DPI 提示符下发出 STOP_JOB 来暂停它们,然后用 START_JOB 来重起它们。这个功能在您空间不足和想在继续执行之前进行修改时非常方便。
--end
2007年1月15日星期一
| [+/-] |
Oracle Database 10g:数据库管理员提供的20个最重要的特性(三) |
第 3 周
名字中包含了什么?:改善的表空间管理
表空间管理得到了重大的改进,这可以归因于一个 sparser SYSTEM、为用户定义一个默认表空间的支持、新的 SYSAUX、甚至重命名
您曾经多少次因用户在 SYSTEM 表空间中创建了非 SYS 和 SYSTEM 的段而伤透脑筋?
在 Oracle9i Database 之前,如果在创建用户时没有指定默认表空间,那么它将默认为 SYSTEM 表空间。如果用户在创建一个段时没有显式地指定一个表空间,那么这个段将在 SYSTEM 中创建—前提是用户在 SYSTEM 表空间中拥有配额(要么显式地授予,要么通过系统权限 UNLIMITED TABLESPACE 来授予)。Oracle9i 允许 DBA 为所有未用显式的临时表空间子句创建的用户指定一个默认的临时表空间,从而减少了这个问题。
在 Oracle Database 10g 中,您可以类似地为用户指定一个默认表空间。在数据库创建期间,CREATE DATABASE 命令可以包含子句 DEFAULT TABLESPACE
ALTER DATABASE DEFAULT TABLESPACE;
未用 DEFAULT TABLESPACE 子句创建的所有用户将以
重要注意事项:拥有旧的表空间的所有用户的默认表空间都被修改为
如果在数据库创建期间没有指定默认表空间,它将默认为 SYSTEM。但您如何才能知道现有的数据库的默认表空间是哪一个?发出以下查询:
SELECT PROPERTY_VALUE
FROM DATABASE_PROPERTIES
WHERE PROPERTY_NAME = 'DEFAULT_PERMANENT_TABLESPACE';
DATABASE_PROPERTIES 视图显示默认表空间之外,还显示一些非常重要的信息 — 例如默认临时表空间、全局数据库名、时区等。
非必要模式的默认表空间
几种模式(如智能代理用户 DBSNMP、数据挖掘用户 ODM)与用户操作不直接相关,但对数据库完整性仍很重要。这些模式中的一些曾经用 SYSTEM 作为它们的默认表空间 — 这是在 SYSTEM 表空间内对象增殖的又一个原因。
Oracle Database 10g 引进了一个新的称为 SYSAUX 的表空间,它用来保存这些模式的对象。这个表空间是在数据库创建期间自动创建的,并在本地进行管理。唯一允许修改的是数据文件的名称。
这种方法在 SYSTEM 损坏需要完整的数据库恢复时,为恢复提供支持。SYSAUX 中的对象可以被恢复为任意正常的用户对象,同时数据库本身保持运行。
但 如果您想将 SYSAUX 中的这些模式中的一些转移到一个不同的表空间中时,该怎么办?例如,考虑 LogMiner 使用的对象,这些对象的大小经常增长,直到最终填满表空间。出于可管理性的原因,您可能考虑将它们转移到它们自己的表空间中。但实现这一目的的最好的方法 是什么?
作为一个数据库管理员,了解转移这些特殊对象的正确过程对您而言是很重要的。幸运的是,Oracle Database 10g 提供了一个新的视图使要凭猜测来做的工作形象化。这个视图,V$SYSAUX_OCCUPANTS,列出了表空间 SYSAUX 中的模式的名称、它们的说明、当前使用的空间,以及如何转移它们。(参见表 1。)
注 意 LogMiner 如何被清楚地显示为占用 7,488 KB 的空间。它归模式 SYSTEM 所有,而要转移对象,您需要执行打包的过程 SYS.DBMS_LOGMNR_D.SET_TABLESPACE。不过,对于 STATSPACK 对象,这个视图推荐使用导入/导出方法;而对于流,没有转移过程 — 因而您不能容易地将它们从 SYSAUX 表空间中转移出来。列 MOVE_PROCEDURE 默认显示 SYSAUX 中存在的几乎所有工具的正确的转移过程。也可以逆向使用转移过程来使对象回到 SYSAUX 表空间中。
重命名一个表空间
在 数据仓库环境中(典型地,对于数据中心体系结构),在数据库之间传输表空间是很常见的。但源数据库和目标数据库必须不存在拥有相同名称的表空间。如果存在 两个拥有相同名称的表空间,则目标表空间中的段必须转移到一个不同的表空间中,然后重新创建这个表空间— 这个任务说起来容易做起来难。
Oracle Database 10g 提供了一个方便的解决方案:您可以用以下命令来简单地重命名一个现有的表空间(SYSTEM 和 SYSAUX 除外) — 无论是永久表空间还是临时表空间:
ALTER TABLESPACERENAME TO ;
这个功能还将应用在存档过程中。假定您有一个按范围分区的表,用于记录 销售历史数据,每个月的这个分区位于按这个月份命名的一个表空间中 — 例如,1 月份的分区命名为 JAN,并位于一个名称为 JAN 的表空间中。这样您就拥有了一个将信息保留 12 个月的策略。在 2004 年 1 月,您将能够存档 2003 年 1 月的数据。大致的操作流程类似于以下操作:
- 利用 ALTER TABLE EXCHANGE PARTITION 从分区 JAN 中创建一个独立的表 JAN03。
- 将表空间重命名为 JAN03。
- 为表空间 JAN03 创建一个可传输表空间集。
- 将表空间 JAN03 重新命名为 JAN。
- 将空的分区交换回表中。
第 1、2、4 和 5 步很简单,并且不会过度地消耗资源(如重做和撤消空间)。第 3 步只是拷贝文件并只为 JAN03 输出数据字典信息,这也是个非常轻松的过程。如果您需要恢复之前存档的分区,这个过程也非常简单,您只需要将相同的过程反过来就行了。
Oracle Database 10g 在处理这些重命名的方式上相当智能化。如果您重命名作为 UNDO 或默认临时表空间的表空间,这可能产生混淆。但数据库将自动调整必要的记录来反映这种变化。例如,将默认表空间的名称从 USERS 修改为 USER_DATA 将自动修改视图 DATABASE_PROPERTIES。在修改之前,查询:
select property_value from database_properties
where property_name = 'DEFAULT_PERMANENT_TABLESPACE';
返回 USERS。在运行下面的语句之后
alter tablespace users rename to user_data;
上述查询返回 USER_DATA,因为所有对 USERS 的引用都被修改为到 USER_DATA。
修改默认临时表空间的情况一样。甚至修改 UNDO 表空间的名称也将触发 SPFILE 中的变化,如下所示:
SQL> select value from v$spparameter where name = 'undo_tablespace';
VALUE
--------
UNDOTBS1
SQL> alter tablespace undotbs1 rename to undotbs;
Tablespace altered.
SQL> select value from v$spparameter where name = 'undo_tablespace';
VALUE
--------
UNDOTBS
结论
在最近的几个 Oracle 版本演变的过程中,对象处理得到了稳定的增强。Oracle8i 引进了表从一个表空间到另一个表空间的转移,Oracle 9i Database R2 引进了列重命名,现在 — 在最新的版本中 — 表空间自身的重命名成为可能。这些增强显著地减轻了数据库管理员的任务 — 特别是在数据仓库或数据中心环境中。
--end2007年1月13日星期六
| [+/-] |
Oracle Database 10g:为DBA提供的最佳前20位的特性(二) |
第一个特性就是前面的那篇<Oracle10g中如何追踪数据操作历史>
从本周开始,陆续介绍这20位特性,敬请留意。
Oracle Database 10g:为 DBA 提供的最佳前 20 位的特性第 2 周
第 2 周还要多长时间?:回滚监视
为用户提供对回滚操作时间的准确评估
我们还在这地方吗?还要多长时间?
听起来熟悉吗?这些问题可能是您在前往孩子们最喜爱的主题公园的路上,从汽车后座上提出来的,并且经常是不断地、越来越频繁地提出来。您不想告诉他们还确切需要多长时间吗 — 或者更简单些,您自己知道答案吗?
同样,在回滚长期运行的事务时,经常会有些用户不停地询问相同的问题。这些问题是合理的,因为该事务进行了锁定,正常的处理经常受到回滚进程的影响。
在 Oracle 9i Database 及更低的版本中,您可以执行查询
SELECT USED_UREC
FROM V$TRANSACTION;
该语句返回由当前事务所使用的重做记录的数量,而如果重复地执行该语句,将会显示连续减少的数值,因为回滚进程在其处理过程中会释放重做记录。随后您可以通过对一段间隔进行快照来计算其速率,然后推断出评估结束时间的结果。 虽然在视图 V$TRANSACTION 中有一个名为 START_TIME 的列,但该列只显示整个事务的起始时间(也就是在回滚执行之前)。因此,除了推断,您没有办法知道回滚实际上是在什么时间执行的。
事务回滚的扩展统计信息
在 Oracle Database 10g 中,这种操作很简单。当事务回滚时,事件被记录在视图 V$SESSION_LONGOPS 中,该视图显示长期运行的事务。用于回滚,如果进程耗时超过六秒,则记录出现在该视图中。在回滚执行以后,您可能会隐藏所查看的监视屏幕并执行以下的查询:
select time_remaining
from v$session_longops
where sid = <sid of the session doing the rollback>;
既然您意识到这个视图 V$SESSION_LONGOPS 的重要性,就让我们来看它必须提供的其他信息。该视图在 Oracle Database 10g 的预览版中提供,但没有捕获关于回滚事务的信息。为了以一种易读的方式显示所有的列,我们将使用由 Tom Kyte 在 AskTom.com 中所描述的 PRINT_TABLE 函数。此过程简单地以表格方式而不是常用的行方式来显示列。 SQL> set serveroutput on size 999999
SQL> exec print_table('select * from v$session_longops where sid = 9')
SID : 9
SERIAL# : 68
OPNAME :Transaction Rollback
TARGET :
TARGET_DESC :xid:0x000e.01c.00000067
SOFAR : 20554
TOTALWORK : 10234
UNITS :Blocks
START_TIME :07-dec-2003 21:20:07
LAST_UPDATE_TIME :07-dec-2003 21:21:24
TIME_REMAINING : 77
ELAPSED_SECONDS : 77
CONTEXT : 0
MESSAGE :Transaction Rollback:xid:0x000e.01c.00000067 :
10234 out of 20554 Blocks done
USERNAME :SYS
SQL_ADDRESS :00000003B719ED08
SQL_HASH_VALUE : 1430203031
SQL_ID :306w9c5amyanr
QCSID : 0
注意,此处显示对行的所有更改,即使删除并重新插入行时也是如此。VERSION_OPERATION 列显示对该行执行的操作 (Insert/Update/Delete)。完成这些操作不需要历史表或额外的列。 让 我们仔细检查这些列中的每一列。在会话中可能会有超过多个长期运行操作 — 特别是因为视图中包含以前的会话中所有长期运行操作的历史。列 OPNAME 显示该记录用于“事务回滚”,这为我们指出了正确的方向。列 TIME_REMAINING 显示所评估的剩余时间秒数,这在前面已经描述过,而列 ELAPSED_SECONDS 显示到目前为止所消耗的时间。
那 么该表如何提供对剩余时间的评估呢?可以在列 TOTALWORK 中找到线索,该列显示要完成的“工作”总量,还有 SOFAR 显示到目前为止已经完成了多少工作。工作的单位显示在列 UNITS 中。在本例中以数据块为单位;因此,到目前为止已经回滚了 20,554 个数据块中共计 10,234 个数据块。此操作到目前为止已消耗了 77 秒。因此,剩余数据块将消耗:
77 * ( 10234 / (20554-10234) ) ˜ 77 秒
但您不必利用这种方法来获得该数值,它已经清楚地显示出来了。最后,列 LAST_UPDATE_TIME 显示有关当前视图内容的时间,这将用于加强您对结果的解释。
SQL 语句
另一部分重要的新信息是正在被回滚的 SQL 语句的标识符。在早先,SQL_ADDRESS 和 SQL_HASH_VALUE 用于获取正在被回滚的 SQL 语句。新的列 SQL_ID 对应于视图 V$SQL 的 SQL_ID,如下所示:
SELECT SQL_TEXT
FROM V$SQL
WHERE SQL_ID = <value of SQL_ID from V$SESSION_LONGOPS>;
该查询返回所回滚的语句,因此提供了额外的校验以及 SQL 语句的地址和散列值。 并行实例恢复
如果 DML 操作是并行操作,则列 QCSID 显示并行查询服务器会话的 SID。在并行回滚事件中,如实例恢复以及随后的故障事务恢复期间,经常用到该信息经常。
例如,假设在大型的更新期间,实例异常关闭。当实例启动时,发生故障的事务被回滚。如果启用了用于并行恢复的初始化参数值,则回滚并行地而不是串行地发生,如同它发生在常规事务回滚中一样。下一步的任务是评估回滚进程的完成时间。
视 图 V$FAST_START_TRANSACTIONS 显示为回滚故障事务所产生的事务。类似的视图 V$FAST_START_SERVERS 显示对回滚进行处理的并行查询服务器的数量。这两个视图都在以前的版本中提供,但显示事务标识符的新列 XID 使得联接更方便了。在 Oracle9i Database 以及更低的版本中,您必须通过三列(USN — 重做段号,SLT — 重做段中的存储区号,SEQ — 序列号)来联接视图。其父集显示在 PARENTUSN、PARENTSLT 和 PARENTSEQ 中。在 Oracle Database 10g 中,您只需将其联接到 XID 列,其父 XID 由直观的名称表示:PXID。
最有用的信息部分来自于 V$FAST_START_TRANSACTIONS 视图中的列 RCVSERVERS。如果发生并行回滚,则该列中显示并行查询服务器的数量。您可以查看该列,了解启动了多少并行查询进程:
select rcvservers from v$fast_start_transactions;
如果输出是 1,则事务正在由 SMON 进程进行串行回滚 — 显然这是完成工作的一种不充分的方法。您可以将初始化参数 RECOVERY_PARALLELISM 的值改为除 0 或 1 以外的值,重新启动实例进行并行回滚。随后您可以执行 ALTER SYSTEM SET FAST_START_PARALLEL_ROLLBACK = HIGH,按 CPU 数量的 4 倍创建并行服务器。 如 果上述查询的输出显示不是 1,则正在进行并行回滚。您可以查询同一视图 (V$FAST_START_TRANSACTIONS) 来获得父事务和子事务(父事务 id — PXID,而子事务 id — XID)。XID 还可用于联接此视图与 V$FAST_START_SERVERS,以获得其他详细信息。
结论
总之,当在 Oracle Database 10g 中回滚长期运行的事务时 — 无论是并行实例恢复会话还是用户执行的回滚语句 — 您所需做的一切就是查看视图 V$SESSION_LONGOPS 并评估还需要多少时间。
现在,如果能预测到达主题公园的时间就好了!
--end
2006年12月23日星期六
| [+/-] |
Oracle10g性能视图flash版本 |
上个月,在eygle的blog上看到有Oracle9i和10g的数据字典的挂图和下载,超级酷~~
打算哪天有空也去弄张挂在书房,倍拉风!!
现在居然有最新的flash版本的,这样电子版本看这就不那么吃力了。
到eygle大侠的站点参考原文
--end
2006年12月20日星期三
| [+/-] |
Oracle10g中如何追踪数据操作历史 |
经常有朋友问,如何追踪数据库的操作历史,谁在什么时候插入/修改/删除了什么数据?
在Oracle10g之前,如果想得到这些数据,只能自己想办法写些脚本或者工具,Oracle10g中有一个feature,叫闪回查询(flash), 让你看到的"不是一个图片,而是一部电影"
下面是从Oracle的官方文档得到的关于这个feature的描述:
得到电影而不是图片:闪回版本查询
不需要设置,立即识别对行的所有更改
在 Oracle9i Database 中,我们看到它推出了以闪回查询形式表示的“时间机器”。该特性允许 DBA 看到特定时间的列值,只要在还原段中提供该数据块此前镜像的拷贝即可。但是,闪回查询只提供某时刻数据的固定快照,而不是在两个时间点之间被更改数据的运 行状态表示。某些应用程序,如涉及到外币管理的应用程序,可能需要了解一段时期内数值数据的变化,而不仅仅是两个时间点的数值。由于闪回版本查询特性,Oracle Database 10g 能够更方便高效地执行该任务。
查询对表的更改
在本示例中,我使用了一个银行外币管理应用程序。其数据库含有一个名称为 RATES 的表,用于记录特定时间的汇率。
SQL> desc rates该表显示 US$ 与各种其他货币的汇率,在 CURRENCY 列中显示。在金融服务行业中,汇率不但在变更时进行更新,而且被记录在历史中。需要这种方式的原因是银行交易可能在“过去时间”生效,以便适应由于汇款而 耗费的时间。例如,对于一项在上午 10:12 发生但在上午 9:12 生效的交易,其有效汇率是上午 9:12 的汇率,而不是现在的汇率。
Name Null?Type
----------------- -------- ------------
CURRENCY VARCHAR2(4)
RATE NUMBER(15,10)
直到现在,唯一的选择是创建一个汇率历史表来存储汇率的变更,然后查询该表是否提供历史记录。另一种选择 是在 RATES 表本身中记录特定汇率适用性的开始和结束时间。当发生变更时,现有行中的 END_TIME 列被更新为 SYSDATE,并插入一个具有新汇率的新行,其 END_TIME 为 NULL。
但是在 Oracle Database 10g 中,闪回版本查询特性不需要维护历史表或存储开始和结束时间。使用该特性,您不必进行额外的设置,即可获得某行在过去特定时间的值。
例如,假定该 DBA 在正常业务过程中数次更新汇率 — 甚至删除了某行并重新插入该行:
insert into rates values ('EURO',1.1012);
commit;
update rates set rate = 1.1014;
commit;
update rates set rate = 1.1013;
commit;
delete rates;
commit;
insert into rates values ('EURO',1.1016);
commit;
update rates set rate = 1.1011;
commit;
在进行了这一系列操作后,DBA 将通过以下命令获得 RATE 列的当前提交值 SQL> select * from rates;此输出显示 RATE 的当前值,没有显示从第一次创建该行以来发生的所有变更。这时使用闪回查询,您可以找出给定时间点的值;但我们对构建变更的审计线索更感兴趣 — 有些类似于通过便携式摄像机来记录变更,而不只是在特定点拍摄一系列快照。
CURR RATE
---- ----------
EURO 1.1011
以下查询显示了对表所做的更改:
select versions_starttime, versions_endtime, versions_xid,注意,此处显示了对该行所作的所有更改,甚至包括该行被删除和重新插入的情况。VERSION_OPERATION 列显示对该行执行了什么操作 (Insert/Update/Delete)。所做的这些工作不需要历史表或额外的列。
versions_operation, rate
from rates versions between timestamp minvalue and maxvalue
order by VERSIONS_STARTTIME
/
VERSIONS_STARTTIME VERSIONS_ENDTIME VERSIONS_XID V RATE
---------------------- ---------------------- ---------------- - ----------
01-DEC-03 03.57.12 PM 01-DEC-03 03.57.30 PM 0002002800000C61 I 1.1012
01-DEC-03 03.57.30 PM 01-DEC-03 03.57.39 PM 000A000A00000029 U 1.1014
01-DEC-03 03.57.39 PM 01-DEC-03 03.57.55 PM 000A000B00000029 U 1.1013
01-DEC-03 03.57.55 PM 000A000C00000029 D 1.1013
01-DEC-03 03.58.07 PM 01-DEC-03 03.58.17 PM 000A000D00000029 I 1.1016
01-DEC-03 03.58.17 PM 000A000E00000029 U 1.1011
在上述查询中,列 versions_starttime、versions_endtime、versions_xid、versions_operation 是伪列,与 ROWNUM、LEVEL 等其他熟悉的伪列相类似。其他伪列 — 如 VERSIONS_STARTSCN 和 VERSIONS_ENDSCN — 显示了该时刻的系统更改号。列 versions_xid 显示了更改该行的事务标识符。有关该事务的更多详细信息可在视图 FLASHBACK_TRANSACTION_QUERY 中找到,其中列 XID 显示事务 id。例如,使用上述的 VERSIONS_XID 值 000A000D00000029,UNDO_SQL 值显示了实际的语句。
SELECT UNDO_SQL除了实际语句之外,该视图还显示提交操作的时间标记和 SCN、查询开始时的 SCN 和时间标记以及其他信息。
FROM FLASHBACK_TRANSACTION_QUERY
WHERE XID = '000A000D00000029';
UNDO_SQL
----------------------------------------------------------------------------
insert into "ANANDA"."RATES"("CURRENCY","RATE") values ('EURO','1.1013');
找出一段时期中的变更
现在,让我们来看如何有效地使用这些信息。假设我们需要找出下午 3:57:54 时 RATE 列的值。我们可以执行:
select rate, versions_starttime, versions_endtime此查询与闪回查询类似。在以上的示例中,开始和结束时间为空,表示汇率在该时间段中没有更 改,而是包含一个时间段。还可以使用 SCN 来找出过去的版本值。可以从伪列 VERSIONS_STARTSCN 和 VERSIONS_ENDSCN 中获得 SCN 号。以下是一个示例:
from rates versions
between timestamp
to_date('12/1/2003 15:57:54','mm/dd/yyyy hh24:mi:ss')
and to_date('12/1/2003 16:57:55','mm/dd/yyyy hh24:mi:ss')
/
RATE VERSIONS_STARTTIME VERSIONS_ENDTIME
---------- ---------------------- ----------------------
1.1011
select rate, versions_starttime, versions_endtime使用关键词 MINVALUE 和 MAXVALUE,可以显示还原段中提供的所有变更。您甚至可以提供一个特定的日期或 SCN 值作为范围的一个端点,而另一个端点是文字 MAXVALUE 或 MINVALUE。例如,以下查询提供那些只从下午 3:57:52 开始的变更,而不是全部范围的变更:
from rates versions
between scn 1000 and 1001
/
select versions_starttime, versions_endtime, versions_xid,最终的分析
versions_operation, rate
from rates versions between timestamp
to_date('12/11/2003 15:57:52', 'mm/dd/yyyy hh24:mi:ss')
and maxvalue
order by VERSIONS_STARTTIME
/
VERSIONS_STARTTIME VERSIONS_ENDTIME VERSIONS_XID V RATE
---------------------- ---------------------- ---------------- - ----------
01-DEC-03 03.57.55 PM 000A000C00000029 D 1.1013
01-DEC-03 03.58.07 PM 01-DEC-03 03.58.17 PM 000A000D00000029 I 1.1016
01-DEC-03 03.58.17 PM 000A000E00000029 U 1.1011
闪回版本查询随取随用地复制表变更的短期易变数值审计。这一优点使得 DBA 能够获得过去时间段中的所有变更而不是特定值,只要还原段中提供数据,就可以尽情使用。因此,最大的可用版本依赖于 UNDO_RETENTION 参数。
原文请参考:
为数据库管理员提供的最佳 Oracle Database 10g 特性
--end
2006年12月11日星期一
| [+/-] |
ORACLE VS DB2 |
很多产品,技术都是类似的
看到IBM上一篇文章说,如何利用Oracle 10g的技能学习DB2 9.1
呵呵,另外还有一篇如何利用SQL Server的技能学习DB2
随着竞争的日益加剧,不同厂家的产品本身再功能上已经没有多大本质的区别
市场份额的彼消此长,也说明这个这个问题,谁的产品更能吸引用户,更能为用户考虑的更多,最终往往能稍胜一筹
ORACLE和DB2的一些系统级别的比较.
图 . Oracle on Linux, UNIX, and Windows Version 10.2 的系统结构
图 . DB2 on Linux, UNIX, and Windows 系统结构
表 . Oracle 数据库与 DB2 数据库和表空间的对应关系
| Oracle 数据库或表空间 | DB2 数据库或表空间 |
| SYSTEM 是存放编目(数据字典)信息的表空间 | SYSCATSPACE(编目表空间);和在 Oracle 中一样,仅在数据库级保存该信息 |
| Data Dictionary(包含表和视图形式的元数据),驻留在 SYSTEM 表空间中 | 系统编目表(由 SYSIBM 模式标识),系统视图(由 SYSCAT 或 SYSSTAT 模式标识),驻留在 SYSCATSPACE 表空间中 |
| SCOTT 数据库 | SAMPLE 数据库 |
| TEMP 表空间 | System Temporary 表空间(缺省情况下名为 tempspace1) |
| UNDO 表空间 | N/A |
| USER 表空间 | 用户表空间。缺省情况下,USERSPACE1 一般是在数据库创建之后才创建的 |
Oracle 内存架构和后台进程
DB2 内存架构和后台进程
比较了 DB2 9 与 Oracle 10g 的 XML 功能。
| XML 功能 | Oracle 10g | IBM DB2 9 for Linux, Unix and Windows |
|---|---|---|
| 支持 XML 的存储 | √ | 不适用 |
| XML 原生存储 | × | √ |
| 大环境的易维护性 | × | √ |
| 高度可伸缩性 | × | √ |
| 将 XML 文档存储为 CLOB | √ | √。但是从长远看,鼓励使用 XML 原生存储 |
| 分解 | √ | √。但是从长远看,鼓励使用 XML 原生存储 |
总结了我们讨论过的 Oracle 与 DB2 9 之间的相同点与不同点。
表 —— Oracle 与 DB2 9 概念总结
| Oracle | DB2 9 | 注解 |
| 实例 | 实例 | 一个 DB2 实例可以包含多个数据库 |
| 数据库 | 数据库 | |
| initSID.ora 或 SPFILE | DBM CFG 和 DB CFG | DB2 使用两个级别的配置:Database Manager Configuration(DBM CFG)(实例级)和 Database Configuration(DB CFG)(数据库级)。与 Oracle 一样,很多配置参数可以动态更改 |
| 表空间 | 表空间 | DB2 支持 SMS 和 DMS 这两类表空间。DMS 表空间与 Oracle 的表空间类似 |
| 数据块 | 页 | DB2 支持以下几种页大小:4k、8k、16k 和 32k。一个行必须能够装入其中一种数据页内。它不能像在 Oracle 中那样跨多个页 |
| 盘区 | 盘区 | |
| 数据文件 | DMS 表空间容器 | 用于 DMS 表空间的容器可以是原始设备,也可以是文件 |
| 重做日志文件 | 事务日志文件 | |
| 数据缓冲区 | 缓冲池 | DB2 没有一组预定义的缓冲池,但是可以根据需要创建足够多的缓冲池。在创建具有给定页大小的表空间时,必须预先存在一个具有给定页宽的缓冲池 |
| SGA | 数据库管理器共享内存和数据库共享内存 | |
| 数据字典 | 编目 | |
| 库缓存 | 包缓存 | |
| 大型池 | 实用程序堆 | |
| 数据字典缓存 | 编目缓存 | |
| SYSTEM 表空间 | SYSCATSPACE 表空间 |
--end
