1. 深入了解 Oracle 自动内
存管理 ASMM
by Maclean.liu
liu.maclean@gmail.com
www.oracledatabase12g.com
2. About Me
l Email:liu.maclean@gmail.com
l Blog:www.oracledatabase12g.com
l Oracle Certified Database Administrator Master 10g
and 11g
l Over 6 years experience with Oracle DBA technology
l Over 7 years experience with Linux technology
l Member Independent Oracle Users Group
l Member All China Users Group
l Presents for advanced Oracle topics: RAC,
DataGuard, Performance Tuning and Oracle Internal.
5. 修改 sga_target 参数,前提是所在的系统平台支持动态地共享内存(dism,主流平台都支持)。使用 ASMM 的一个
必要条件是初始化参数 statistics_level 必须设置为 typical 或 ALL,如果设置为 BASIC 那么 MMON 后台进程
(Memory Monitor is a background process that gathers memory statistics (snapshots) stores this information in
the AWR (automatic workload repository). MMON is also responsible for issuing alerts for metrics that exceed
their thresholds)将无法有效分析内存的使用的统计信息从而驱动 ASMM 的自动调优,实际上我们不能同时设置
sga_target 为非零值和 statistics_level 为 BASIC:
SQL> show parameter sga
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 2000M
sga_target big integer 2000M
SQL> show parameter sga_target
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sga_target big integer 2000M
SQL> alter system set statistics_level=BASIC;
alter system set statistics_level=BASIC
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00830: cannot set statistics_level to BASIC with auto-tune SGA enabled
如果使用了 server parameter file 即 spfile 的话,ASMM 会在实例 shutdown 之前将当前实际的内存组件大小
(Oracle 认为这是最优的,但实际上可能不是)保存到 spfile 中,如果你使用 strings 命令打印过 spfile 的内容的可
以发现一些以双下划线开头的参数,如:
G10R2.__db_cache_size=973078528
G10R2.__java_pool_size=16777216
G10R2.__large_pool_size=16777216
G10R2.__shared_pool_size=1006632960
G10R2.__streams_pool_size=67108864
这些在 spfile 保存的组件大小会在下次启动时被沿用,以达到将已经实践得出的”最佳值”记住的目的,这样下次就
不用从头再”学习”了。
9. 3. _memory_management_tracing: 该参数控制针对 MMON 和 MMAN 后台进程包括内存建议
(advisor)和内存代理(Memory Broker)决议的相关 trace 的级别;针对 ORA-04031 的诊断可以设置
为 36,设置为 8 启用针对启动期间组件大小的 trace,设置为 23 启动针对 Memory Broker decision
的跟踪,设置为 32 将转储 cache resize 的细节;该参数的具体级别如下:
Level Contents
0×01 Enables statistics tracing
0×02 Enables policy tracing
Enables transfer of granules
0×04
tracing
0×08 Enables startup tracing
0×10 Enables tuning tracing
0×20 Enables cache tracing
接下来我们通过设置_memory_management_tracing 隐藏参数和 DUMP_TRANSFER_OPS 转储来实地了解一次
完整的内存转移,和不完整的内存转移。以下演示的完整 trace 文件可以从这里下载
mman_trace、transfer_ops_dump。
SQL> alter system set "_memory_management_tracing"=63;
System altered
Operation make shared pool grow and buffer cache shrink!!!..............
以下为一个完整 granule 转移的过程,包括了对 default buffer pool 的 resize 操作:
AUTO SGA: Request 0xdc9c2628 after pre-processing, ret=0
/* 这里的 0xdc9c2628 是前台进程的 addr */
AUTO SGA: IMMEDIATE, FG request 0xdc9c2628
/* 这里可以看到前台进程的 Immediate 立即申请 */
AUTO SGA: Receiver of memory is shared pool, size=16, state=3, flg=0
/* 此次申请的收益人是 shared pool,共享池,其大小为 16 个 granule,处于 grow 状态 */
10. AUTO SGA: Donor of memory is DEFAULT buffer cache, size=106, state=4, flg=0
/* 此处的捐献者是 Default buffer cache,高速缓存,其大小为 106 个 granule,处于 shrink 状态 */
AUTO SGA: Memory requested=3896, remaining=3896
/* 这里 immeidate request 所要求的空间是 3896 bytes */
AUTO SGA: Memory received=0, minreq=3896, gransz=16777216
/* 这里没有 free 的 granule,所以 received 为 0,gransz 为 granule 的大小 */
AUTO SGA: Request 0xdc9c2628 status is INACTIVE
/* 因为没有空的内存颗粒,先将申请置于 inactive 状态 */
AUTO SGA: Init bef rsz for request 0xdc9c2628
/* 为相关申请初始化 before-process 大小调整 */
AUTO SGA: Set rq dc9c2628 status to PENDING
/* 将 request 置于 pending 状态 */
AUTO SGA: 0xca000000 rem=3896, rcvd=16777216, 105, 16777216, 17
/* 返回起始地址为 0xca000000 的 16M 大小 granule */
AUTO SGA: Returning 4 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 4, 1, a
AUTO SGA: Resize done for pool DEFAULT, 8192
/* 完成对 default pool 的 resize */
AUTO SGA: Init aft rsz for request 0xdc9c2628
AUTO SGA: Request 0xdc9c2628 after processing
AUTO SGA: IMMEDIATE, FG request 0x7fff917964a0
AUTO SGA: Receiver of memory is shared pool, size=17, state=0, flg=0
AUTO SGA: Donor of memory is DEFAULT buffer cache, size=105, state=0, flg=0
AUTO SGA: Memory requested=3896, remaining=0
AUTO SGA: Memory received=16777216, minreq=3896, gransz=16777216
11. AUTO SGA: Request 0x7fff917964a0 status is COMPLETE
/* shared pool 成功收到 16M 的 granule */
AUTO SGA: activated granule 0xca000000 of shared pool
以下为一个 partial granule 不完全内存颗粒的转移过程 trace:
AUTO SGA: Request 0xdc9c2628 after pre-processing, ret=0
AUTO SGA: IMMEDIATE, FG request 0xdc9c2628
AUTO SGA: Receiver of memory is shared pool, size=82, state=3, flg=1
AUTO SGA: Donor of memory is DEFAULT buffer cache, size=36, state=4, flg=1
/* 此处的受益者仍为 shared pool,而捐献者是 default buffer cache */
AUTO SGA: Memory requested=4120, remaining=4120
AUTO SGA: Memory received=0, minreq=4120, gransz=16777216
AUTO SGA: Request 0xdc9c2628 status is INACTIVE
AUTO SGA: Init bef rsz for request 0xdc9c2628
AUTO SGA: Set rq dc9c2628 status to PENDING
AUTO SGA: Moving granule 0x93000000 of DEFAULT buffer cache to activate list
AUTO SGA: Moving 1 granule 0x8c000000 from inuse to quiesce list of DEFAULT buffer cache
for an immediate req
/* 以上将 buffer cache 中起始地址为 0x8c000000 的 granule 从使用中列表 inuse list,
移动到静默列表 quiesce list 中 */
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: activated granule 0x93000000 of DEFAULT buffer cache
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
/ * 等待 dbwr 写出 0x8c000000 granule 中所有的 dirty buffer */
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
12. AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
AUTO SGA: Returning 0 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 0, 1, 20a
AUTO SGA: NOT_FREE for imm req for gran 0x8c000000
.........................................
AUTO SGA: Rcv shared pool consuming 8192 from 0x8c000000 in granule 0x8c000000; owner is
DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 90112 from 0x8c002000 in granule 0x8c000000; owner is
DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 24576 from 0x8c01a000 in granule 0x8c000000; owner is
DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 65536 from 0x8c022000 in granule 0x8c000000; owner is
DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 131072 from 0x8c034000 in granule 0x8c000000; owner
is DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 286720 from 0x8c056000 in granule 0x8c000000; owner
is DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 98304 from 0x8c09e000 in granule 0x8c000000; owner is
DEFAULT buffer cache
AUTO SGA: Rcv shared pool consuming 106496 from 0x8c0b8000 in granule 0x8c000000; owner
is DEFAULT buffer cache
.....................
/* 以上 shared pool 开始消费 0x8c000000 granule 中的 chunk,
但此 granule 的 owner 暂时仍为 default buffer cache */
AUTO SGA: Imm xfer 0x8c000000 from quiesce list of DEFAULT buffer cache to partial inuse
list of shared pool
/* 以上将 0x8c000000 granule 从 default buffer cache 的静默列表转移到 shared pool 的不完整 inuse
list */
AUTO SGA: Returning 4 from kmgs_process for request dc9c2628
AUTO SGA: Process req dc9c2628 ret 4, 1, 20a
AUTO SGA: Init aft rsz for request 0xdc9c2628
AUTO SGA: Request 0xdc9c2628 after processing
AUTO SGA: IMMEDIATE, FG request 0x7fffe9bcd0e0
AUTO SGA: Receiver of memory is shared pool, size=83, state=0, flg=1
AUTO SGA: Donor of memory is DEFAULT buffer cache, size=35, state=0, flg=1
13. AUTO SGA: Memory requested=4120, remaining=0
AUTO SGA: Memory received=14934016, minreq=4120, gransz=16777216
AUTO SGA: Request 0x7fffe9bcd0e0 status is COMPLETE
/* 以上一个 partial transfer 完成 */
对应于以上 partial transfer 我们可以通过 DUMP_TRANSFER_OPS 来了解该 0x8c000000 partial granule 的实际
使用情况,如:
SQL> oradebug setmypid;
Statement processed.
SQL> oradebug dump DUMP_TRANSFER_OPS 1;
Statement processed.
SQL> oradebug tracefile_name;
/s01/admin/G10R2/udump/g10r2_ora_21482.trc
=======================trace content==============================
GRANULE SIZE is 16777216
COMPONENT NAME : shared pool
Number of granules in partially inuse list (listid 4) is 23
Granule addr is 0x8c000000 Granule owner is DEFAULT buffer cache
/* 该 0x8c000000 granule 在 shared pool 的 partially inuse list,
但这里它的 owner 仍为 default buffer cache */
Granule 0x8c000000 dump from owner perspective
gptr = 0x8c000000, num buf hdrs = 1989, num buffers = 156, ghdr = 0x8cffe000
/ * 可以看到该 granule 的 granule header 地址位于 0x8cffe000,
其中共有 156 个 buffer block,1989 个 buffer header */
/* 以下 granule 中具体的内容,实际既包含了 buffer cache 也有 shared pool chunk */
BH:0x8cf76018 BA:(nil) st:11 flg:20000
BH:0x8cf76128 BA:(nil) st:11 flg:20000
BH:0x8cf76238 BA:(nil) st:11 flg:20000
BH:0x8cf76348 BA:(nil) st:11 flg:20000
BH:0x8cf76458 BA:(nil) st:11 flg:20000
BH:0x8cf76568 BA:(nil) st:11 flg:20000
14. BH:0x8cf76678 BA:(nil) st:11 flg:20000
BH:0x8cf76788 BA:(nil) st:11 flg:20000
BH:0x8cf76898 BA:(nil) st:11 flg:20000
BH:0x8cf769a8 BA:(nil) st:11 flg:20000
BH:0x8cf76ab8 BA:(nil) st:11 flg:20000
BH:0x8cf76bc8 BA:(nil) st:11 flg:20000
BH:0x8cf76cd8 BA:0x8c018000 st:1 flg:622202
...............
Address 0x8cf30000 to 0x8cf74000 not in cache
Address 0x8cf74000 to 0x8d000000 in cache
Granule 0x8c000000 dump from receivers perspective
Dumping layout
Address 0x8c000000 to 0x8c018000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c018000 to 0x8c01a000 not in this pool
Address 0x8c01a000 to 0x8c020000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c020000 to 0x8c022000 not in this pool
Address 0x8c022000 to 0x8c032000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c032000 to 0x8c034000 not in this pool
Address 0x8c034000 to 0x8c054000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c054000 to 0x8c056000 not in this pool
Address 0x8c056000 to 0x8c09c000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c09c000 to 0x8c09e000 not in this pool
Address 0x8c09e000 to 0x8c0b6000 in sga heap(1,3) (idx=1, dur=4)
Address 0x8c0b6000 to 0x8c0b8000 not in this pool
Address 0x8c0b8000 to 0x8c0d2000 in sga heap(1,3) (idx=1, dur=4)
以上可以看到该 granule 真的是一个 shared granule 共享内存颗粒,其中不仅包含了部分 buffer block,还包含了
1 号 shared subpool 共享池子池的 durtaion 为 4 的 chunk,duration=4 即 execution duration;这类 duration 的
chunk 一般有着较短的生命周期,当其 extent 被置于 quiesce list 静默列表时将很有可能变得足够
free。execution duration 是共享池中唯一能可靠转移的,因此唯有该类 duration 所在的 extent(一般来说一个
extent 占用一个 granule)可以用来收缩。