Ora-600的博客
===========================================================
硬解析带来高CPU消耗的诊断
===========================================================

客户的系统进行压力测试时发现CPU压力非常大,正常情况下CPU负载在30-40%,而峰值期间CPU基本上100%,以至于事务无法处理完成,甚至无法登陆。

经过客户的描述,这个压力测试实际上压力应该不大,仅仅设置了100个客户端的并发,而且单个客户端整个功能模块完成实际上仅需要25秒钟,但并发一多,CPU负载就非常高,以至于单个功能模块完成时间被延长至几百秒。

到客户现场,在操作系统级察看,CPU大量消耗在user上,ioCPU等待很少,确定CPU是消耗在应用层面。

[oracle@localhost ~]$ sar -u 3 50

Linux 2.6.18-92.el5 (localhost.localdomain) 20090615 _x86_64_ (8 CPU)

145650 CPU %user %nice %system %iowait %steal %idle

145653 all 93.29 0.00 1.08 0.00 0.00 5.62

145656 all 90.54 0.00 1.33 0.00 0.00 8.12

145659 all 93.00 0.00 1.08 0.00 0.00 5.93

145702 all 92.34 0.00 0.92 0.00 0.00 6.75

145705 all 93.25 0.00 0.87 0.00 0.00 5.88

145708 all 92.06 0.00 1.02 0.00 0.00 6.92

145711 all 91.95 0.00 0.87 0.00 0.00 7.18

145714 all 92.71 0.00 0.92 0.00 0.00 6.38

145717 all 92.19 0.00 0.87 0.00 0.00 6.94

145720 all 94.96 0.00 0.79 0.00 0.00 4.25

145723 all 92.91 0.00 0.83 0.00 0.00 6.26

145726 all 92.06 0.00 0.70 0.00 0.00 7.24

由于客户描述的情况中并发量与CPU消耗有直接关系,因此怀疑有应用级并发的竞争,于是收集了一下Statspack报告,在命中率方面:

Instance Efficiency Percentages (Target 100%)

Buffer Nowait %:

99.98

Redo NoWait %:

99.98

Buffer Hit %:

100.00

In-memory Sort %:

100.00

Library Hit %:

74.95

Soft Parse %:

72.85

Execute to Parse %:

0.27

Latch Hit %:

97.18

Parse CPU to Parse Elapsd %:

9.47

% Non-Parse CPU:

7.65

库高速缓存的命中率很低,硬解析很高,而硬解析与CPU消耗有直接关系。

在等待事件方面:

Top 5 Timed Events

Event

Waits

Time(s)

Avg Wait(ms)

% Total Call Time

Wait Class

latch: library cache

5,679,771

363,979

64

86.1

Concurrency

CPU time

41,658

9.9

latch: shared pool

1,908,510

6,061

3

1.4

Concurrency

latch free

192,585

5,334

28

1.3

Other

latch: cache buffers chains

19,228

823

43

.2

Concurrency

很明显,主要等待都集中在与库高速缓存相关的Latch竞争上,库高速缓存是主要的性能问题,而且硬解析也主要在消耗CPU,看来性能瓶颈已经表现出来了,通过下面会话级的直接查询,也发现在大量会话中同时都存在着latch: library cache 竞争:

select event from v$session_wait

where event not in ('SQL*Net message from client','rdbms ipc message')

EVENT

----------------------------------------------------------------

SQL*Net message to client

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: shared pool

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

latch: library cache

。。。。。。

smon timer

pmon timer

目前客户的共享池有544M,而在程序运行过程中共享池的剩余空间还有59M,同时从报告中的共享池大小建议上看,对于目前的应用来说,共享池只需要400M就足够,因此造成库高速缓存命中率低,硬解析高,CPU大量消耗的主要原因很可能是SQL代码没有共享。

Shared Pool Size(M)

SP Size Factr

Est LC Size (M)

Est LC Mem Obj

Est LC Time Saved (s)

Est LC Time Saved Factr

Est LC Load Time (s)

Est LC Load Time Factr

Est LC Mem Obj Hits

416

0.76

67

7,820

3,652

0.98

466,989

1.00

3,518,320

480

0.88

130

15,164

3,710

1.00

466,931

1.00

Ora-600 发表于:2009.06.16 14:25 ::分类: ( Oracle ) ::阅读:(540次) :: 评论 (0)
===========================================================
DBMS_SPACE包的使用(2)
===========================================================

CREATE_TABLE_COST有两种用法,因此包内进行了overload,具体的语法如下:
DBMS_SPACE.CREATE_TABLE_COST (
tablespace_name IN VARCHAR2,
avg_row_size IN NUMBER,
row_count IN NUMBER,
pct_free IN NUMBER,
used_bytes OUT NUMBER,
alloc_bytes OUT NUMBER);

DBMS_SPACE.CREATE_TABLE_COST (
tablespace_name IN VARCHAR2,
colinfos IN CREATE_TABLE_COST_COLUMNS,
row_count IN NUMBER,
pct_free IN NUMBER,
used_bytes OUT NUMBER,
alloc_bytes OUT NUMBER);

CREATE TYPE create_table_cost_colinfo IS OBJECT (
COL_TYPE VARCHAR(200),
COL_SIZE NUMBER);

下面是关于CREATE_TABLE_COST的测试代码:
1、测试创建一个表所需的存储大小,预计该表平均行长度为100字节,10000行数据
SQL> DECLARE
2 V1 NUMBER;
3 V2 NUMBER;
4 BEGIN
5 DBMS_SPACE.CREATE_TABLE_COST('USERS', 100, 10000, 10, V1, V2);
6 DBMS_OUTPUT.PUT_LINE('V1: '||V1/1024/8||' V2: '||V2/1024/8);
7 END;
8 /
V1: 143 V2: 256 --估算出该表需要存储空间143块,所需分配空间256块
PL/SQL 过程已成功完成。

2、创建该表,并插入10000行数据
SQL> CREATE TABLE T1(C CHAR(96)); --96字节的char字段平均行长度为100字节
表已创建。

SQL> BEGIN
2 FOR I IN 1..10000 LOOP
3 INSERT INTO T1 VALUES(I);
4 END LOOP;
5 COMMIT;
6 END;
7 /
PL/SQL 过程已成功完成。

3、分析表统计信息
SQL> ANALYZE TABLE T1 COMPUTE STATISTICS;
表已分析。

SQL> SELECT BLOCKS,EMPTY_BLOCKS,AVG_ROW_LEN
FROM USER_TABLES WHERE TABLE_NAME='T1';
BLOCKS EMPTY_BLOCKS AVG_ROW_LEN
---------- ------------ -----------
180 76 100
--经检查,高水平线之前的块数180块,高水平线之后的空块数76块,总存储空间为256块,与DBMS_SPACE.CREATE_INDEX_COST计算出的总需要存储空间大小相符。

4、通过dbms_space.space_usage过程,可以进一步看到表中各个块的使用情况
declare
unf number;
unfb number;
fs1 number;
fs1b number;
fs2 number;
fs2b number;
fs3 number;
fs3b number;
fs4 number;
fs4b number;
full number;
fullb number;
own dba_tables.owner%type;
tab dba_tables.table_name%type;
yesno varchar2(3);
type parts is table of dba_tab_partitions%rowtype;
partlist parts;
type cursor_ref is ref cursor;
c_cur cursor_ref;
begin
own:=upper('&owner');
tab:=upper('&table_name');
dbms_output.put_line('--------------------------------------------------------------------------------');
open c_cur for select partitioned from dba_tables
where owner=own and table_name=tab;
fetch c_cur into yesno;
close c_cur;
dbms_output.put_line('Owner: '||own);
dbms_output.put_line('Table: '||tab);
dbms_output.put_line('------------------------------------------------');
if yesno='NO' then
dbms_space.space_usage(own,tab,'TABLE',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,full,fullb);
dbms_output.put_line('unf: '||unf||' fs1: '||fs1||' fs2: '||fs2||' fs3: '||fs3||' fs4: '||fs4||' full: '||full);
else
open c_cur for select * from dba_tab_partitions
where table_owner=own and table_name=tab;
fetch c_cur bulk collect into partlist;
close c_cur;
for i in partlist.first .. partlist.last loop
dbms_space.space_usage(partlist(i).table_owner,partlist(i).table_name,'TABLE PARTITION',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,full,fullb,partlist(i).partition_name);
dbms_output.put_line('Partition: '||partlist(i).partition_name);
dbms_output.put_line('unf: '||unf||' fs1: '||fs1||' fs2: '||fs2||' fs3: '||fs3||' fs4: '||fs4||' full: '||full);
end loop;
end if;
dbms_output.put_line('--------------------------------------------------------------------------------');
end;
/

输入 owner 的值: HR
原值 22: own:=upper('&owner');
新值 22: own:=upper('HR');
输入 table_name 的值: T1
原值 23: tab:=upper('&table_name');
新值 23: tab:=upper('T1');
--------------------------------------------------------------------------------
Owner: HR
Table: T1
------------------------------------------------
unf: 0 fs1: 1 fs2: 0 fs3: 0 fs4: 39 full: 140
--------------------------------------------------------------------------------
PL/SQL 过程已成功完成。
--经查看,发现该表写满数据的块有140块,3/4满的块有39块,1/4满的块有1块,该表存储空间没有有效利用,可以看到140+39+1=180,这些均为高水平线之下的块。但与DBMS_SPACE.CREATE_INDEX_COST计算出的数据需要143块不符。

5、对表进行空间整理并重新分析
SQL> ALTER TABLE T1 MOVE;
表已更改。

SQL> ANALYZE TABLE T1 COMPUTE STATISTICS;
表已分析。

SQL> SELECT BLOCKS,EMPTY_BLOCKS,AVG_ROW_LEN
FROM USER_TABLES WHERE TABLE_NAME='T1';
BLOCKS EMPTY_BLOCKS AVG_ROW_LEN
---------- ------------ -----------
155 101 100
--经检查,高水平线之前的块数155,高水平线之后的空块数101,平均行长度100字节

6、通过dbms_space.space_usage过程,可以进一步看到表中各个块的使用情况
declare
unf number;
unfb number;
fs1 number;
fs1b number;
fs2 number;
fs2b number;
fs3 number;
fs3b number;
fs4 number;
fs4b number;
full number;
fullb number;
own dba_tables.owner%type;
tab dba_tables.table_name%type;
yesno varchar2(3);
type parts is table of dba_tab_partitions%rowtype;
partlist parts;
type cursor_ref is ref cursor;
c_cur cursor_ref;
begin
own:=upper('&owner');
tab:=upper('&table_name');
dbms_output.put_line('--------------------------------------------------------------------------------');
open c_cur for select partitioned from dba_tables
where owner=own and table_name=tab;
fetch c_cur into yesno;
close c_cur;
dbms_output.put_line('Owner: '||own);
dbms_output.put_line('Table: '||tab);
dbms_output.put_line('------------------------------------------------');
if yesno='NO' then
dbms_space.space_usage(own,tab,'TABLE',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,full,fullb);
dbms_output.put_line('unf: '||unf||' fs1: '||fs1||' fs2: '||fs2||' fs3: '||fs3||' fs4: '||fs4||' full: '||full);
else
open c_cur for select * from dba_tab_partitions
where table_owner=own and table_name=tab;
fetch c_cur bulk collect into partlist;
close c_cur;
for i in partlist.first .. partlist.last loop
dbms_space.space_usage(partlist(i).table_owner,partlist(i).table_name,'TABLE PARTITION',unf,unfb,fs1,fs1b,fs2,fs2b,fs3,fs3b,fs4,fs4b,full,fullb,partlist(i).partition_name);
dbms_output.put_line('Partition: '||partlist(i).partition_name);
dbms_output.put_line('unf: '||unf||' fs1: '||fs1||' fs2: '||fs2||' fs3: '||fs3||' fs4: '||fs4||' full: '||full);
end loop;
end if;
dbms_output.put_line('--------------------------------------------------------------------------------');
end;
/
输入 owner 的值: HR
原值 22: own:=upper('&owner');
新值 22: own:=upper('HR');
输入 table_name 的值: T1
原值 23: tab:=upper('&table_name');
新值 23: tab:=upper('T1');
--------------------------------------------------------------------------------
Owner: HR
Table: T1
------------------------------------------------
unf: 0 fs1: 0 fs2: 0 fs3: 0 fs4: 0 full: 143
--------------------------------------------------------------------------------
PL/SQL 过程已成功完成。
--经查看,发现该表写满数据的块有143块,与DBMS_SPACE.CREATE_INDEX_COST计算出的数据需要块数完全相同


-- review the parameters
SELECT argument_name, data_type, type_owner, type_name
FROM all_arguments
WHERE object_name = 'CREATE_TABLE_COST'
AND overload = 2

-- examine the input parameter type
SELECT text
FROM dba_source
WHERE name = 'CREATE_TABLE_COST_COLUMNS';

-- drill down further into the input parameter type
SELECT text
FROM dba_source
WHERE name = 'create_table_cost_colinfo';

set serveroutput on
DECLARE
ub NUMBER;
ab NUMBER;
cl sys.create_table_cost_columns;
BEGIN
cl := sys.create_table_cost_columns( sys.create_table_cost_colinfo('NUMBER',10),
sys.create_table_cost_colinfo('VARCHAR2',30),
sys.create_table_cost_colinfo('VARCHAR2',30),
sys.create_table_cost_colinfo('DATE',NULL));
DBMS_SPACE.CREATE_TABLE_COST('SYSTEM',cl,100000,0,ub,ab);
DBMS_OUTPUT.PUT_LINE('Used Bytes: ' || TO_CHAR(ub));
DBMS_OUTPUT.PUT_LINE('Alloc Bytes: ' || TO_CHAR(ab));
END;
/


Ora-600 发表于:2009.04.29 22:51 ::分类: ( Oracle ) ::阅读:(548次) :: 评论 (0)
===========================================================
DBMS_SPACE包的使用(1)
===========================================================

最近有朋友问到了DBMS_SPACE包的使用,也看了一下,大部分是关于dbms_space.space_usage的使用,space_usage这个过程的例子已经很多了,我也就不再多说了,除了这个过程外,另外还有两个过程也有着特殊的用处,但使用的人不多,我们也来看看这两个过程有什么用。
这两个过程为:CREATE_INDEX_COST和CREATE_TABLE_COST,分别用户评估创建索引和创建表的存储开销(空间占用情况)。

CREATE_INDEX_COST的语法如下:
DBMS_SPACE.CREATE_INDEX_COST (
ddl IN VARCHAR2,
used_bytes OUT NUMBER,
alloc_bytes OUT NUMBER,
plan_table IN VARCHAR2 DEFAULT NULL);

下面是相关的测试代码:
1、准备相关表和数据
SQL> set serveroutput on
SQL> create table t(c char(100),d varchar2(200));
表已创建。

SQL> begin
2 for i in 1..5000 loop
3 insert into t values(i,i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 过程已成功完成。

2、分析表,注意:没有统计信息,CREATE_INDEX_COST将无法计算索引的存储开销
SQL> analyze table t compute statistics;
表已分析。

SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(c)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
488.28125 640 --计算出的索引将占用488K字节空间,为该索引需要分配640k存储空间
PL/SQL 过程已成功完成。

3、创建实际索引,确定索引存储空间是否与计算的结果相符
SQL> create index i on t(c);
索引已创建。

SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
11
已选择1行。 --11个64k的区,比计算出的大1个区

4、再次装载数据
SQL> begin
2 for i in 1..5000 loop
3 insert into t values(i,i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 过程已成功完成。

SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(c)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
488.28125 640 --没有分析之前,获得得仍然是根据以前分析结果计算的值
PL/SQL 过程已成功完成。

SQL> analyze table t compute statistics;
表已分析。

SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(c)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
976.5625 2048 --分析之后,得到新的结果
PL/SQL 过程已成功完成。

5、再次验证,16个64k的区和1个1024k的区,2048k,与估计值相同
SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
17

-------------------------------------------------------------
6、换了一个字段进行测试
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(d)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
39.0625 192 --计算出的索引将占用39K字节空间,为该索引需要分配192k存储空间
PL/SQL 过程已成功完成。

7、创建索引,新建的索引比估算的值大1个区
SQL> create index i on t(d);
索引已创建。

SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
4

SQL> drop index i;

8、再次装载数据并分析表
SQL> begin
2 for i in 1..10000 loop
3 insert into t values(i,i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 过程已成功完成。

SQL> analyze table t compute statistics;
表已分析。

9、重新计算,得到新的估算值
SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(d)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
78.125 320

PL/SQL 过程已成功完成。

10、创建索引,新建的索引比估计的大2个区
SQL> create index i on t(d);
索引已创建。

SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
7

11、顺便测试shink space的效果
SQL> select count(*) from t;
COUNT(*)
----------
20000

SQL> delete t where rownum<=15000;
已删除15000行。

SQL> commit;
提交完成。

SQL> alter table t enable row movement;
表已更改。

12、在删掉15000行数据后,没有整理空间之前进行统计信息收集
SQL> analyze table t compute statistics;
表已分析。

SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(d)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
24.4140625 128 --基于新收集的统计信息计算,估算的索引需要分配128k存储空间
PL/SQL 过程已成功完成。

13、收缩表,释放占用的存储空间
SQL> alter table t shrink space;
表已更改。

SQL> analyze table t compute statistics;
表已分析。

SQL> declare
2 v1 number;
3 v2 number;
4 begin
5 DBMS_SPACE.CREATE_INDEX_COST('create index i on t(d)',v1,v2);
6 dbms_output.put_line(v1/1024||' '||v2/1024);
7 end;
8 /
24.4140625 128 --收缩后重新收集统计信息,与原统计信息一样,因此计算出的大小一样
PL/SQL 过程已成功完成。

SQL> select count(*) from user_extents where segment_name='I';
COUNT(*)
----------
7
--现有索引并没有收缩,仅仅是表空间进行了收缩,因此现有索引仍保持原大小

14、重建索引,对比新的索引大小与计算出的索引大小一样大
SQL> alter index i rebuild;
索引已更改。

SQL> select count(*) from user_extents where segment_name='I';

COUNT(*)
----------
2
--重建索引后新的索引占用空间与计算出的空间一样大


Ora-600 发表于:2009.04.28 00:00 ::分类: ( Oracle ) ::阅读:(467次) :: 评论 (0)
===========================================================
Oracle收购sun,一次大鱼吃大鱼的表演
===========================================================
4月20日晚19时40分消息,SUN终于卖了出去,但是买家不是IBM,而是IBM最大的竞争对手之一、全球最大的数据库软件商Oracle公司。
收到这条消息已经是晚上10点,在告知其他几个朋友的时候,朋友说他们早就知道啦,看来我还是后知后觉阿。
最近IT业好像很繁忙的样子,尤其是Oracle的老larry,就没见消停的,去年大手笔收购了BEA,感觉才有点点尘埃落地的意思,就突然冒出了这么个消息,而且还不像IBM,只是传出个要收购SUN的消息,Oracle直接发布的就是收购成功消息,看来larry不是一般的强势阿。IBM之前才传出60多亿要收购sun,紧接着就冒出个谈判破裂的传闻,然后又以迅雷不及掩耳之势出现了Oracle成功收购SUN的消息,看来还是Oracle比较牛,不像IBM那么玩虚的,要收购,直接就一把搞定。当然了,想想看,本来IBM就有自己全套的软硬件体系,收购SUN只不过减少个对手,实际上对自身实力的提高并没有太大帮助,毕竟IBM和SUN在软硬件方面重叠的太多,有很多冲突,而Oracle跟SUN的合并,则能够更大的增强自身的实力,体现出收购的价值所在。
SUN,日不落的王国,终于跟桀骜不驯的老牛仔larry搞到了一起,准确地说,应该是老larry终于搞上了日不落。
前两天IBM宣称要收购SUN的时候,我还觉得很奇怪,因为IBM收购SUN的意义不大,所以跟哥们还开玩笑的说,要说收购,Oracle收购SUN还差不多,起码从很早以前他们就是很好的合作伙伴,只不过SUN还是太侧重于技术,市场做的不怎么样,反而让HP和Intel后来居上,现在跟Oracle合作更多的是HP、DELL、Intel。我哥们直接就说,这样看来,说不定IBM收购SUN,Oracle收购HP或者DELL,这样才能抗衡。对此,我不置可否,我心中还是希望Oracle能够跟SUN站在一起,而不是对立,呵呵,结果今天得到了这样的消息,看来还真有点心想事成的意思。
在评价此次交易时,甲骨文公司首席执行官拉里·埃里森(Larry Ellison)表示:“此次对Sun的收购,将在一定程度上改变IT业的现有格局,因为此次交易意味着,一个一流的软件公司与一家高端计算机公司实现了完美的结合。”
呵呵,老larry还是那么牛X,野心很大啊。当然了,Oracle与SUN的结合不会那么快,也不会那么完美,毕竟SUN有大量的软件与Oracle是有重叠的,而且之前Oracle正在与HP、Intel紧密合作,并且刚刚推出了Exadata及HP Oracle Database Machine计划,Oracle与SUN平台的完美融合也需要一段时间的磨合,一切的一切都刚刚开始,只不过这个开端看上去还是有着很美好前景的,那就让我们拭目以待了。
另外,Oracle在行业用户内广泛使用,同时目前用户量最大的互联网应用又在广泛使用MYSQL数据库,从高端到低端,从传统行业应用到互联网平台,从企业应用级到开源数据库,Oracle与MYSQL有机的结合,将更大程度的满足各种用户的需求,DB老大的地位将更加无法撼动。同时,SUN的主机曾经也逐波战场,与IBM、HP共同在高端服务器市场争战,如果真的被IBM收购了,就此黯然退出,必然成为一大遗憾,而被Oracle收购后,有软有硬,软硬结合,Oracle和SUN将能走得更远,再一次征战沙场。到时候,老larry左手持Oracle DB、BEA Weblogic大剑,右手举Solaris巨盾,长啸九天,堪与IBM蓝色巨人一争天下。
Ora-600 发表于:2009.04.23 23:41 ::分类: ( Oracle ) ::阅读:(365次) :: 评论 (0)
===========================================================
数据库restore时遇到1119错误
===========================================================

今夜天高云淡,夜色迷人,正跟LP在餐馆吃饭,没事聊聊天,忽然电话响起,美好画面就此打破。。。
客户紧急求助,让我立马赶赴现场解决故障,没法,跟LP致歉,然后飞奔出去,打着飞的就奔赴现场。
故障情况如下:客户主服务器重大故障,盘阵损坏,暂时无法使用或者修复,不过磁带机上有Rman备份,因此选择了一台备用机进行修复,服务器为AIX4.3,Oracle为10g,单机,所有备份归档都有(这就放心了)。。。
客户在做恢复时报错(一颗心立马揪了起来。。。不会备份的文件有问题吧),错误代码为ORA-01119和ORA-27040,也就是说,在restore文件到新服务器存储的时候报错,无法restore备份。
感到客户现场,气氛有点紧张,呵呵,原来客户领导也在,这不给咱压力嘛。
开始了解详细的用户操作步骤,从描述上看,备机与原服务器的os版本相同,补丁也都打完全了,数据库版本也一致,存储空间和目录也都与原来一样,用户将磁带机连好后,将初始化参数文件复制到相应位置,创建了口令文件,nomount数据库后,通过rman将控制文件restore到相应的目录中,mount数据库后开始restore数据文件,在数据文件restore到一个undo表空间的文件时报错。
听上去好像用户也没有任何操作错误,检查了一下,确实备机与主机环境基本上一样,为什么会报ORA-01119和ORA-27040错误呢?还是先亲自试试看吧。
在mount状态下,我开始逐一测试restore文件,结果发现,并不是所有的数据文件都不能restore,有些可以正常restore出来,但有些数据文件不行,而且发现了一个很明显的现象,不能restore出来的文件一般都比较大。
分析ORA-01119和ORA-27040错误原因,一般来说主要是存储空间不够,没有目录操作权限之类,但如果是这种原因,那应该在相应目录下所有文件都不能创建,但现在的情况是大文件创建不行,小文件没问题。。。说到这里,可能大部分人都猜到了——对地,就是大文件的问题。。。这也算是经典问题了,很多平台都有,这次是aix,上次我还遇到过在hp unix上。
经过检查,发现备机上确实没有调整文件大小限制,需要进行调整。在aix上影响文件大小限制的主要有两个地方,一个是文件系统类型本身,需要使用large file enable filesystem,例如如果使用jfs2系统,默认就支持大文件;另一个是os上一个核心参数的设置。
可以使用下面的方法取消文件大小限制:
找到 /etc/security/limits文件,把fszie改为-1,-1表示文件大小无限制(当然也可以设置为有限制,如果限制为4GB,可以将fszie设置为 4GB/512 的值),在设置后重新连接会话,设置生效。
找到问题原因了,自然后面的restore、recover就没问题了,该故障解决完成,我还来得及继续回家跟LP欣赏夜景去。。。


注意:Oracle的有些文件需要注意这个问题,如果用到这些文件,最好将文件大小设置为无限制,主要要关注的文件有:
1、数据文件(设置了自动扩展,一般可以扩展到8gb-128GB,大文件表空间的数据文件可以扩展到128TB)
2、告警和trace文件,尤其是一些bug或者异常产生的trace文件
3、Rman备份文件
4、exp或者expdp的导出文件


Ora-600 发表于:2009.04.22 16:41 ::分类: ( Oracle ) ::阅读:(362次) :: 评论 (0)
===========================================================
终于拿到ACE的衣服了
===========================================================
早上就接到个电话,说是美国的快件,问我送到哪里,有点紧张的告诉快递公司我的地址,放下电话就开始琢磨,美国。。。。谁给我快递东西了。。。。难道是。。。。她。。。。不可能不可能。。。
中午吃饭,又收到电话,DHL送的快递,说快到了,突然一个机灵,想起来会不会是上次Oracle的ACE发东西了,可是寄个衣服还需要从美国寄过来,成本高了点吧,还是有点犹豫。。。
收到东西,果然是美国。。。。的Oracle寄来的,一个挺大挺扁的盒子,看上去应该是衣服了,打开一看,果然,好像是抓绒的衣服,夏天是不能穿的了,不然非得被送进安定医院去,质量还不错,看来秋天有新衣服穿了,另外,还有个玻璃牌牌,跟pub发的差不多,好像质量比pub的那个好点。。。
LP看到后说了一句,我们家狗狗小便缺少个立柱,这个不错。。。。倒
Ora-600 发表于:2008.08.01 16:46 ::分类: ( Oracle ) ::阅读:(2881次) :: 评论 (1)
===========================================================
undo offline,一个不大不小的故障
===========================================================

周末,夜,放松了一天,周末的夜晚无所事事,本打算吃完了看看片,看完了睡睡觉,晃晃悠悠过周末。时近晚上10点,突然接到一个客户电话,一看号码,心说这可不好,肯定出问题了,希望不是大事。。。
电话里,客户看样子还挺着急,原来是数据库起不来了,不过听上去问题不算太严重。客户下午本来要换UPS,结果正在备份呢,突然停电,这还没换掉的UPS再加上停电,结果服务器带存储一起就咔嚓了,等来电了把服务器都起来,结果发现,服务器上的三个库,其中有一个起不来了,故障呢,是open数据库的时候出现了SQL递归调用失败,访问undo表空间的文件有问题了。客户环境是9i rac,文件存储在raw上,有备份、有归档(一听这个就放心了,哈哈)。
开始远程电话指导,首先mount数据库,查询v$recover_file,发现2号文件和12号文件在里面出现,并且这两个文件状态都为offline,而且error字段为空。然后查询v$datafile和v$tablespace,发现这两个文件分别是undo表空间和另一个用户数据表空间的。既然刚才看到error字段为空,那应该是介质还在,但文件不一致拉,所以让客户直接recover datafile,再查询v$recover_file,发现里面已经没有任何信息了,这就说明文件的介质恢复已经完成了,那就打开数据库吧。
本以为接下来用户打开数据库,然后在电话里向我表达一下谢意,俺就可以挂了电话睡觉去了,结果没想到,用户open数据库的时候还是出了同样的错误,数据库仍然没有打开! 奇怪了。。。难道存储有问题了? 跟客户确认了一下,emc的存储厂商说存储没有问题,操作系统也没有做任何改动。。。奇怪,算了,先不想那么多,反正有备份嘛。于是我让客户把主机整个重起,然后用备份再作一次恢复。。。半小时后,电话再次响起,客户的声音有点颤抖,说道,还是出现了刚才的错误。。。晕
我心里也有点紧张了,这可奇怪了,不会半夜把我搞过去给他们现场解决吧,而且从现象上看,也跟正常恢复的情况有些不一样啊,问题出在哪儿了呢。。。。。。抓了抓头皮,点了一下鼠标,让手中正在打的游戏暂停。。。突然,一个想法出现在脑子里,靠,一个基本的常识性问题忘了,其实根本就不需要恢复!
什么问题呢,很简单,在讲表空间状态的时候,我们一般都会强调有些表空间是不能offline的,其中就包含了在用undo表空间,那么刚才已经在v$recover_file查看到了2号(undo表空间的文件)文件的状态正好是offline的,虽然随着日志的应用,2号和12号文件已经不出现在v$recover_file里了,但他们offline的状态并没有改阿! 赶紧让用户再查询一下v$datafile,发现果然状态都是offline的,出了口大气,原来是这么个小问题在作怪,让客户把2号和12号文件都online了,然后直接open数据库,ok了。。。果然听到客户接下来一连串的感谢之声,呵呵,问题搞定。
现实中很多问题看似复杂,其实就是我们最基础的知识,对这些知识的消化吸收和灵活运用,才能够在出现问题的时候在最短的时间内确定清晰可行的解决方法,所以,基础真是很重要。


Ora-600 发表于:2008.07.13 21:08 ::分类: ( Oracle ) ::阅读:(1452次) :: 评论 (1)
===========================================================
10g isqlplus dba登录配置
===========================================================

从oracle9i开始,oracle提供了web方式的sqlplus界面,通过isqlplus,用户可以不需要安装任何oracle客户端,就能够通过浏览器方式的sqlplus进行数据操作与数据库管理。普通的数据库用户可以直接通过isqlplus的网址http://ip:port/isqlplus登陆,进入该网址后会直接进入数据库用户登陆界面,使用数据库中的普通用户即可登陆;但如果是DBA用户登陆isqlpus,则需要首先配置isqlplus dba的用户和口令,然后输入网址http://ip:port/isqlplus/dba,进入该网址后首先会弹出一个登陆框,要求先输入iSQL*Plus DBA的用户和密码,注意这里不是数据库用户,而是isqlplus应用服务器要求的用户和密码,也就是前面配置的isqlplus dba的用户名和口令,然后才能出现isqlplus登陆界面,此时可以输入sys或者system用户,登陆数据库进行管理。
要以DBA身份登陆isqlplus,必须先配置好oc4j用户。oc4j可以使用两种身份认证方式:基于xml配置文件(jazn-data.xml) 或者基于LDAP(Oracle Internet Directory) 。通常采用xml配置文件认证的方式较多,这种方式使用的该配置文件位于$ORACLE_HOME/oc4j/j2ee/isqlplus/application-deployments/isqlplus/config,但是该配置文件中的密码是加密过的,所以无法手动修改该文件,配置用户密码需要通过JAZN(Java AuthoriZatioN)来配置,JAZN是oracle提供的一个JASS(Java Authentication and Authorization Service)工具。
通过JAZN,可以完成以下任务:Create user / List user / Grant the webDba role / Remove users / Revoke the webDba role / Change user passwords
上述任务既可以先进入JAZN命令环境后再执行,也可以直接直接在命令行中实现。

下面是Oracle 10g上配置isqlplus dba的方法,注意unix和windows上稍有不同。
unix:
$ isqlplusctl stop
$ JAVA_HOME=$ORACLE_HOME/jdk
$ export JAVA_HOME
$ cd $ORACLE_HOME/oc4j/j2ee/isqlplus/application-deployments/isqlplus
$ $JAVA_HOME/bin/java Djava.security.properties=$ORACLE_HOME/oc4j/j2ee/home/config/jazn.security.props -jar $ORACLE_HOME/oc4j/j2ee/home/jazn.jar -user "iSQL*Plus DBA/admin" -
password welcome –shell
JAZN:> adduser "iSQL*Plus DBA" oracle oracle
JAZN:> grantrole webDba "iSQL*Plus DBA" oracle
JAZN:> exit
$ isqlplusctl start

windows:
set ORACLE_HOME=...
set JAVA_HOME=%ORACLE_HOME%/jdk
cd %ORACLE_HOME%/oc4j/j2ee/isqlplus/application-deployments/isqlplus
%JAVA_HOME%/bin/java Djava.security.properties=%ORACLE_HOME%/oc4j/j2ee/home/config/jazn.security.props -jar %ORACLE_HOME%/oc4j/j2ee/home/jazn.jar -user "iSQL*Plus DBA/admin" -
password welcome –shell


注意:
1、admin虽然是默认的管理员,但初始并没有真正被授权
2、必须在$ORACLE_HOME/oc4j/j2ee/isqlplus/application-deployments/isqlplus目录中执行命令,否则会出现下面的错误:
oracle.security.jazn.JAZNRuntimeException: Configuration file "configjazn.xml" does not exist. Check your JAAS configuration settings.
或者
Realm [iSQL*Plus DBA] does not exist in system.
3、在windows中注意目录的书写,不能使用'',而要像unix一样使用'/'
4、iSQL*Plus DBA的默认管理员admin的默认口令是 'welcome',为了安全起见,最好修改口令


Ora-600 发表于:2008.06.14 23:30 ::分类: ( Oracle ) ::阅读:(2352次) :: 评论 (0)
===========================================================
最近病了,该歇歇了
===========================================================

一直在高强度的运转,突然停下来休息,非常不适应,因此,病了。

从初期的身体有点发冷,到后来喉咙痛,眼睛痛,头痛,现在还能动,不过非常的没有精神,看来忙得过度了,也是会得病的。

还好,还年轻,熬过这几天,继续为了oracle的事业而奋斗。


Ora-600 发表于:2008.06.04 20:14 ::分类: ( Oracle ) ::阅读:(465次) :: 评论 (0)
===========================================================
数据块的空间参数
===========================================================
最近正好有朋友问起了块空间参数对性能的影响,简单写了几句,记录一下。 db_block_size是数据块的大小,也是数据库I/O的最小大小,对数据访问时的I/O性能影响大,而且创建好数据库后就不能修改了,所以最好在创建数据库之前确定 好,通常建议尽量使用较大的块,另外,块的大小也跟经常执行的并发事务数有关,过大的块也可能出现热点块竞争。对数据块的考虑通常从下面这几个方面考虑: 1、对查询来说数据块要足够大以减少I/O 2、对查询来说尽可能在块中放入更多的数据以减少I/O 3、对查询来说尽可能数据在最少的块中得到(减少行链、行迁移) 4、对DML操作来说应该减少并发事务带来的块头竞争这几点分别对应着块大小的初始化参数和数据块上设置的空间参数,块的空间参数主要有四个:INITRANS,MAXTRANS,PCTFREE,PCTUSED,下面列出了这四个空间 参数的含义以及对性能的影响: initrans是块头的初始事务槽数,每一个访问块的事务都必须首先获得数据块头的一个事务槽,所以如果块中数据的并发事务多,那么就需要准备更多的事务槽。如 果初始事务槽太小,那么在需要的时候就会动态扩展,动态扩展会导致事务槽等待分配,降低DML的速度;但是如果事务槽太大,没有那么多的并发事务,那么会浪 费块的空间,使块中的可用空间降低,块中容纳的行数减少,那么在查询数据时需要访问更多的块,增加了I/O,也会降低性能。所以设置的initrans应该能够满足 正常业务的需求,也就是与并发事务相关。 maxtrans是在事务槽不够的情况下,最大可以扩展的事务槽数。如果不够大,无法扩展,需要事务槽的事务则等待。 pctfree决定了为update保留的空间百分比,如果太小会产生大量的行迁移,造成单行的访问不得不读取多个块,做无谓的I/O;如果太大会造成空间浪费,一个块只 能容纳少量的数据,就需要更多的块存放数据,全表扫描和索引访问将需要扫描更多的数据块。 pctused决定了数据块合适回到可用状态。可用的块就是可以执行插入的块,不可用状态的块则只能执行删除和修改,所有处于可用状态的块被放 在freelist中,freelist是存放在段头的一个数据结构。pctused不能和pctfree离得太近,如果两个标记太紧的话,也就意味和pctused设置太大,例 如pctfree=20,pctused=75,两个只相差5%,这时候如果在块中发生大量的数据删除和插入时,数据块的状态可能会发生非常频繁的更改,而块状态被纪录 在freelist中,块被频繁的从freelist中插入和删除,会造成freelist的争用。当然,如果pctused设置太小,会使块长时间处于不可用状态,也就意味着这个块的 空闲空间无法使用,造成空间浪费,I/O的增多。所以这些空间参数的设置对数据块的访问性能有很大的关系,必须仔细设置这些参数。顺便说一句,如果段所在的表空间已经是ASSM(自动段空间管理)表空间了, 那么PCTFREE和PCTUSED这两个参数将不再被使用,块状态由数据库自动进行管理。
Ora-600 发表于:2008.05.30 00:02 ::分类: ( Oracle ) ::阅读:(466次) :: 评论 (0)
===========================================================
今天,你捐了吗
===========================================================

我捐了,捐的不多,1000元,但这是第一次,以后,还会有第二次,第三次,第四次。。。。

每天打开电视,看得第一个节目,就是地震灾区的救灾直播,打开电脑,关注的第一个页面,就是地震救灾中又救了多少人,与朋友的聊天,第一句话,就是,你捐了了嘛。。。

看着灾区那么多受灾的人,尤其是那一个个受伤的孩子,废墟中伸出的一双双手,心很难受。。。

捐吧,捐了的钱我们还能挣,而这些钱对于灾区的人民,也许就是他们温饱的饭,避寒的衣,挡雨的伞,或者是减少他们痛苦的药,对于生命和享受,你还有什么可选择的,捐。。。

震灾晚会在进行着,人们都在捐款,钱越来越多,灾区的人民生存的希望也就越大,看着那些画面,泪满了眼。。。


Ora-600 发表于:2008.05.18 21:48 ::分类: ( 随笔 ) ::阅读:(426次) :: 评论 (0)
===========================================================
又是一次惨痛的天灾
===========================================================

这两天最关心的莫过于数字——一个大地震的伤亡数字,一个在不断递增,不断在人们心上、身上刻着、刺着、划着,带来巨大伤痛的数字,从7000到8000多,到11000多,现在,已经12000多,而从报道的情况看,可能还会有更多,也许是2万,或者。。。
看着心疼,尤其是看到那些照片,原本还天真活泼的孩子,没有了可爱的笑容,只剩下一本书放在脸上,遮盖着已经没有任何生气地脸,而那些父母,哭天喊地的悲痛欲绝,这不是人间惨剧,还是什么。为什么倒塌了那么多学校,为什么伤亡了那么多孩子,为什么这么大的地震居然一点前期预报都没有,只剩下心疼地感觉,慢慢的心痛的都麻木了。。。
早上翻看着报纸,一篇篇的报道,一串串的数字,当看到无数的企业、组织、个人都在捐款,无数的人在组织者捐血捐钱捐物,无数的人群在关心着这个事件,眼眶不禁的湿了,虽然还没有哭出来,但心已经感动。灾难中,我们更需要同心。。。


Ora-600 发表于:2008.05.14 13:36 ::分类: ( 随笔 ) ::阅读:(398次) :: 评论 (0)
===========================================================
大地震
===========================================================

今天,最大的事情看来就是地震了
正在上网,一个消息从朋友的MSN发了过来,说西安地震了,而且在震中,让我赶紧跟家里联系一下。。。开始并没有太在意,在网上看了一下,震中不是在西安,而是在四川汶川县,不过地震等级确实挺高的。想了想,四川离西安还是有一定距离的,应该没事。
没过多久,突然发现几乎所有的QQ群里都出现了大量的地震信息,北京地震。。。重庆地震。。。杭州地震。。。山西地震。。。连大老远的上海都有地震了,靠,那西安肯定也会震阿,赶紧打个电话吧。
这一打不要紧,结果我们家3个手机没一个能打通的,从3点多一直打到5点,这可急死我了,也没啥心情干活了,着急啊,还好从西安的朋友口中得到消息,西安那边震得并不严重,应该没什么问题。。。
网上看到消息,2008年05月12日14时28分04.0秒,在四川汶川县发生M7.8级地震,震中位于北纬31.0度,东经103.4度。12日14时35分左右,北京、上海等地区明显感觉到有地震发生。
5点15分,终于打通了电话,全家没有任何问题,仅仅是西安市移动、联通的线路全忙,无法拨通,连市内自己也无法拨打电话,看来这次虽然人员损失不大,但整体影响还是非常夸张的。
今年看,真是个大灾年阿,希望全家人都平平安安,也希望朋友们都一切顺利,这样的灾难最好别发生了,老天保佑。


Ora-600 发表于:2008.05.12 20:22 ::分类: ( 随笔 ) ::阅读:(474次) :: 评论 (1)
===========================================================
迁移long类型对象
===========================================================

在帮客户进行数据库巡检时发现,客户的库是从8i升级到9i的,因此,很多表空间仍然使用了原有的字典管理表空间模式,而这种模式的空间管理性能很差,因此建议客户将这些表空间全部换成本地管理的表空间,经过沟通,客户也认可此建议,因此,今晚开始实施。
实施之前,对整个数据库进行了备份,这是传统,也是本能(希望以后做dba的朋友们也能养成这样的习惯,当然,这次的备份倒是没派上什么用处)
丢弃字典管理表空间换成本地管理倒也不难,新创建本地管理表空间,然后把原来字典管理表空间上的存储对象移动过来就是了,对于表可以使用move,对于索引可以使用rebuild。
一切都很顺利,直到遇到了long类型字段。在move一个table时遇到了一个错误,这个表包含了long类型字段,因此无法直接move到新的位置,此时的处理方式大概有下面几个:
1、如果表中没有数据,呵呵,最简单的情况,可以直接将该表的定义用dbms_metadata.get_ddl取出,然后将表删除,修改刚才取出的ddl语句中的表空间名称定义,然后重新创建表在新的表空间上即可。当然,有数据这样作就不一定合适了
2、用exp导出,然后将原表删除,创建表到本地管理表空间上,然后导入数据,在导入的时候使用选项ignore=y(因为表已经存在)
也可以在导入之前将用户的默认表空间指向新的本地管理表空间,并且将原字典管理表空间的quota设置为0,导入也会将表生成在新的表空间上
3、在新表空间上创建出新表,使用sqlplus中的copy命令将原表数据插入新表,然后删除原表,再将新表名改为原表名(当然表上相关的索引、约束、触发器的定义要事先保存好,以便重建)。例如:
SQL> create table test(c1 varchar2(20),c2 long);

表已创建。

SQL> insert into test values('abc','abc');

已创建 1 行。

SQL> commit;

提交完成。

SQL> create table test1
2 as
3 select * from test;
select * from test
*
ERROR 位于第 3 行:
ORA-00997: 非法使用 LONG 数据类型

SQL> create table test1
2 (c1 varchar2(20),c2 long)
3 tablespace users;

SQL> copy from hr/hr@ora9i INSERT test1 using select * from test;

数组读取/结合的大小为15。(数组大小为15)
将在完成时提交。(提交的复本为 0)
最长为80。(长度为80)
1行选自
hr@ora9i
1行被插入TEST1。
1行已提交至TEST1(位于DEFAULT HOST连接)。

SQL> drop table test;

表已丢弃。

SQL> rename test1 to test;

表已重命名。

4、将long类型数据修改为lob类型(Oracle也建议以后用lob取代long,但需要考虑对应用是否有影响),然后再执行move
SQL> alter table test move tablespace users;
alter table test move tablespace users
*
ERROR 位于第 1 行:
ORA-00997: 非法使用 LONG 数据类型

SQL> alter table test modify(c2 clob);

表已更改。
SQL> create table test2
2 as
3 select * from test;

表已创建。
SQL> alter table test move tablespace users;

表已更改。


Ora-600 发表于:2008.05.11 14:34 ::分类: ( Oracle ) ::阅读:(1208次) :: 评论 (0)
===========================================================
飞机安检严格之后,近期遇到的特殊待遇。。。
===========================================================
北京飞上海,特意没带刀具,没带打火机,没带易燃易爆危险品,枪也没带,连洗漱用品都基本省略,就带了毛巾、牙刷、牙膏(80毫升),离京没事,一切顺利。上海虹桥被要求放弃牙膏,理由:疑似危险品。。。旁边mm携带数瓶洗面奶、擦脸油之类,被放行,问官之,官曰:洗漱用品小于100毫升可带,牙膏无论多少毫升,不可带! 靠,后来一捉摸,估计牙膏类似塑胶炸药了

北京飞南京,这次牙膏也不带了,带了空水瓶,这样过了安检还可以接点水喝,登机无碍,一切顺利。 南京机场,临安检前特意大灌了几口水,应把瓶子水放空,刚灌爆肚子,旁边机场地勤mm过来说了一句话,请把瓶子抛弃。。。我很疑惑的问了一句,空瓶子也不能带吗。。。mm很蔑视的看了我一眼,就挤出两个字:当然。。。晕倒,我又很不好意思地低声问了一句。。。那我要渴了怎么办,人家很不情愿的说了一句,我们里面给你们准备水了,进去就能喝。。。。。。你说我还能说什么。。。。。。可问题是,我丢了水瓶,过了安检,进去找了半天,果然有水。。。不过没有水杯
Ora-600 发表于:2008.05.08 09:59 ::分类: ( 随笔 ) ::阅读:(1070次) :: 评论 (2)
切换风格
新闻聚合
博客日历
文章归档...
最新发表...
博客统计...
网站链接...