转载请注明出处:

http://blog.csdn.net/guoyjoe/article/details/38264883

一组LRU链表包含LRU主链。LRU辅助链。LRUW主链,LRUW辅助链,称为一个WorkSet(工作组)例如以下图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VveUpvZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

sys@ZMDB> select CNUM_SET,CNUM_REPL,ANUM_REPL,CNUM_WRITE,ANUM_WRITE from x$kcbwds where CNUM_SET>0;

  CNUM_SET  CNUM_REPL  ANUM_REPL CNUM_WRITE ANUM_WRITE
---------- ---------- ---------- ---------- ----------
15221 15221 3796 0 0
15221 15221 3783 0 0

CNUM_SET:工作组总的buffer总数量

CNUM_REPL:工作组中LRU的buffer总数量(主LRU+辅LRU)

ANUM_REPL:工作组中辅LRU总BUFFER的数量

通过隐含參数查到BUFFER的总的个数是30442,正好与上面的CNUM_SET=15221+15221

sys@ZMDB> @?/rdbms/admin/show_para
Enter value for p: _db_block_buffers
old 12: AND upper(i.ksppinm) LIKE upper('%&p%')
new 12: AND upper(i.ksppinm) LIKE upper('%_db_block_buffers%') P_NAME P_DESCRIPTION P_VALUE ISDEFAULT ISMODIFIED ISADJ
---------------------------------------- -------------------------------------------------- ------------------------------ --------- ---------- -----
_db_block_buffers Number of database blocks cached in memory: hidden 30442 TRUE FALSE FALSE
Parameter

我们用下面语句查下数据库中buffer所在LRU的状态

sys@ZMDB> select lru_flag,count(*) from x$bh group by lru_flag;

  LRU_FLAG   COUNT(*)
---------- ----------
6 208
2 10
4 7122
8 15199
0 7646

我们对LRU_FLAG=6。2。4,8,0等做出解释。举个样例,对于6是什么含义呢?

首先要在x$bh中找到lru_flag=6的随意的一个BUFFER

sys@ZMDB> select LRU_FLAG,LOWER(BA)from x$bh where lru_flag=6 and rownum=1;

  LRU_FLAG LOWER(BA)
---------- ----------------
6 0000000081dae000

DUMP buffer_cache中BH信息,例如以下命令:

sys@ZMDB> alter session set events'immediate trace name buffers level 1';

Session altered.
ys@ZMDB> col value for a85
sys@ZMDB> select * from v$diag_info where name='Default Trace File'; INST_ID NAME VALUE
---------- -------------------------------------------------- -------------------------------------------------------------------------------------
1 Default Trace File /u01/app/oracle/diag/rdbms/zmdb/zmdb/trace/zmdb_ora_13235.trc

通过BA=81dae000搜索trace文件。

/u01/app/oracle/diag/rdbms/zmdb/zmdb/trace/zmdb_ora_13235.trc

得到例如以下内容:

BH (0x81fe7e38) file#: 1 rdba: 0x0040ace1 (1/44257) class: 1 ba: 0x81dae000
set: 6 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,25
dbwrid: 0 obj: 421 objn: 423 tsn: 0 afn: 1 hint: f
hash: [0x9ef9d710,0x853f8da8] lru: [0x81fe7df0,0x81fe8050]
lru-flags: moved_to_tail on_auxiliary_list
ckptq: [NULL] fileq: [NULL] objq: [NULL] objaq: [NULL]
st: CR md: NULL fpin: 'kdswh06: kdscgr' tch: 1
cr: [scn: 0x0.80350f4d],[xid: 0x0.0.0],[uba: 0x0.0.0],[cls: 0x0.80350f4d],[sfl: 0x0],[lc: 0x0.8034c532]
flags: block_written_once redo_since_read

LRU_FLAG=6的意思是lru-flags:moved_to_tail on_auxiliary_list,就是向LRU的辅助链表的尾部移动,这有可能是SMON从LRU的主链表上的非脏块、TCH<=1而且状态是非PIN的BUFFER被挂接到LRU辅助链表的尾部。

依据以上的方法同理能够解释出LRU_FLAG的含义:

LRU_FLAG

0==>LRU-主链冷端的头部,这个比較特殊他在DUMP没有显示LRU_FLAG

2==>LRU-主链冷端的尾部。lru-flags:moved_to_tail

4==>LRU-辅助链,lru-flags:on_auxiliary_list

6==>LRU-辅助链的尾部。lru-flags:moved_to_tail on_auxiliary_list

8==>LUR-主链热端,lru-flags:hot_buffer

当发生物理读时。Oracle会从LRU辅助链表找空暇的BUFFER,然后把LRU辅助的链上的BUFFER挂接到LRU主链的冷端头。实验例如以下:

首先要保证有LRU辅助链上的BUFFER,即有LRU_FLAG=6或LRU_FLAG=4,假设数据库刚刚启来,可能没有LRU_FLAG=6、LRU_FLAG=4,那须要做大量的物理读操作。才会有LRU_FLAG=6或LRU_FLAG=4

sys@ZMDB> alter system flush buffer_cache;

System altered.

sys@ZMDB> select lru_flag,count(*) from x$bh group by lru_flag;

  LRU_FLAG   COUNT(*)
---------- ----------
6 208
4 30009
0 2

第一次DUMP整个BUFFER CACHE:

sys@ZMDB> alter session set events'immediate trace name buffers level 1';
/u01/app/oracle/diag/rdbms/zmdb/zmdb/trace/zmdb_ora_13480.trc

发生物理读

gyj@ZMDB> conn gyj/gyj
Connected.
gyj@ZMDB> set autot on;
gyj@ZMDB> select id,name, dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from gyj_t1 where id=1; ID NAME FILE# BLOCK#
---------- ------------------------------ ---------- ----------
1 gyj1 7 139 Execution Plan
----------------------------------------------------------
Plan hash value: 59758809 ----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 14 | 68 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| GYJ_T1 | 1 | 14 | 68 (0)| 00:00:01 |
---------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("ID"=1) Statistics
----------------------------------------------------------
1 recursive calls
1 db block gets
254 consistent gets
248 physical reads
0 redo size
733 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed sys@ZMDB> select LRU_FLAG,lower(BA),TCH from x$bh where file#=7 and dbablk=139; LRU_FLAG LOWER(BA) TCH
---------- ---------------- ----------
0 000000007d1b2000 1
4 0000000078558000 0
4 0000000085f68000 0

物理读完毕后。再次dump整个buffer cache,

sys@ZMDB> alter session set events'immediate trace name buffers level 1';

/u01/app/oracle/diag/rdbms/zmdb/zmdb/trace/zmdb_ora_13511.trc

拿BA=7d1b2000,搜索第一次DUMP的trace文件

/u01/app/oracle/diag/rdbms/zmdb/zmdb/trace/zmdb_ora_13480.trc

BH (0x7d3e8098) file#: 3 rdba: 0x00c0586b (3/22635) class: 34 ba: 0x7d1b2000
set: 5 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,25
dbwrid: 0 obj: -1 objn: 0 tsn: 2 afn: 3 hint: f
hash: [0x9efa7570,0x9efa7570] lru: [0x7f7f5d30,0x7d3e8050]
lru-flags: on_auxiliary_list
ckptq: [NULL] fileq: [NULL] objq: [NULL] objaq: [NULL]
st: FREE md: NULL fpin: 'ktuwh03: ktugnb' tch: 0 lfb: 33
flags:

拿BA=7d1b2000,搜索第二次DUMP的trace文件

/u01/app/oracle/diag/rdbms/zmdb/zmdb/trace/zmdb_ora_13511.trc

BH (0x7d3e8098) file#: 7 rdba: 0x01c0008b (7/139) class: 1 ba: 0x7d1b2000
set: 5 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,25
dbwrid: 0 obj: 22919 objn: 19567 tsn: 7 afn: 7 hint: f
hash: [0x787e4bd8,0x9e4cda50] lru: [0x7f7f5d30,0x7d3e8050]
ckptq: [NULL] fileq: [NULL] objq: [0x9a88e518,0x7d3e8078] objaq: [0x9a88e508,0x7d3e8088]
st: XCURRENT md: NULL fpin: 'kdswh11: kdst_fetch' tch: 1
flags: only_sequential_access
LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [65535]

从上面的两个trace能够得出结论ba: 0x7d1b2000

从lru-flags: on_auxiliary_list(LRU_FLAG=4)到LRU-主链冷端的头部,这个比較特殊在DUMP没有显示LRU_FLAG(LRU_FLAG=0)

观察LRU TCH>=2时冷端移到热端

1、BUFFER手动设为100M

ALTER SYSTEM SET memory_max_target=0 scope=spfile;
ALTER SYSTEM SET memory_target=0;
alter system set sga_target=0; create table gyj1_t80 (id int,name char(2000)); create table gyj2_t80 (id int,name char(2000)); begin
for i in 1 .. 30000
loop
insert into gyj1_t80 values(i,'gyj'||i);
commit;
end loop;
end;
/ SQL> SQL> select bytes/1024/1024||'M' from dba_segments where segment_name='GYJ1_T80' and owner='GYJ'; BYTES/1024/1024||'M'
-----------------------------------------
80M begin
for i in 1 .. 30000
loop
insert into gyj2_t80 values(i,'gyj'||i);
commit;
end loop;
end;
/ create index idx_gyj1_t80m on gyj1_t80(id); create index idx_gyj2_t80m on gyj2_t80(id); SQL> show user;
USER is "GYJ"
SQL> conn / as sysdba
Connected.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

第一次dump

SQL> alter session set events'immediate trace name buffers level 1';

Session altered.

SQL> select * from v$diag_info where name='Default Trace File';

   INST_ID NAME
---------- --------------------
VALUE
--------------------------------------------------------------------------------
1 Default Trace File
/u01/app/oracle/diag/rdbms/jfdb/jfdb/trace/jfdb_ora_7210.trc

发生一个物理读走索引

set autot on
select id,name,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from gyj1_t80 where id=1; SQL> select id,name,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from gyj1_t80 where id=1; ID NAME FILE# BLOCK#
---------- -------------------- ---------- ----------
1 gyj1 5 581 select LRU_FLAG,lower(BA),TCH from x$bh where file#=5 and dbablk=581;
SQL> select LRU_FLAG,lower(BA),TCH, decode(state,0,'free',1,'xcur',2,'scur'
2 ,3,'cr', 4,'read',5,'mrec',6,'irec',7,'write',8,'pi', 9,'memory',10,'mwrite',11,
3 'donated', 12,'protected', 13,'securefile', 14,'siop',15,'recckpt', 16, 'flashf
4 ree', 17, 'flashcur', 18, 'flashna') from x$bh where file#=5 and dbablk=581; LRU_FLAG LOWER(BA) TCH DECODE(STA
---------- ---------------- ---------- ----------
0 000000009fca8000 1 xcur SQL> select LRU_FLAG,lower(BA),TCH from x$bh where file#=5 and dbablk=581; LRU_FLAG LOWER(BA) TCH
---------- ---------------- ----------
0 000000009fca8000 5 SQL> set autot traceonly;
SQL> select /*+ index(G) */ count(name) from gyj1_t80 G where id<=8000; SQL> select LRU_FLAG,lower(BA),TCH from x$bh where file#=5 and dbablk=581; LRU_FLAG LOWER(BA) TCH
---------- ---------------- ----------
0 000000009fca8000 6

再次发生物理读,此时LRU_FLAG=0变为8,同一时候TCH=8重置为0

SQL> select LRU_FLAG,lower(BA),TCH from x$bh where file#=5 and dbablk=581;

  LRU_FLAG LOWER(BA)               TCH
---------- ---------------- ----------
0 000000009fca8000 8 SQL> select LRU_FLAG,lower(BA),TCH from x$bh where file#=5 and dbablk=581; LRU_FLAG LOWER(BA) TCH
---------- ---------------- ----------
8 000000009fca8000 0 BH (0x9ffe02a8) file#: 5 rdba: 0x01400245 (5/581) class: 1 ba: 0x9fca8000
set: 5 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 15,19
dbwrid: 0 obj: 13537 objn: 13537 tsn: 5 afn: 5 hint: f
hash: [0xb6a86de0,0xb6a86de0] lru: [0x9ffe0260,0x9ffe9a60]
lru-flags: hot_buffer
ckptq: [NULL] fileq: [NULL] objq: [0x9ffe0618,0x9ffe0028] objaq: [0x9ffe0628,0x9ffe0038]
st: XCURRENT md: NULL fpin: 'kdswh05: kdsgrp' tch: 0
flags:
LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [65535]

当TCH=0时。再发生大量物理读,地址为9fca8000的BUFFER就被重用了,彻底从BUFFER消失

SQL>  select LRU_FLAG,lower(BA),TCH from x$bh where file#=5 and dbablk=581;

  LRU_FLAG LOWER(BA)               TCH
---------- ---------------- ----------
8 000000009fca8000 0 SQL> select LRU_FLAG,lower(BA),TCH from x$bh where file#=5 and dbablk=581;
no rows selected 

通过实验。我们更清楚地了解到物理读LRU的基本流程。能够进一步理解物理读内部的LRU算法。

物理读之LRU(近期最少被使用)的深入解析的更多相关文章

  1. LRU近期最少使用算法

    LRU(least recently used)最少使用. 假设 序列为 4 3 4 2 3 1 4 2 物理块有3个 则 首轮 4调入内存 4 次轮 3调入内存 3 4 之后 4调入内存 4 3 之 ...

  2. [LeetCode] 146. LRU Cache 近期最少使用缓存

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  3. 边缘节点 如何判断CDN的预热任务是否执行完成刷新 路由追踪 近期最少使用算法

    阿里云内容分发网络(Content Delivery Network,简称CDN)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络.阿里云CDN分担源站压力,避免网络拥塞, ...

  4. DB_FILE_MULTIBLOCK_READ_COUNT对物理读和IO次数的影响

    当执行SELECT语句时,如果在内存里找不到相应的数据,就会从磁盘读取进而缓存至LRU末端(冷端),这个过程就叫物理读.当相应数据已在内存,就会逻辑读. 物理读是磁盘读,逻辑读是内存读:内存读的速度远 ...

  5. 初谈SQL Server逻辑读、物理读、预读

    前言 本文涉及的内容均不是原创,是记录自己在学习IO.执行计划的过程中学习其他大牛的博客和心得并记录下来,之所以想写下来是为了记录自己在追溯的过程遇到的几个问题,并把这些问题弄清楚. 本章最后已贴出原 ...

  6. ORACLE 物理读 逻辑读 一致性读 当前模式读总结浅析

    在ORACLE数据库中有物理读(Physical Reads).逻辑读(Logical Reads).一致性读(Consistant Get).当前模式读(DB Block Gets)等诸多概念,如果 ...

  7. SQL Server逻辑读、预读和物理读

    SQL Server数据存储的形式 预读:用估计信息,去硬盘读取数据到缓存.预读100次,也就是估计将要从硬盘中读取了100页数据到缓存. 物理读:查询计划生成好以后,如果缓存缺少所需要的数据,让缓存 ...

  8. SQL Server 中的逻辑读与物理读

    首先要理解逻辑读和物理读: 预读:用估计信息,去硬盘读取数据到缓存.预读100次,也就是估计将要从硬盘中读取了100页数据到缓存. 物理读:查询计划生成好以后,如果缓存缺少所需要的数据,让缓存再次去读 ...

  9. SQL SERVER中的逻辑读,预读和物理读

    sqlserver:数据存储方式:最小单位是页,每一页8k,sqlserver 对页的读取是具有原子性,也就是说,要么读取完整一页,要么完全不读取,不会有中间状态,而页之间的数据组织结构是B树 但是每 ...

随机推荐

  1. oracle 的列转行函数 listagg()

    当你的表X中有A,B两列,数据如下 A B a 1 a 2 a 3 b 1 b 2 b 3 想让数据以 a|1|2|3 , b|1|2|3 格式显示可使用listagg() 1.使用listagg() ...

  2. MyBatis学习总结(5)——实现关联表查询

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

  3. dubbo标签

    <dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心. <dubbo:reference/&g ...

  4. [Gatsby] Install Gatsby and Scaffold a Blog

    In this lesson, you’ll install Gatsby and the plugins that give the default starter the ability to t ...

  5. UVA 11294 - Wedding(Two-Set)

    UVA 11294 - Wedding 题目链接 题意:有n对夫妻,0号是公主.如今有一些通奸关系(男男,女女也是可能的)然后要求人分配在两側.夫妻不能坐同一側.而且公主对面一側不能有两个同奸的人,问 ...

  6. JavaScript学习记录三

    title: JavaScript学习记录三 toc: true date: 2018-09-14 23:51:22 --<JavaScript高级程序设计(第2版)>学习笔记 要多查阅M ...

  7. POJ 3261 后缀数组+二分

    思路: 论文题- 二分+对后缀分组 这块一开始不用基数排序 会更快的(其实区别不大) //By SiriusRen #include <cstdio> #include <cstri ...

  8. BZOJ 2096 单调队列

    思路: 偷懒用的STL //By SiriusRen #include <deque> #include <cstdio> using namespace std; struc ...

  9. ios上有时候提交按钮点击两次才可以取消输入框软键盘

    ios上有时候提交按钮点击两次才可以取消输入框软键盘,点击第一次软键盘消失,点击第二次输入框页面消失,这样用户体验不好.我的做法是用 touchstart 代替click来处理 反应快,但是有时候会出 ...

  10. node.js连接数据库基本操作、封装数据库操作,输出到网页

    声明:以下代码测试通过,不同于直接的复制粘贴乱七八糟未测试的代码,完全可以用,最后会附上所有的代码和sql文件 首先建立表,建表语句如下: /* SQLyog Ultimate v12.08 (64 ...