遇到oracle错误6550。MAZ,读书心得—《深入解析Oracle》(一)

他很喜欢从多个版本说问题,从技术演进角度来学比较有效,但他喜欢在老版本上重演bug来分析,这比较扯蛋,就像在win2000上分析windows漏洞一样,感觉像在自娱自乐。

不知道他从什么资料上学的到的这么细致。外文资料吗,如果是,应该有引进。oracle有意隐藏这些内部的实现过程,所以市面上见不到这样的书。作者自己捉摸出来的吗,一些东西其他书上完全没有涉及到过

,用了很多奇妙的方法去窥探数据库的内部,研究的非常深。

更多的介绍了研究手段和方法,如怎么转储,转储出来怎么看,用跟踪事件查看语句执行过程中对数据做了哪些动作,查看数据字典的创建语句来分析数据来源。

喜欢他最后说的一段话:“然而除了Oracle,我一直还想说的

,不要忘记了生活,没有什么比生活更重要的。想一想你匆忙的脚步是否已经很久没有为一览风景而停留?想一想你是否已经很久没有陪家人与朋友出游谈天?要记住我们是为了生活而工作,而不是为了工作而生活。”

没看或没细看或没看明白

MOUNT相同DB_NAME的数据库

P49。

P161

案例之二 RAC环境参数文件

11G新特性。11G虽然出来五年了,但用的还是比较少,对11G的新特性,可以找专门的书。

p262-x 库缓存和字典缓存的内存结构,dump分析。

9i中模拟ORA-04031错误,p270

library cache

pin和library cache lock等待事件的研究p274-p281

p344数值在oracle内部存储

p357

undo_retention的内部实现

说明:

和作者同样10.2.0.1.0版,dump出来有些地方字符格式不一样,照着书上用grep可能就找不到,比如实例恢复时,书上是

Started recovery

at指出开始恢复,而我的数据库是Started redo application at。

#可执行文件

File $ORACLE_HOME/bin/oracle可以查看oracle这个文件的信息

V$proecss字段解释

Spid 系统进程id

Pid

oracle进程id

Addr 进程在内存中的物理地址,和v$session 中的paddr相关联

latchWait 闩等待

latchspin

闩自旋

v$process被认为是从操作系统到数据库的入口。

#oracle_sid和instanc_name可以不一样。

#启动

Nomount根据参数文件的参数据启动实例。

Mount加载控制文件,控制文件在参数文件指定。

Open打开数据文件和重做日志文件,这些由控制文件指定。

Mount时如果某个数据文件丢失,不会前台提示,会记录在日志中(测试,并没有),在open时报错。

Open时oracle进行两项检查

数据文件头中的检查点计数是否和控制文件中的检查点计数一致。

数据文件头的开始SCN和控制文件中记录的该文件的结束SCN是否一致。

检查完成后,打开数据库,锁定数据文件,并将每个数据文件的结束SCN设为无穷大。打开锁定的数据文件。

#关闭

Close

Dimount

shutdwn

#ORA-00600要充分重视,会导致数据损失。

NOMOUNT状态就出现问题,通常是系统问题,如系统资源不足,修改内核参数。

#v$recover_file查看哪些文件加载失败

用diff比较两个控制文件找到heartbeat,在mount状态下hearbeat会发生改变,heartbeat: 797107166 mount id:

3081731594

表时实例被特定例程所mount,这个属性在RAC环境下有用,但在单实例下也有hearbeat。

#重建口令文件

口令文件丢失,启动时不会报错,只是授权时报错

ORA-01031Insufficient

privileges

orapwd file='orapwcqming'

password='sysdba' entries=10 force=y

#9i后不用listener.ora文件,而用自动注册。

#SCN

SCN由两部分组成,高位SCN Wrap由2Bytes记录,低们SCN Base由4Bytes记录

转储出来的数据文件

DATA FILE#1后面的是控制文件中关于数据文件的信息。

FILE HEADER:后面是数据文件头的信息。

#检查点

写脏数据,写控制文件和数据文件头中的检查点信息。

完全检查点,就是常规的检查点,写全部脏数据。

增量检查点,DBWR从检查点队列(CKPTQ)按LRBA (low redo byte address)的顺序写,同时,CKPT进程将当前的最低RBA写入控制文件,并不改写控制文件中数据文件的检查点信息以及数据文件头信息,而只是记录控制文件检查点时的SCN,并根据增量检查点的写出进度,增进RBA信息。

FILEQ文件检查点队列按文件划分的检查点队列,每个文件一个FILEQ,其上有各自的脏buffer。每个buffer的header上都有CKPTQ和FILEQ,有指向前和后的地址,使之形成双向链。

对象检查点队列OBJQ,参照FILEQ的解释。

select * from v$sgastat where name

like 'object queue%';

查看检查点队列受latch保护

Select name,gets,misses from

v$latch where name=’checkpoint queue latch’;

Select name,gets,misses from

v$latch_children where name=’checkpoint queue latch’;

Dump出buffers来

alter session set events 'immediate

trace name buffers level 10';

ckptq: [223e6034,2d9a0ac0]

fileq: [223e603c,2d9a0ae8] objq: [2bfd46c0,223e60b4]

ckptq: [NULL] fileq:

[NULL]—说明干净

这些信息可以在X$KCCCP里查到

select

CPDRT,CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low

RBA",CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF "On disk

RBA",CPODS,CPODT,CPHBT from x$kcccp;

CPDRT列是检查点队列中的脏块数目.

CPODS列是on disk rba的scn

CPODT列是on disk rba的时间戳CPHBT列是心跳

LOG

SWITCH引起的检查点时,要同时在控制文件和数据文件头上标记检查点进度

#

增量检查点通过 Fast-start

checkpointing特性来实现,这一特性包含在Fast-start Fault recover组件中。V$option视图可以查看是否有这一组件。

FAST_START_MTTR_TARGET参数影响恢复时间,影响检查点。

V$mttr_tartget_advie评估不mttr时间下I/0次数等操作。这个建议的信息的详细程度受参数statistics_level的控制,设为typical或all时要收集,BASIC不收集。

v$instance_recovery查看当前实例恢复状态

1.ESTIMATED_MTTR 估计的平均恢复时间,基于脏块数和日志块得出

2.TARGET_MTTR应该等于

3.FAST_START_MTTR_TARGET参数值

1接近或超过3时,发生检查点,如果较长时间这种状态,说明DBWR忙不过来,检查点不能完成。

4 .CKPT_BLOCK_WRITES检查点写出的block

5.WRITES_AUTOTUNE自动检查点写出的block

不设置3时,自动检查点功能生效。

#控制文件和数据文件头转储信息

整个数据库的

DATABASE

ENTRY开头

以DATA

FILE开头,表示控制文件中的数据文件信息

DATA FILE #1:

(name #7)

/home/oracle/oradata/ly/system01.dbf

creation size=0 block

size=8192 status=0xe head=7 tail=7 dup=1

tablespace 0, index=1

krfil=1 prev_file=0

unrecoverable scn:

0x0000.00000000 01/01/1988 00:00:00

Checkpoint cnt:62 scn:

0x0000.00094587 10/20/2012 19:00:19

***1

Stop scn:

0xffff.ffffffff 10/20/2012 18:59:54

Creation Checkpointed

at scn:

0x0000.00000009 06/30/2005 19:10:11

thread:0

rba:(0x0.0.0)

enabled threads: 00000000 00000000

00000000 00000000 00000000 00000000

以FILE

HEADER:开头,表示数据文件中的数据文件头信息,保存在dbf文件里

V10 STYLE FILE

HEADER:

Compatibility Vsn = 169869568=0xa200100

Db ID=1349173110=0x506abf76, Db Name='LY'

Activation ID=0=0x0

Control Seq=489=0x1e9, File size=61440=0xf000

File Number=1, Blksiz=8192, File Type=3 DATA

Tablespace #0 -

SYSTEM

rel_fn:1

Creation

at

scn: 0x0000.00000009 06/30/2005 19:10:11

Backup taken at scn:

0x0000.00000000 01/01/1988 00:00:00 thread:0

reset logs

count:0x2e72e6b7 scn: 0x0000.0006ce7b reset logs terminal rcv

data:0x0 scn: 0x0000.00000000

prev reset logs

count:0x2184ef74 scn: 0x0000.00000001 prev reset logs terminal rcv

data:0x0 scn: 0x0000.00000000

recovered at

10/20/2012 19:00:16

status:0x2004 root

dba:0x00400179 chkpt cnt: 62 ctl cnt:61

***3

begin-hot-backup file size:

0

Checkpointed at scn: 0x0000.00094587

10/20/2012 19:00:19

***2

thread:1

rba:(0x7.2.10)

enabled threads: 01000000 00000000

00000000 00000000 00000000 00000000

*1,*2

正常情况下控制文件中的SCN和数据文件头中的SCN相同。

*3

为什么数据文件头里认为控制文件的检查点数要比他少一个呢。

更新数据文件头里的CNT时,先要把此时控制文件中的CNT记录到这里,因为可能突然crash,导致更新控制文件的CNT时失败,这样可以保证上一次检查点是成功的。然后再更新控制文件的CNT时,加1了

#数据库相关信息

正常关闭,mount下,dump出控制文件

为什么不一样,因为database

checkpoint是上次完成检查点的信息

*******************************************************************

DATABASE ENTRY

*********************************************************************Database

checkpoint: Thread=1 scn: 0x0000.0009bbab

Controlfile Checkpointed at

scn:

0x0000.0009b1d2 10/21/2012 09:21:06

REDO THREAD

RECORDS

Checkpointed at

scn:

0x0000.0009bbab 10/21/2012 10:20:41

DATA FILE #4:

Checkpoint cnt:75 scn:

0x0000.0009bbab 10/21/2012 10:20:41

Stop scn:

0x0000.0009bbab 10/21/2012 10:20:41

这几个一样,说明数据库一致,下次启动不用恢复

异常关闭,mount下,dump出控制文件

DATABASE ENTRY

Database checkpoint:

Thread=1 scn: 0x0000.000a0a59

Controlfile Checkpointed at

scn:

0x0000.000a0aa5 10/21/2012 10:55:13

REDO THREAD

RECORDS

Checkpointed at

scn:

0x0000.000a0a59 10/21/2012

10:55:10

DATA FILE #4:

Checkpoint cnt:79 scn:

0x0000.000a0a59 10/21/2012

10:55:10

Stop scn:

0xffff.ffffffff 10/21/2012 10:54:44

数据文件的stop

scn为无穷大,说明上次没有正常关闭,需要实例恢复

非正常关闭后SMON自动进行实例恢复,包括两个步骤

cache

recovery(前滚)和transaction recovery(回滚)。

将上面的数据启动,在alert日志中查看恢复过程。

alter database

open

Sun Oct 21 11:02:33

2012

Beginning crash recovery of

1 threads

parallel recovery

started with 3 processes

Sun Oct 21 11:02:35

2012

Started redo scan

Sun Oct 21 11:02:39

2012

Completed redo

scan

98 redo blocks read, 53

data blocks need recovery

Sun Oct 21 11:02:39

2012

Started

redo application at

Thread 1: logseq 9,

block 3

Sun Oct 21 11:02:39

2012

Recovery of Online Redo Log:

Thread 1 Group 2 Seq 9 Reading mem 0

Mem# 0 errs 0:

/home/oracle/oradata/ly/redo02.log

Sun Oct 21 11:02:39

2012

Completed redo

application

Sun Oct 21 11:02:39

2012

Completed

crash recovery at

Thread 1: logseq 9,

block 101, scn 678100

53 data blocks read,

53 data blocks written, 98 redo blocks read

Sun Oct 21 11:02:39

2012

Thread 1 advanced to log

sequence 10

目前完成cache

recovery。

回滚的原理和意义不说了。

8I以后有两个新特性来加快事务恢复阶段的效率。

一个是fast-start on-demand

rollback,不回滚完所有事务再允许新事务,如果一个用户试图访问被异常中止进程锁定的记录,oracle回滚那些新事务请求的记录,即因需求而回滚,

另一个是fast-start parallel

rollback对长时间运行的未提交事务有效,尤其是并行INSERT UPDATE DELETE

#自动检查点

10g开始,没有设置fast_start_mttr_target,自动检查点调整生效。

#如果出现坏块,肯定是修复不了的

在出数据时,可以跳过块,使导出操作顺利进行完

Alter system set

events=’10231 trace name context forever,level 10’;

#参数文件

除了第一次启动数据库需要PFILE,以后可以不再需要。

V$system_parameter系统级的参数,如果在会话级改了参数,v$parameter和v$system_parameter会不一样。

V$parameter和v$parameter2的区别。

select b.indx,b.ksppstvl,b.ksppstdvl

from

X$KSPPI a,X$KSPPCV b where a.indx=b.indx

and a.ksppinm like '%simultaneous%';

查看隐含参数

#妙招

案例一

Spfile不能直接编辑,可以通过linke链接到spfile,用后来的参覆盖前面的参数,达到直接编辑spfile的效果。

系统运行时一些参数修改错误

alter system set sga_max_size=5G scope=spfile;

SQL> startup;

ORA-27102: out of memory

[oracle@llm dbs]$ vi initcqming.ora –或者直接编辑修改init文件

spfile='/u01/app/oracle/product/db_1/dbs/spfilecqming.ora'

sga_max_size=500000000—500M

SQL> startup

pfile='/u01/app/oracle/product/db_1/dbs/initcqming.ora';

SQL> select name ,value from v$spparameter where

name like '%sga%';

sga_max_size

5368709120

—5G

SQL> select name ,value from v$parameter

where name like '%sga%';

sga_max_size

503316480

--500M

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

或者创建了pfile后,直接编辑修改init文件

SQL> create pfile from spfile;

File created.

SQL> startup

pfile='/u01/app/oracle/product/db_1/dbs/initcqming.ora';

SQL> create spfile from pfile;

File created.

SQL>startup;

案例二

dbs/下所有参数文件被删

系统没有关闭,从实例中取出非默认的参数

set linesize 120

set pagesize 999

set heading off

set feedback off

spool

$ORACLE_HOME/dbs/tmp/inittemp.ora

select '*.'||name||'='||value from

v$parameter where isdefault='FALSE';

spool off

create

spfile='/u01/app/oracle/product/db_1/dbs/spfile2' from

pfile='/u01/app/oracle/product/db_1/dbs/tmp/inittemp.ora';--生成spfile

mv spfile2

spfilecqming.ora—重命名spfile

下次就可以用spfile正常启动了

11g

重置spfile参数

Alter system reset

open_cursor scope=spfile sid=’*’;

修改了系统参数scope=spfile,导致下次不能再启动。可以

Create pfile from

spfile

编辑修改pfile内容

Create spfile from

pfile

#scope=spfile虽然对实例没效,但可以从v$spparameter查到。

Rac中还有sid参数

Oracle运行期间不锁定spfile,可以在系统级下动他,oracle也不知道。

#判断是否使用了spifle

select name,value from

v$parameter where name='spfile';

SQL> show parameter

spfile

select count(*) from v$spparameter

where value is not null;--如果为0则用的pfile

#在查联机错误号

oeer ora 39212

#x$表

可以打开set autorace trace

explain

查一些视图时,可以看到用了哪些x$视图

x$kvit;

$ORACLE_HOME/rdbms/admin/sql.bsq建库时用来生成数据字典

$ORACLE_HOME/rdbms/admin/catalog.sql静态数据字典视图

#常用数据字典

dict/dictionary,有哪些数据字典

它们是同意词

dict_columns,数据字典所有列名

dba_source,对象的源代码

dba_objects

#动态性能视图

数据库启动过程中创建。所以不同阶段访问到的视图数量不一样

GV$用于多实例环境下,反回所有实例数据,多一个INST_ID字段。

V$session 反回本实例的。

v$fixed_view_definition视图可以查看v$视图怎么从GV$视图创建过来的。

GV_$、V_$视图和GV_$、V_$同义词基于GV$、V$视图创建,起来不让普通用户访问GV$、V$。所以普通用户访问的v$视图不是真正的v$视图(v$视图基于x$表创建),而只是指向v_$的同义词

#有视图和同义词的情况下,会优先访问视图

#PGA

固定PGA

可变PGA,包括以下。X$KSMPP查看使用情况

会话内存,存放会话的登录信息,对于共享模式,这部分内存是共享的。

私有SQL区,包含绑定变量的信息、查询执行状态以及查询工作区等。每个发出的SQL查询的会话都有一块私有SQL区,专用模式下在PGA中,共享模式下在SGA中。私有SQL区包含以下两个。

永久区域。绑定变量等信息,只在游标关闭时释放。

运行时区域。执行请求时创建,其中包含了查询执行的状态信息(如全表扫描的进度等)、SQL WORK Areas(sort或hash-join等内存要求高的请求时分配),对于DML语句来说,SQL语句执行完毕就释放该区域,对于查询语句则是在记录返回后或查询取消时释放)。

select name,value from v$pgastat where

name like '%OS';

PGA返回给OS的内存累计。

#PGA_aggregate_target(P_A_T)参数指定所有session总计最大内存(10M~4096G)

Workarea_size_policy=auto(自动) ,MANUAL手动。

10g中自动PGA管理下,单个SQL操作可分配的最大PGA内存

P_A_T<=500MB,则_smm_max_size=0.2*P_A_T

500MB<

P_A_T<

TCSC="0" NumberType="1" Negative="False" HasSpace="False"

SourceValue="1" UnitName="g">1G,则100MB

1G<

P_A_T<

TCSC="0" NumberType="1" Negative="False" HasSpace="False"

SourceValue="2.5"

UnitName="g">2.5G,则0.1* P_A_T

>2.5G

则 262M

自动PGA情况下,可调整PGA+不可调PGA<= P_A_T

OLTP系统PGA=物理总内存*0.8*0.2

OLAP系统PGA=物理总内存*0.8*0.5

#v$process可以查看每个服务器进程的PGA使用。

V$process_memory还可以查看PGA消耗在什么地方。

#v$pgastat

v$sql_workarea

#SQL在工作区中有3种方式

在v$sysstat中查询

workarea executions

– multipass大量磁盘交互

workarea executions

– onepass部分磁盘交互

workarea executions

– optimal全在内存中

#UGA(user global area

用户全局区),包括用户会话数据、游标状态和索引区。可通过X$KSMUP查询。

共享模式下,UGA在shared pool或large pool里,专用模式下UGA在PGA里。

PGA与UGA的关系像process和session的关系。PGA服务于进程的内存结构,包含进程信息,UGA服务于会话,包含会话信息。

#SGA

固定区域,有latch或地址指针等。可以能过x$ksmfsv查询,他说查询这视图也可能导致异常。

x$ksmmem记录了整个SGA的地址映射关系,每条记录达表一块SGA地址,count(*)可以查出映射了多少块

#buffer cache中的recycle倾向于即时老化,default才是用LRU算法,默认所有表都用default区域大小就是 buffer cache大小,由db_cache_size设置

建表时参数指定storage(buffer_pool

keep),stroage(buffer_pool recycle)

SQL> select * from

v$sga;

NAME

VALUE

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

----------

Fixed Size

2054552

Variable Size

1107297896

Database Buffers

5083496448

Redo Buffers

14721024

Variable Size=shared_pool_size+java_pool_size+large_pool_size=

(sga_max_size-db_cache_size)

Database Buffers=db_cache_size

v$sgastat查看SGA具体使用信息。

v$sgainfo分类统计SGA使用信息。

#共享内存

指操作系统中允许单个共享内存段的最大值,如果SGA小于这个值,SGA会被分配多个共享内存段,所以最好将系统的这一参数修改

[root@llm ~]# vi

/proc/sys/kernel/shmmax

2147483648

这样修改重启后无效

vi /etc/sysctl.conf

kernel.shmmax =

4294967295

永久有效

ipcs –sa 可以查看分配给oracle的共享内存有多少,如果shmmax参数小了,会有多条。

ps –ef|grep dbw 找到dbw进程号

pmap 3102 查看这个进程号使用的内存

#没修改shmmax参数,启动时日志里有

warnimng einval creating

segment of size 0x5432145

p216

#设置SGA大小时,有个粒度因素

SGA<

TCSC="0" NumberType="1" Negative="False" HasSpace="False"

SourceValue="1" UnitName="g">1G

4MB

否则16MB

最低3个粒度

# v$db_cache_advice

它受参数 db_cache_advice控制

OFF 关

ON 开

READY 不采集信息,但还要那些建议?

# v$shared_pool_advice

受v$statistics_level影响,他的收集密度受参数statistics_level影响,其值有

basice 收集基本

typical 默认值,推荐,收集大部分

all 全部

v$statistics_level,的activation_level列有 basice typical

all三种值,确定了在三种级别下,会收集哪些信息。

#自动共享内存管理受参statistics_level影响。

就是调整SGA组件

由MMAN进程来做

SGA_TARGET=0时关闭这功能

v$sga_dynamic_components可以看到SGA各组件

#

SGA=物理总内存*0.8*0.8

SGA+PGA=物理总内存*0.8

sga_maz_size+pga_aggreate_target

对于总内存小于1G的系统,SGA一般设小于0.5

SGA设置过大时,会看到SWAP大量消耗

#buffer cache

LRU

dirty list

检查点队列的内存在shared

pool中。

各种list上存放的是具体指向buffer指针

#

初始化时所有buffer都被hash到LRU

list。

当要从数据文件读取数据时,先在LRU

list上寻找free的buffer(顺带把发现的dirty buffer注册到dirty list上),再把数据读到那些buffer cache里。

被修改后移动到dirty

list(也叫wirte

list)里,dirty

list是候选的可以被DBWR写出到数据文件 的buffer。所以buffer要么在dirty

list上,要么在 LRU

list上,不可能同时在两个链上。

这些都是server在做。

#

多个触发条件中的两个,dirty

queue超过1/4满时,扫描LRU到40%时,server通知dbwr写。

CKPT通知dbwr写时,dbwr也会主动扫描LRU

list(1/4) 将发现的脏块注册到dirty

queue 和checkpoing

queue

#

8i以后lru list和dirty list增加了辅助list,之前的list被叫主list

数据库初始化时,buffer放在辅助LRU

list (auxiliary

rpl_lst)上,被用过后移动到主 LRU

list( main rpl_lst)上。

用户搜索free

buffer时从lru-aux

list开始,dbwr搜索dirty

buffer从LRU-main

list开始。

#

导出的块中,每种list有多个,因为他们被分给buffer cache各个部分(keep,recycle,不同大小的block_size)。

确实有那么个链表。

#latch保存chain

select * from v$latch where name

like

'cache buffers lru chain';

select * from v$latch_children where

name like

'cache buffers lru chain';

#

所有buffer按hash算法,把他们分到不同的bucket中,当用户需要在buffer中定位数据是否存在时,只需要通过同样的算法获得hash值,然后到相应的bucket中查找。

每个buffer应该存在哪个bucket中,由buffer的数据块(他在磁盘中,DBA,data

block address)地址早已决定。

在bucket内部,通过cache buffer

chain(一个双向链表)将所有的buffer通过buffer

header(存有指向具体buffer的指针) 信息联系起来。

Buffer header存放的是对应数据块的概要信息,包括数据块的文件号、块地址、状态等。在判断数据块在buffer中是否存在,通过检查buffer header即可确定。

每个bucket 一个chain,受 “cache buffer chain

latch”保护,一个latch管理多个bucket。需要的latch被占用会出现”latch free”等待事件。

这图道尽了

a4c26d1e5885305701be709a3d33442f.png

区别

bucket是buffer cache的管理结构

bucket和他的chain作用不同于dirt list、lru

list,chkpq这些链。

lru list是用户要写数据到buffer时,用lru list找空闲buffer,然后写进来。

dirty list在刷出脏块时,扫描dirty list找到脏块

bucket chain用于确定磁盘中的某个block是否在buffer中有映射,这个功能能快速实现的关键是 DBA地址一定,所在的bucket就能确定。

#v$bh

tch字段

touch,被访问的次数

HLADDR hash chain latch

address

查出热块

SELECT *

FROM

(SELECT

addr, ts#, file#, dbarfil, dbablk, tch

FROM x$bh

ORDER BY tch DESC)

WHERE ROWNUM

< 11;

查出热块所在对象

SELECT distinct e.owner,

e.segment_name, e.segment_type

FROM

dba_extents e,

(SELECT *

FROM (SELECT

addr, ts#, file#, dbarfil, dbablk, tch

FROM x$bh

ORDER BY tch DESC)

WHERE ROWNUM < 11) b

WHERE e.relative_fno = b.dbarfil

AND e.block_id <= b.dbablk

AND e.block_id + e.blocks > b.dbablk;

查出热块所在对象,有哪些SQL在用它。

select hash_value,sql_text from

v$sqltext

where (hash_value,address) in

(

select

a.hash_value,a.address

from v$sqltext a,

(SELECT distinct e.owner,

e.segment_name, e.segment_type

FROM dba_extents e,

(SELECT

*

FROM (SELECT

addr, ts#, file#, dbarfil, dbablk, tch

FROM x$bh

ORDER BY tch DESC)

WHERE ROWNUM < 11) b

WHERE e.relative_fno = b.dbarfil

AND

e.block_id <= b.dbablk

AND e.block_id + e.blocks > b.dbablk )b

where upper(a.sql_text) like '%'||b.segment_name||'%'

and b.segment_type='TABLE')

order by hash_value,address,piece;

#所有latch等待都被归入 latch free等待。

#connect by操作容易引起争用?

#shared pool

库缓存

数据字典缓存,它是以行存储的,所以叫row

cache。

V$librarycache

--分类统计信息

V$rowcache

#

shared pool通过free lists管理free 内存块(chunk),按不同size被划分到不同的bucket管理。

Oracle请求shared pool空间时,首先进入相应Bbucket进行查找(在适合这个请求大小的bucket里找)。如果找不到(这个bucket里都用完了)则,则转向下一个非空的Bucket(更大一点的bucket),获取第一个chunk。分割这个chunk(因为比想要的大些,所以用不完),剩余部分进入相应的bucket(因为这个bucket分割了一部分,变小了,所以被放在小一些的bucket里)。

不停的分割形成了碎片,碎片过多会导致搜索Free

lists的时间过长,而搜索free

list要持有 shared pool

latch,所以产生性能问题。

碎片问题是shared

pool的根本问题。

当尝试分配大块的连续内存失败(其实还有内存,只是被碎片化),oracle清除共享池中没有使用的所有对象,使空闲内存块合并,如果还是不够,则报ORA-04031。

9i开始shared pool被分割为多个子缓冲池(subpool),每个subpool可以看作一个mini shared pool拥有自己独立的free list,内存结构以及LRU List,每个sub

pool还有shared pool

reserved area。每个sub

pool被一个Latch保护,最多有7个sub

pool。

多共享池可能有这样的问题,一个sub

pool被用完了,用户却还被分到这个sub

pool里来,而其他sub

pool还有空间。虽然10g可以SubPool间切换,但不能无限制的切换,所以这个问题还是存在。

子缓冲池分配算法

每个至少256MB,4颗CPU一个子缓冲池。

每个子缓冲池又被分割为4个子缓冲池。

sga heap(1,0)

sga heap(1,1)

sga heap(1,2)

sga heap(1,3)

sga heap(2,0)

sga heap(2,1)

sga heap(2,2)

sga heap(2,3)

不能显式设置sbu

pool大小,可以通过shared

pool大小和sub

pool数量(参数来控制_kghdsidx_count)来设置sub pool大小。

x$kghlu查询子缓冲池,一条对应一个子缓冲。

x$ksmsp一条对应一个chunk,查这个视图会导致过度CPU,BUG引起的。

ksmchcom注释

ksmchsiz块大小

ksmchcls类型,有4类

free,不包含任何对象的chunk,可以自由分配。

recr,recreatable,包含可以被临时移出内存的对象,

在时候,这个对象可以被重建。如,存储共享

SQL代码的内存可以重建。

freeable,包含session周期或调用的对象,可以全部

或部分提前释放。

perm,permanent,永久对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值