千家信息网

物理读之LRU(最近最少被使用)的深入解析

发表于:2024-11-27 作者:千家信息网编辑
千家信息网最后更新 2024年11月27日,一组LRU链表包括LRU主链,LRU辅助链,LRUW主链,LRUW辅助链,称为一个WorkSet(工作组)如下图:sys@ZMDB> selectCNUM_SET,CNUM_REPL,ANUM_REP
千家信息网最后更新 2024年11月27日物理读之LRU(最近最少被使用)的深入解析

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


sys@ZMDB> selectCNUM_SET,CNUM_REPL,ANUM_REPL,CNUM_WRITE,ANUM_WRITE from x$kcbwds whereCNUM_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:工作组中LRUbuffer总数量(主LRU+LRU

ANUM_REPL:工作组中辅LRUBUFFER的数量

通过隐含参数查到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) LIKEupper('%&p%')

new 12: AND upper(i.ksppinm) LIKEupper('%_db_block_buffers%')

P_NAME P_DESCRIPTION P_VALUE ISDEFAULT ISMODIFIEDISADJ

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

_db_block_buffers Number of database blocks cached inmemory: 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=62480等做出解释,举个例子,对于6是什么含义呢?

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

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

LRU_FLAG LOWER(BA)

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

6 0000000081dae000

DUMP buffer_cacheBH信息,如下命令:

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 TraceFile';

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: 1hint: 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的辅助链表的尾部移动,这有可能是SMONLRU的主链表上的非脏块、TCH<=1并且状态是非PINBUFFER被挂接到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=6LRU_FLAG=4,如果数据库刚刚启来,可能没有LRU_FLAG=6LRU_FLAG=4,那需要做大量的物理读操作,才会有LRU_FLAG=6LRU_FLAG=4

sys@ZMDB> alter system flush buffer_cache;

System altered.

sys@ZMDB> selectlru_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 bufferslevel 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> selectLRU_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,搜索第一次DUMPtrace文件

/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,搜索第二次DUMPtrace文件

/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: 'kdswh21: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)

观察LRUTCH>=2时冷端移到热端

1BUFFER手动设为100M

ALTER SYSTEM SETmemory_max_target=0 scope=spfile;

ALTER SYSTEM SET memory_target=0;

alter system set sga_target=0;

create table gyj1_t80 (idint,name char(2000));

create table gyj2_t80 (idint,name char(2000));

begin

for i in 1 .. 30000

loop

insert into gyj1_t80 values(i,'gyj'||i);

commit;

end loop;

end;

/

SQL> SQL> selectbytes/1024/1024||'M' from dba_segments where segment_name='GYJ1_T80' andowner='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 ongyj1_t80(id);

create index idx_gyj2_t80m ongyj2_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 level1';

Session altered.

SQL> select * fromv$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

selectid,name,dbms_rowid.rowid_relative_fno(rowid)file#,dbms_rowid.rowid_block_number(rowid) block# from gyj1_t80 where id=1;

SQL> selectid,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),TCHfrom 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 anddbablk=581;

LRU_FLAG LOWER(BA) TCH DECODE(STA

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

0 000000009fca8000 1 xcur

SQL> selectLRU_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) fromgyj1_t80 G where id<=8000;

SQL> selectLRU_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

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

0000000009fca8000 8

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

LRU_FLAG LOWER(BA) TCH

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

8000000009fca8000 0

BH (0x9ffe02a8) file#: 5 rdba: 0x01400245 (5/581) class: 1 ba:0x9fca8000

set: 5 pool: 3 bsz: 8192bsi: 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时,再发生大量物理读,地址为9fca8000BUFFER就被重用了,彻底从BUFFER消失

SQL> selectLRU_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 wherefile#=5 and dbablk=581;

no rows selected

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


物理 辅助 尾部 工作组 工作 数量 文件 端的 第一次 搜索 特殊 再次 含义 头部 数据 数据库 状态 面的 实验 解释 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 链接数据库显示无监听程序 蜀门游戏怎么退出服务器 海南推广软件开发商家 产品软件开发管理国家标准 网络安全与意思形态的关系 数据库空白数据怎么弄 数据库技术及应用教材答案 密云韩各庄有软件开发公司吗 可视化窗口连接数据库 云龙服务器 现在的最新的网络技术 关闭数据库连接池连接 西安泛在网络技术创新型产业 关于宣讲会问网络安全的问题 议论文网络安全的重要 英雄联盟地图对应的服务器 随机单方块生存服务器推荐 与网络安全相关的算法 绝地求生哪个服务器可以免费玩 熊片数据库正式版 国内云服务器代理项目网络平台 康定天气预报软件开发 中国科学技术学会阿里数据库 如何保证服务器系统安全 路由器的网络安全设置在哪 数据库设计需要的技术 检测局域网服务器 网络安全 虚拟专用网络 sql联合查询两个数据库不同 数据库技术的特点是数据结构化
0