第1章 章名章名章名章名章名
mmap2(0xb5e84000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5e84000
mmap2(0xb5e94000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5e94000
mmap2(0xb5ea4000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5ea4000
mmap2(0xb5ec4000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5ec4000
mmap2(0xb5ee4000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5ee4000
mmap2(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE, 7, 0x1f4) = 0xb5c84000 mmap2(0xb5c84000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5c84000
mmap2(0xb5ca4000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5ca4000
mmap2(0xb5cc4000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5cc4000
mmap2(0xb5ce4000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0) = 0xb5ce4000
munmap(0xb5c84000, 1048576) = 0 munmap(0xb5e84000, 524288) = 0 times(NULL) = 32667141
write(11, \read(8, \times(NULL) = 32667142 times(NULL) = 32667142
write(11, \read(8,
注意以上输出,在SQL执行过程中,进行了两块内存分配,通过mmap调用实现,在执行完毕之后,通过munmap来释放了两块连续的内存。
而如果设置_use_realfree_heap为False,再来转储进程HEAP空间: SQL> alter system set \
System altered.
SQL> ALTER SESSION SET EVENTS 'immediate trace name heapdump level 1';
Session altered.
可以看到进程HEAP此次仅分配了一个PGA HEAP:
·21·
书名书名书名书名书名书名书名书名书名书名书名书名书名书名
[oracle@test udump]$ grep HEAP mmstest_ora_5929.trc HEAP DUMP heap name=\
这就是自动的PGA管理和Oracle9i之前手动的PGA管理的区别所在。
5.2 SGA管理
SGA指系统全局区(System Global Area),是一块用于加载数据、对象并保存运行状态和数据库控制信息的一块内存区域,在数据库实例启动时分配,当实例关闭时释放,每个实例都拥有自己的SGA区。
在第一章曾经提到,当数据库启动到nomount状态时,SGA已经分配,同时启动后台进程,在SQL*Plus中通过show sga命令可以看到SGA的分配情况:
SQL> show sga
Total System Global Area 338390716 bytes Fixed Size 102076 bytes Variable Size 133308416 bytes Database Buffers 204800000 bytes Redo Buffers 180224 bytes
连接到Oracle数据库的用户都可以共享SGA中的数据,通常为了更优化的性能,我们总是期望在物理内存允许的情况下,设置更高的SGA区,以减少物理I/O(SGA中数据缓冲区的增大可以有效地减少物理读)。
5.1.1 SGA的组成
下图是最常见的数据库实例体系结构图,展现了SGA的结构:
·22·
第1章 章名章名章名章名章名
1. 固定区域 - Fixed Area
Fixed Size 部分是SGA中的固定部分,包含几千个变量和一些小的数据结构,如Latch或地址指针等,这部分内存分配和特定的数据库版本以及平台有关,不受用户控制,而且这些信息对于数据库来说非常重要,但是通常我们用户不需要关心。
固定部分只需要很小的内存,可以通过一个内部表X$KSMFSV([K]ernel [S]ervice Layer ,[M]emory Management,Addresses of [F]ixed [S]GA [V]ariables)查询。此外Oracle的内部表X$KSMMEM记录了整个SGA的地址映射关系,通过X$KSMFSV和X$KSMMEM关联,可以找出Fixed Area中每个变量的设置。
在32位平台上,X$KSMMEM表中每条记录代表4 Bytes,在64位平台,每条记录代表4 Bytes:
SQL> select banner from x$version where indx in (0,3); BANNER
---------------------------------------------------------------- Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production TNS for Solaris: Version 9.2.0.4.0 – Production SQL> show sga
Total System Global Area 2400687424 bytes SQL> select count(*) from x$ksmmem; COUNT(*) ---------- 300085928
SQL> select 2400687424/300085928 from dual; 2400687424/300085928 -------------------- 8
SQL> select * from x$ksmmem where rownum <5; ADDR INDX INST_ID KSMMMVAL
---------------- ---------- ---------- ---------------- 0000000380000000 0 1 0000000000000EEE 0000000380000008 1 1 0920040000000001 0000000380000010 2 1 00 0000000380000018 3 1 00
以下是32位Linux平台的设置情况:
SQL> select banner from x$version where indx in (0,3); BANNER
-------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production TNS for Linux: Version 11.1.0.6.0 - Production
·23·
书名书名书名书名书名书名书名书名书名书名书名书名书名书名
SQL> select count(*) from x$ksmmem; COUNT(*) ---------- 130777088 SQL> show sga
Total System Global Area 523108352 bytes SQL> select 523108352/130777088 from dual; 523108352/130777088 ------------------- 4
在修改某些相关参数及变量时,可以看到内存中相关变量的改变:
SQL> select a.ksmfsnam,b.ksmmmval,b.addr from x$ksmfsv a, x$ksmmem b 2 where a.ksmfsadr=b.addr and a.ksmfsnam like 'sgaflg%'; KSMFSNAM KSMMMVAL ADDR -------------------- -------- -------- sgaflg_ 0070021A 2001A3C0 SQL> alter system disable distributed recovery; System altered.
SQL> select a.ksmfsnam,b.ksmmmval,b.addr from x$ksmfsv a, x$ksmmem b 2 where a.ksmfsadr=b.addr and a.ksmfsnam like 'sgaflg%'; KSMFSNAM KSMMMVAL ADDR -------------------- -------- -------- sgaflg_ 00700212 2001A3C0 SQL> alter system enable distributed recovery; System altered.
SQL> select a.ksmfsnam,b.ksmmmval,b.addr from x$ksmfsv a, x$ksmmem b 2 where a.ksmfsadr=b.addr and a.ksmfsnam like 'sgaflg%'; KSMFSNAM KSMMMVAL ADDR -------------------- -------- -------- sgaflg_ 0070021A 2001A3C0
通过oradebug也可以看到类似变化:
SQL> oradebug setmypid
SQL> oradebug dumpvar sga sgaflg
SQL> alter system disable distributed recovery; SQL> oradebug dumpvar sga sgaflg
SQL> alter system enable distributed recovery; SQL> oradebug dumpvar sga sgaflg
此外我们知道SCN就记录在Fixed Size内存之中,Oracle使用32位来存储SCN值,可以查询获得这个信息:
·24·
第1章 章名章名章名章名章名
SYS@WAPDBS>select ksmfsnam,ksmfssiz from x$ksmfsv 2 where ksmfsnam='kcsgscn_';
KSMFSNAM KSMFSSIZ ---------------------------------------------------------------- ---------- kcsgscn_ 32
通过ORADEBUG工具可以得到当前内存中的SCN值:
SYS@WAPDBS>oradebug setmypid Statement processed.
SYS@WAPDBS>oradebug DUMPvar SGA kcsgscn_
kcslf kcsgscn_ [2000C848, 2000C868) = 00000000 000E23B5 00001322 00000000 00000000 00000000 00000000 2000C654
SYS@WAPDBS>select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 926645
SYS@WAPDBS>select to_number('E23B5','xxxxxx') SCN from dual; SCN ---------- 926645
Fixed Area包含很多控制信息,但是需要注意的是,查询X$KSMFSV视图可能会导致进程异常,需要谨慎使用。
1. Buffer Cache
Buffer Cache-缓冲区高速缓存,用于存储最近使用的数据块,这些数据块可能是被修改过的,也可能是未经修改的。我们知道,在Oracle对数据的处理过程中,代价最昂贵的就是物理I/O(Physical I/O )操作了,同样的数据从内存中得到要比从磁盘上读取快得多,所以将尽可能多的数据保存在内存中,可以减少磁盘I/O操作,从而提高数据库的性能。
在Oracle9i之前,Buffer Cache的设置主要由两个参数决定:db_block_buffers和db_block_size。db_block_buffers设置分配给Buffer Cache的缓冲区数量,这个数值乘以db_block_size得出的才是Buffer Cache的大小。
SQL> select * from v$version where rownum <2;
Oracle8i Enterprise Edition Release 8.1.7.4.0 - 64bit Production
SQL> select name,value from v$parameter where name in ('db_block_buffers','db_block_size'); NAME VALUE
-------------------- -------------------- db_block_buffers 25000 db_block_size 8192 SQL> select (select value from v$parameter where name='db_block_buffers')
·25·