他很喜欢从多个版本说问题,从技术演进角度来学比较有效,但他喜欢在老版本上重演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”等待事件。
这图道尽了
区别
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,永久对象。