lru oracle,一个测试理解什么是主、辅LRU(oracle cuug)
LRU是Buffer Cache池中的重要链表,它的作用我不再详述,已经有很多相关资料。这次主要和大家讨论下主LRU、辅助LRU的作用。
先来看一个测试。
步1:环境介绍
先来看看Buffer Cache的大小:
SQL> show sga
Total System Global Area 1073741824 bytes
Fixed Size 1284344 bytes
Variable Size 960497416 bytes
Database Buffers 104857600 bytes
Redo Buffers 7102464 bytes
Buffer Cache大小100M。
再来看看测试表大小:
SQL> set linesize 1000
SQL> col segment_name for a30
SQL> SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name='A3_70M';
SEGMENT_NAME BYTES/1024/1024
------------------------------ ---------------
A3_70M 80
SQL> SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name='A4_70M';
SEGMENT_NAME BYTES/1024/1024
------------------------------ ---------------
A4_70M 80
两张测试表,A3_70M、A4_70M,各自大小80M。本来是想把它们两个大小建为70M的,所以名字带有后缀_70M,但建的大了一点,不过,这无所
谓,不会影响我们的测试结果。
步2:刷新Buffer Cache池,观察LRU链长度
SQL> alter system flush buffer_cache;
SQL> select CNUM_SET,CNUM_REPL,ANUM_REPL,CNUM_WRITE ,ANUM_WRITE from x$kcbwds;
CNUM_SET CNUM_REPL ANUM_REPL CNUM_WRITE ANUM_WRITE
---------- ---------- ---------- ---------- ----------
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
6238 6238 6219 0 0
6237 6237 6224 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
CNUM_SET CNUM_REPL ANUM_REPL CNUM_WRITE ANUM_WRITE
---------- ---------- ---------- ---------- ----------
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
16 rows selected.
这个视图返回16行,但只有两行有数据。其他行都是0,原因是什么?
查一下select name from v$latch_children where name ='cache buffers lru chain'; 就可以知道,我一共有16个cache buffers lru
chain Latch,但只有两个被使用了。
每一个cache buffers lru chain latch,都算作一个“工作组”,work set。意义是指每个cache buffers lru chain latch,都对应一组主
、辅LRU链,和脏LRU链。
x$kcbwds视图中CNUM_SET列,统计工作组所有块数量。简单点说,也就是LRU链上所有块的数量。
CNUM_REPL列是主、辅LRU链表中所有的块数。
ANUM_REPL列是辅LRU链上所有的块数。
用CNUM_REPL-ANUM_REPL,即为所有主LRU链上的块数。
CNUM_WRITE、ANUM_WRITE这个列对应LRUW(也即为脏LRU)链,CNUM_WRITE为LRUW链中所有块数,ANUM_WRITE为辅助LRUW中的块数。两个相减,
要以得到主LRUW中的块数。
这个测试中,先不用观察LRUW。我们先只关注主、辅LRU。
来看我们的显示结果吧,两个工作组加起来,一共12475个块。
另外,可以看到,CNUM_REPL的ANUM_REPL列的几乎相等,这说明绝大多数块,都在辅助LRU链表中,这是为什么呢?这是我们今天第一点结论,
flush了buffer cache、或刚刚开启数据库时,所有的可用Buffer都会链接到辅助LRU中。
步3:先查询a3_70M,再查询a4_70M,分别观察物理读。(注意顺序,先查询A3_70M,再查询A4_70M)
SQL> set autot trace
SQL> select count(*) from a3_70m;
Execution Plan
----------------------------------------------------------
Plan hash value: 850873958
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1643 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| A3_70M | 1511K| 1643 (1)| 00:00:20 |
---------------------------------------------------------------------
Statistics
----------------------------------------------------------
207 recursive calls
0 db block gets
9292 consistent gets
9271 physical reads
0 redo size
414 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select count(*) from a4_70m;
Execution Plan
----------------------------------------------------------
Plan hash value: 2047399966
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1643 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| A4_70M | 1502K| 1643 (1)| 00:00:20 |
---------------------------------------------------------------------
Statistics
----------------------------------------------------------
207 recursive calls
0 db block gets
9292 consistent gets
9259 physical reads
0 redo size
414 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
1 rows processed
可以看到,第一次查询A3_70M和A4_70M,物理读分别是9200多。
步4:再次查询a3_70M,再查询a4_70M,分别观察物理读。(顺序无所谓,先查谁都可以)
SQL> select count(*) from a3_70m;
Execution Plan
----------------------------------------------------------
Plan hash value: 850873958
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1643 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| A3_70M | 1511K| 1643 (1)| 00:00:20 |
---------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9269 consistent gets
213 physical reads
0 redo size
414 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select count(*) from a4_70m;
Execution Plan
----------------------------------------------------------
Plan hash value: 2047399966
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1643 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| A4_70M | 1502K| 1643 (1)| 00:00:20 |
---------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9269 consistent gets
9135 physical reads
0 redo size
414 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
发现没有,A3_70M的物理读在第二次查询时大量下降,只有213次。而A4_70M在第二次查询时,物理读下降很不明显,还是9200次左右。
可以再测个几遍,情况依旧。A3_70M的物理读很少,而A4_70M的物理读很多。
这是我们今天的问题一:考虑这是为什么。
下面继续我们的问题2。
步5:连续两次查询A3_70M和A4_70M
SQL> select count(*) from a4_70m;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9269 consistent gets
8686 physical reads
0 redo size
414 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select count(*) from a4_70m;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9269 consistent gets
8722 physical reads
0 redo size
414 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
这是两次A4_70M的结果对比,多次查询A4_70M之后,物理读下降到了8700多,然后不再下降。
再来看两次连续查询A3_70M的结果对比:
SQL> select count(*) from a3_70m;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9269 consistent gets
600 physical reads
0 redo size
414 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select count(*) from a3_70m;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9269 consistent gets
0 physical reads
0 redo size
414 bytes sent via SQL*Net to client
381 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
第一次有600次物理读,第二次就没有了。
问题2出来了,考虑这是没什么。
步6:暂时总结
1、A3_70M和A4_70M表大小一样。行数一样、所占空间也一样,都是80M
2、第一次查询时,我们是先查询A3_70M,再查A4_70M。如果你反过来,先查A4_70M,将看到A4_70M的物理读在第二次查询时大大减少,连续两
次查询时物理读为0。
两个问题:
1、为什么第一次查询时,先查的表,在第二次查询时物理读会大大减少,而后查的表则不会。
2、为什么第一次查询时,先查的表连续两次查询时物理读会减少为0,而后查的表不会。
一个提示:可以观察一下我们开始提到的x$kcbwds视图。
步7:如何观察块处在哪个链上。
如何进一步分析这个问题?其实这两个问题的回答,都需要着落到一件事上,就是要分析两个表对应的块,分别在什么链上。是在主LRU,还是
辅LRU。如何进行这个观察呢?其实很简单,x$bh中有个LRU_FLAG列,通过这个列,就可以确定块在哪个链表上。
我们来看一下这个视图:
SQL> select lru_flag,count(*) from x$bh group by lru_flag;
LRU_FLAG COUNT(*)
---------- ----------
6 3081
2 6734
8 2
0 2658
在我的测试库中,我观察到的LRU_FLAG有4种值,6、2、8和0。这4个值分别代别什么意义呢?确定这个其实很简单,DUMP一下块对应的Buffer
就行了,以LRU_FLAG为6的为例:
(1)、随便查找LRU_FLAG为6的一行:
SQL> select lru_flag,file#,dbablk,TS# from x$bh where LRU_FLAG=6 and rownum=1;
LRU_FLAG FILE# DBABLK TS#
---------- ---------- ---------- ----------
6 5 12459 4
(2)、如下DUMP一下这个BUffer:
SQL> alter session set events 'immediate trace name SET_TSN_P1 level 5';
Session altered.
SQL> alter session set events 'immediate trace name BUFFER level 0x014030ab';
Session altered.
上面这两个命令,“SET_TSN_P1 level 5”中的5,是表空间号加1得到的。也就是TS#+1。
第二个命令中“BUFFER level 0x014030ab”,其中0x014030ab,是5号文件12459号块的DBA。
这个DBA是如何计算出的?其实我是在另一个会话中DUMP一下5号文件12459号块,查看DUMP结果才得到的,Oracle也提供了一个包,其实有个函
数可以根据文件号、块号生成DBA,包名、函数名我都忘了,只好用笨方法。
好,来查看DUMP结果吧,到user_dump_dest目录中,找到日期最靠后的(我一般是ls -lFrt),它就是我们刚刚生成的DUMP文件。在它的开头,
我们可以看到如下内容:
*** 2012-07-03 08:58:36.571
*** SERVICE NAME
SYS$USERS) 2012-07-03 08:58:36.523
*** SESSION ID
874.3) 2012-07-03 08:58:36.523
Dump of buffer cache at level 10 for tsn=4, rdba=20983979
BH (7bbf0764) file#: 5 rdba: 0x014030ab (5/12459) class: 1 ba: 7b9dc000
set: 5 blksize: 8192 bsi: 0 set-flg: 0 pwbcnt: 0
dbwrid: 0 obj: 9738 objn: 9738 tsn: 4 afn: 5
hash: [7d7e687c,8e94b67c] lru: [7bbe80b8,7bbf0704]
lru-flags: moved_to_tail on_auxiliary_list
ckptq: [NULL] fileq: [NULL] objq: [7bbf075c,7bbe8110]
st: XCURRENT md: NULL tch: 0
flags: only_sequential_access
LRBA: [0x0.0.0] HSCN: [0xffff.ffffffff] HSUB: [65535]
buffer tsn: 4 rdba: 0x014030ab (5/12459)
scn: 0x0000.00418edb seq: 0x01 flg: 0x06 tail: 0x8edb0601
frmt: 0x02 chkval: 0xc400 type: 0x06=trans data
我对这里面的东西,不过多解释了,其实有一行:
lru-flags: moved_to_tail on_auxiliary_list
这一行说明了块对应Buffer所在LRU链表的状态。Buffer目前在辅助LUR,moved_to_tail说明Buffer正移向链表末尾。
好了,我们已经总结出来,LRU_FLAG列为6,说明Buffer在辅助LRU链表。
其他的我不再一一列出测试过程了,总结一下,LRU_FLAG为6、4,说明BUffer在辅助LRU中。为0、2,说明在主LRU的冷端,为8、9的,说明在
主LRU的热端。
步8:问题1:为什么第一次查询时,先查的表,在第二次查询时物理读会大大减少,而后查的表则不会
让我们来观察一下A3_70M、A4_70M 的块都在什么链上
SQL> select lru_flag,count(*) from x$bh a,dba_objects b where a.obj=b.data_object_id and object_name='A3_70M' group by lru_flag;
LRU_FLAG COUNT(*)
---------- ----------
2 8554
0 1
SQL> select lru_flag,count(*) from x$bh a,dba_objects b where a.obj=b.data_object_id and object_name='A4_70M' group by lru_flag;
LRU_FLAG COUNT(*)
---------- ----------
6 3082
2 366
0 1
这两条语句,我就不再过多解释了,根据LRU_FLAG列的值,我们可以确认,A3_70M,共有8555个块在Buffer Cache中,所有相关的块都在主LRU
链。A4_70M,只有3400多个块在Buffer Cache中,而且大部分块都在辅助LRU。
为什么A3_70M的块,被读进Buffer Cache时,大多被放置在主LRU的冷端?而A4_70M的块,则被放进辅助LRU呢?
能回答这个问题,我们今天的问题也就有了答案。
步9:回答问题1
有如下三点基础知识:
1、当数据库刚刚打开、或刚刚做过FLush Buffer_cache操作时,所有的块,都被放进辅助LRU。
2、进程寻找可用块时,先会在辅助LRU中查找,然后才会到主LRU中找。
3、Oracle会保持20%至25%左右的块在辅助LRU链,80%的在主LRU。这一点,从观察x$kcbwds中的CNUM_REPL、ANUM_REPL列,可以很容易的验证
。
有了这三点基础知识,让我们来得出结论吧:
当所有块都在辅助LRU时,Oracle为了急于保证主、辅LRU,块数量80%,20%的比例,第一次查询时,会将大量的块移到主LRU。也就是说,第一
次查询A3_70M时,大至步骤是这样的,分两种情况:
一、主LRU几乎为空时:
1、在辅助LRU找到可用块。
2、将它移到主LUR
3、将数据读入此块。
二、当主、辅LRU的块数量比例到达80%、20%后
1、在辅助LRU找到查用块
2、所处链表不变,直接将数据读入此块。
3、物理读完成后,块还在辅助LRU中。
由于第一次查询A3_70M时,主LRU几乎为空,所以,它的绝大部分的块被放在了主LRU,少部分块被放入了辅助LRU。
根据比例,辅助LRU中将会有3000到3200个左右的块。根据我们的测试结果,全表扫描A4_70M后,有3000多个块在辅助链上。根据这个,得出我
们今天第二个结论,正常的全表扫描操作,将只会反复使用辅助LRU中的块。
当然,我们的测试中,还是有少量A4_70M的块进入到了主LRU,不过数量不多,只有几百个。
好了,回答一开始的问题吧,第一次查询A3_70M,Oracle会了保持主、辅LRU的比例,将很多被A3_70M占用的块移进了主LRU,所以,A3_70M在
Buffer Cache中可以有很多块,再次查询A3_70M时,物理读大大减少。
而全表扫描A4_70M,只能反复使用辅LRU中的块,几乎无法占用主LRU中的块,因此在Buffer Cache中块数较少,每次物理读都很高。
步10:回答问题2
为什么连续两次查询A3_70M,就没有物理读了?可以连续两次全表扫描一下A3_70M,查看结果:
SQL> select lru_flag,count(*) from x$bh a,dba_objects b where a.obj=b.data_object_id and object_name='A3_70M' group by lru_flag;
LRU_FLAG COUNT(*)
---------- ----------
6 1004
2 8254
0 1
一共9000多个块,8000多个在主LRU,1000多一点在辅助LRU。A3_70M表的全部块,都可以被缓存到Buffer Cache中。
当再次查询A4_70M时,A4_70M将又反复占用辅助LRU中的块,A3_70M留在辅助LRU中的1000多一点块会被覆盖,所以,当A3_70M、A4_70M交替查
询时,每次A3_70M在辅助LRU中的块都会被覆盖,因此,它会有少量物理读,但,当连续查询A3_70M时,辅助LRU中的块没被覆盖,就不会有物理读了。
好,问题已经解答了,让我们总结一下吧。
总结:
1、flush了buffer cache、或刚刚开启数据库时,所有的可用块都会链接到辅助LRU中。
2、查找可用块的过程,是先找辅助LRU,再从主LRU的冷端尾开始找。
3、全表扫描在辅助LRU找到块后,不会将块读进主LRU。所以,全表扫描的结果很容易被覆盖。
4、非全表扫描时,在辅助LRU找到块后,会将块移到主LRU的冷端头。这一点我们还没验证过。
5、全表扫描的块,如果再次以非全表扫描方式访问,TCH列会增加,但会一直留在辅助LRU,不会被移到主LRU冷端头。只有等到TCH值超过2时,才会在
下次被扫描到时,移到主LRU热端。
第4点和第5点,我们并没用测试验证,但找个这样的测试也是很简单的。留给大家自己验证一下吧,研究Internal,结果不是目的,过程更有
意义。
最后还有一个注意事项,这个测试只能在10G下做,因为11GR2后有些改变,即使是开库后第一次全表扫描,也不会把块移往主LRU,这样其实更合理,Oracle其实一直没有停止对内核优化步伐。
另外,本篇中除这个测试外,其他测试都可以在10G、11GR2下做。
lru oracle,一个测试理解什么是主、辅LRU(oracle cuug)相关推荐
- oracle ssh测试不通过,ssh 连接不上 oracle linux 7.2
问题描述 oralce linux 可以ssh到其他设备,可是其他设备ssh不上oracle linux ssh username@hostip -v OpenSSH_6.6.1,OpenSSL 1. ...
- oracle stalestats_深入理解oracle优化器统计数据(Optimizer Statistics)
理解oracle优化器统计数据 首先来介绍oracle数据库使用基于规则优化器(RBO)来决定如何执行一个sql语句.基于规则优化器顾名思义,它是遵循一组规则来判断一个sql语句的执行计划.这组规则是 ...
- oracle 压测工具 ld,ORACLE压力测试工具
Swingbench for oracleRAC使用方法图解 1 Swingbench 简述 1.1 概述 这是Oracle UK的一个员工在一个被抛弃的项目的基础上开发的.目前稳定版本2.2,最新版 ...
- Oracle的概念理解
1.了解一些关于数据库的概念 2.了解oracle背景 3.oracle数据库服务器的组成 4.oracle数据库服务器与orcl数据库的关系 5.如何在oracle数据库服务器中创建多个数据库 6. ...
- 用oracle怎么测试,oracle – 如何(单位)测试数据密集的PL / SQL应用程序
有几种不同的PL / sql测试工具. Steven Feuerstein已经写了两个 utplsql和 Quest Code Tester for Oracle(以前的QUTE).我是utplsql ...
- 1.oracle的dump理解一 BH buffer header
1.oracle的dump理解一 BH buffer header 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/5122844 ...
- 论高危职业,测试员坦然垫底,揭秘一个测试员疯狂的全过程!
1.你把时间浇灌在哪里,哪里就会开花结果. 大三在考研与工作的纠结中,我最终选择了工作,据学长学姐的推荐下就这样开始了我的测试学习之路.因为从未接触过,在图书馆借了几本书,越看越发现和学长学姐口中说的 ...
- 斯坦福大学马腾宇:无法理解现有的深度学习算法?那就设计一个能理解的
2020-01-22 05:41:34 作者 | 丛末 编辑 | Camel 本科毕业于清华姚班.博士毕业于普林斯顿大学,师从 Sanjeev Arora 教授,马腾宇作为 AI 学界一颗冉冉升起的新 ...
- LinkedHashMap 的理解以及借助其实现LRU
LinkedHashMap 的理解以及借助其实现LRU LinkedHashMap中有一个参数 accessOrder,这个参数定义了LinkedHashMap的访问顺序. LinkedHashMap ...
最新文章
- 快速原型工具 原型可视化
- Web3.0来了!玩法变了
- ABAP中创建动态内表的三种方法(转载)
- android打印intent flag,Android flag详解
- LeetCode数据库 176. 第二高的薪水
- VIRT,RES,SHR,虚拟内存和物理内存(转)
- 新零售讲堂之时代下的传统零售业,何去何从?
- 大数据治理体系如何搭建
- 运动控制系统课程设计
- SecureCRT for mac 破解安装
- UltraEdit 26 总是偶尔提示运行的是试用模式
- 清华OS前置知识:80386处理器
- 【数据结构】leetcode707:python实现链表设计;leetcode142:环形链表
- 缩放指数型线性单元(SELU)
- 九宫怎么排列和使用_奇门遁甲九宫数字 九宫数字的排列和算法
- 沧小海深入剖析xilinx的GTP/GTX核,掌握高速串行收发机制——第六章 接收端结构及功能说明
- 产品可用性原则:网页设计点睛秘笈
- 在移动硬盘里移动视频文件到移动硬盘 另外一个文件夹 显示正在计算_稳定可靠的数据之仓 柯达X200 SSD固态移动硬盘体验评测...
- golang与手机如何实现一些自动化操作?
- 我是如何从屌丝程序员逆袭成为大厂总监的?
热门文章
- ASDL用户端设备(无线猫)配置及各种设置综合
- error C2365: : redefinition:previous definition was
- [MacOSX]_[Mac Book电脑的快捷键*长期更新]
- 【Leetcode刷题记录_C++】【贪心】
- 5-7课:与二分查找共组双子星座:快速排序
- idm下载器2024官方最新中文版免费下载
- ubuntu 直接安装rails环境
- 【安卓逆向】CTF实战分析
- android fastboot命令大全,ADBFastboot常用命令
- Java在线音乐播放系统的设计与实现