SGA管理
SGA(System Global Area)是一块用于加载数据、对象并保存运行状态和数据控制信息的一块区域,在数据库实例启动时分配,当实例关闭时释放,每个实例都有自己的SGA。连接到Oracle数据库的用户都可以共享SGA中的数据,通常为了优化性能,在物理内存允许的情况下设置更高的SGA,以减少物理I/O的读写次数。
1、 固定区域(Fixed Area)
Fixed Area部分是SGA中的固定部分,包含几千个变量和一些小的数据结构,如Latch或地址指针等,这部分内存分配和特定的数据库版本以及平台有关,不受用户限制,而且这些信息对于数据库来说非常重要,但都不需要用户参与。
固定部分只需要很小的内存,可以通过一个内部表X$KSMFSV([K]ernel [S]ervice Layer [M]emery Management,Address of [F]ixed [S]GA [V]ariables)查询,此外,Oracle的内部表X$KSMMEM记录了整个SGA的地址映射关系,通过X$KSMFSV和X$KSMMEM关联,可以找出Fixed Area中每个变量的设置。
Fixed Area包含很多控制信息,但是需要注意的是,查询X$KSMFSV视图可能导致进程异常,需要谨慎使用。
2、 Buffer Cache
Buffer Cache用于存储最近使用的数据块,这些数据块可能是被修改过的,也可能是未经修改的,在Oracle对数据的处理过程中,代价最昂贵的就是物理I/O的操作了,所以尽可能多的缓存可以提高Oracle数据库的性能。
在Oracle9i之前,Buffer Cache的设置主要由两个参数决定:db_block_buffers和db_block_size。Db_block_buffers设置分配给Buffer Cache的db_block数量,db_block_size指定数据块的尺寸。这两个数据的乘积才是Buffer Cache的大小。
从Oracle9i开始,Oracle引入了一个新的初始化参数db_cache_size,该参数用来定义主Block_size的Default缓冲池的大小。
Db_cache_size最小值为一个粒度(Granule),粒度也是Oracle9i引入的一个新的概念,是连续虚拟内存分配的单位,其大小取决于估计的SGA的总大小。
在Oracle10gR2中,Granule的分配算法有所改变,在大多数平台上,如果SGA<1GB,Granule通常为4MB。Granule的大小受一个内部隐含参数_ksmg_granule_size的控制。
Enter value for par: _ksmg_granule_size
NAME VALUE PDESC
------------------------------ ------------------------- ----------------------------------------
_ksmg_granule_size 4194304 granule size in bytes
各内存组件所使用的Granule大小可以通过动态视图查询得到,如下所示:
SQL> select component,granule_size from v$sga_dynamic_components;
COMPONENT GRANULE_SIZE
---------------------------------------------------------------- ------------
shared pool 4194304
large pool 4194304
java pool 4194304
streams pool 4194304
DEFAULT buffer cache 4194304
KEEP buffer cache 4194304
RECYCLE buffer cache 4194304
DEFAULT 2K buffer cache 4194304
DEFAULT 4K buffer cache 4194304
DEFAULT 8K buffer cache 4194304
DEFAULT 16K buffer cache 4194304
DEFAULT 32K buffer cache 4194304
ASM Buffer Cache 4194304
Oracle对于Buffer Cache的管理采用的LRU算法,但是这又带来另一个问题,很多批处理操作(如全表扫描)可能会导致Buffer Cache的刷新,将经常使用的数据“挤出”Buffer Cache,在不同的版本中,Oracle也在不停的改进LRU的算法,提出了多缓冲池技术,从另一个方面来解决这个问题。所谓的多缓冲池是将默认的缓冲池做进一步的细分,如下:
(1) Default Buffer Cache
(2) Keep Buffer Cache
(3) Recycle Buffer Cache
不同的缓冲池对数据的缓冲时间不同。对于经常使用的数据,可以在建表是就指定将其存放在Keep池中;对于经常一次性读取的数据,可以将其放在Recycle池中,而Default池用于存放未指定存储池的数据,按照LRU算法。
默认情况下,所有表都使用Default池,它的大小就是数据缓冲区Buffer Cache的大小,由初始化参数db_cache_size决定。
此外,从Oracle9i开始支持多类型数据块大小表空间支持,在一个数据库中可以存在多种block_size的表空间,分别支持2k、4k、8k、16k和32k,其中db_block_size用于指定主Block_size的大小,其它分别由db_nk_cache_size参数指定。
上述信息可以从v$buffer_pool视图中得到:
SQL> select id,name,block_size,current_size,target_size from v$buffer_pool;
ID NAME BLOCK_SIZE CURRENT_SIZE TARGET_SIZE
---------- -------------------- ---------- ------------ -----------
1 KEEP 8192 8 8
2 RECYCLE 8192 8 8
3 DEFAULT 8192 168 168
SQL> show parameter cache
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_2k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_16k_cache_size big integer 0
db_32k_cache_size big integer 0
3、 Shared Pool
共享池由参数Shared_pool_size定义,在Oracle9i中,最小值为一个Granule
SQL> show parameter shared_pool_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
shared_pool_size big integer 0
4、 Redo Log Buffer
日志缓冲区由参数Log_buffer决定。这是一个静太参数,不能动态修改
SQL> show parameter log_buffer
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
log_buffer integer 7057408
5、 Large_pool
这是SGA一个可选组件,通常用于共享服务器模式(MTS)、并行计算或RMAN的备份恢复操作
SQL> show parameter large
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
large_pool_size big integer 0
6、 Jave Pool
提供给java程序使用
SQL> show parameter java_pool_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
java_pool_size big integer 0
7、 Streams Pool
Streams Pool是Oracle10g引入的概念,为Oracle的Streams功能使用,如果不定义该参数,这部分内存将从Share Pool中分配
SQL> show parameter stream
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
streams_pool_size big integer 0
8、 总结
SQL> show parameter sga_target
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sga_target big integer 272M
SQL> select name,round(value/1024/1024,2) size_mb from v$sga;
NAME SIZE_MB
-------------------- ----------
Fixed Size 1.16
Variable Size 80
Database Buffers 184
Redo Buffers 6.84
SQL> select name,round(bytes/1024/1024,2) size_MB,RESIZEABLE from v$sgainfo;
NAME SIZE_MB RES
-------------------------------- ---------- ---
Fixed SGA Size 1.16 No
Redo Buffers 6.84 No
Buffer Cache Size 184 Yes
Shared Pool Size 72 Yes
Large Pool Size 4 Yes
Java Pool Size 4 Yes
Streams Pool Size 0 Yes
Granule Size 4 No
Maximum SGA Size 272 No
Startup overhead in Shared Pool 36 No
Free SGA Memory Available 0
SGA与共享内存
SGA的设置在UNIX、Linux上和一个操作系统的内核参数设置有关,这个参数在Solaris上是由/etc/system文件中shmsys:shminfo_shmmax定义;在Linux上,该参数由/proc/sys/kernel/shmmax参数定义。
该参数定义的是系统允许的单个共享内存段的最大值。如果该参数小于SGA的设置,那SGA是仍然可以创建成功的,但是会创建多个共享内存段。通常推荐通过调整shmmax参数的设置,将SGA限制在一个共享内存段中。
[root@Oracle ~]# cat /proc/sys/kernel/shmmax
2,147,483,648
在Linux系统中,可以通过如下方式查看共享内存状况:
[root@Oracle ~]# ipcs -sa
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 65536 root 600 393216 2 dest
0x00000000 98305 root 600 393216 2 dest
0x00000000 131074 root 600 393216 2 dest
0x00000000 163843 root 600 393216 2 dest
0x00000000 196612 root 600 393216 2 dest
0x00000000 229381 root 600 393216 2 dest
0x00000000 262150 root 600 393216 2 dest
0x00000000 294919 root 600 393216 2 dest
0x00000000 327688 root 600 393216 2 dest
0x00000000 1540105 root 600 393216 2 dest
0x00000000 1572874 root 600 393216 2 dest
0x4032a294 524299 oracle 640 289406976 20
0x00000000 884748 root 600 393216 2 dest
0x00000000 917517 root 600 393216 2 dest
0x00000000 950286 root 600 393216 2 dest
0x00000000 1245199 root 600 393216 2 dest
0x00000000 1343504 root 600 393216 2 dest
------ Semaphore Arrays --------
key semid owner perms nsems
0xddaf4f30 98304 oracle 640 154
------ Message Queues --------
key msqid owner perms used-bytes messages
可以进一步用pmap查看每个进程的共享内存状态:
[root@Oracle ~]# ps aux|grep ora_dbw0_orcl|head -1
oracle 4740 0.0 7.2 377988 75372 ? Ss 00:29 0:12 ora_dbw0_orcl
[root@Oracle ~]# pmap 4740
4740: ora_dbw0_orcl
00110000 436K r-x-- /u01/app/oracle/10.2.0/db_1/lib/libocr10.so
0017d000 4K rwx-- /u01/app/oracle/10.2.0/db_1/lib/libocr10.so
0017e000 88K r-x-- /u01/app/oracle/10.2.0/db_1/lib/libdbcfg10.so
00194000 8K rwx-- /u01/app/oracle/10.2.0/db_1/lib/libdbcfg10.so
00196000 8K r-x-- /lib/libdl-2.5.so
00198000 4K r-x-- /lib/libdl-2.5.so
00199000 4K rwx-- /lib/libdl-2.5.so
0019a000 148K r-x-- /lib/libm-2.5.so
001bf000 4K r-x-- /lib/libm-2.5.so
001c0000 4K rwx-- /lib/libm-2.5.so
001c1000 76K r-x-- /lib/libpthread-2.5.so
001d4000 4K r-x-- /lib/libpthread-2.5.so
001d5000 4K rwx-- /lib/libpthread-2.5.so
001d6000 8K rwx-- [ anon ]
001d8000 76K r-x-- /lib/libnsl-2.5.so
001eb000 4K r-x-- /lib/libnsl-2.5.so
001ec000 4K rwx-- /lib/libnsl-2.5.so
001ed000 296K rwx-- [ anon ]
提示:如果内核参数shmmax的设置小于SGA的设置,Oracle可能会在Alert日志记录告警日志。这时可以通过修改/etc/sysctl.conf文件中kernel.shmmax = 2147483648的值,然后重启数据库就可以了。
但是,在有些情况下也有可能因数据库上次未能正常关闭而在Alert日志中记录相关信息。
遇到共享内存未能正常释放而导致数据库无法正常启动时,可以通过ipcs命令找到共享内存段的id(shared memory id),然后通过ipcm命令强制释放该共享内存段。然后就可以尝试启动数据库了。
SGA管理变迁
在Orace9i之前,SGA一直是静态分配内存的,一旦分配完毕,可用共享内存的大小就不能动态更改,如果确实要变更,DBA需要关闭实例,修改参数文件,然后重启才能完成SGA的变更。
从Oracle8i开始,研究Oracle SGA管理的变迁。
1、 Oracle8i中静态SGA的管理
db_block_buffers = 25000
shared_pool_size = 1048576000
large_pool_size = 8388608
java_pool_size = 10485760
log_buffer = 163840
2、 Oracle9i动态SGA管理
从Oracle9i开始,Oracle推出了动态SGA调整,也就是说,允许用户不重启数据库修改SGA配置就可以立即生效。
在Oracle9i中,可以设置参数SGA_MAX_SIZE,该参数用以控制各缓冲池使用的内存总和。本质上是在进程中预先分配一段虚拟地址备用而不分配物理内存,目的是防止和进程私有地址段冲突。
3、 Oracle10g自动共享内存管理(ASSM)
在Oracle9i中,虽然实现了SGA的动态调整,但是依然需要DBA的参与以调整到最佳性能。到了Oracle10g,Oracle就可以完全实现SGA的自调整了。
如,在白天OLTP高峰时,Oracle可以自动调整大部分内存给Buffer Cache以提供更好的性能,到了晚上OLAP时段,Oracle可以调整大部分内存给Larget Pool,以获得更好的数据分析任务性能。
在Oracle10g中使用了一个新的初始化参数SGA_TARGET,通过指定这个参数,让Oracle自动管理SGA中以下大部分的内存分配。SGA_TARGET是个动态参数,但是该参数不能超越SGA_MAX_SIZE参数的设置,否则会出现错误。
注意,并非所有的SGA组件都可以自动调整,可以自动分配的内存包括:
(1) Buffer Cache
(2) Shared Pool
(3) Java Pool
(4) Larget Pool
启用自动共享内存管理,可以估算一个SGA的总大小,然后设置SGA_TARGET参数为非零值将启用自动共享内存管理。自动共享内存管理需要STATISTICS_LEVEL参数设备为TYPICAL或ALL。
Oracle服务器根据系统运行的情况自动调整这些内存的大小,并记录在SPFILE中,重启也不会丢失这些更改。此外,以下相关参数还是需要手工设置的:
(1) 非标准的Block Size的Cache
(2) Keep/Recycle Buffer Cache
(3) Redo Log Buffer
(4) Streams Pool
自动共享内存管理引入一个新的后台进程MMAN(Memory Manager),该进程用以动态调整内存组件。动态调整的依据来自系统不间断的收集的内存数据建议。
如果不想使用自动共享内存管理的新特性,Oracle也允许使用手工的管理。只需要将SGA_TARGET参数设置为0即可。当前的各内存组件值会被计入SPFILE,作为手工管理的初始值。
随着自动共享内存管理新特性的加入,许多相关参数也发生了改变,这些参数值会处于未设置状态。如下:
SQL> select name,value from v$parameter
2 where name in (
3 'large_pool_size',
4 'java_pool_size',
5 'shared_pool_size',
6 'streams_pool_size',
7 'db_cache_size');
NAME VALUE
----------------------------------- ------------------------------
shared_pool_size 0
large_pool_size 0
java_pool_size 0
streams_pool_size 0
db_cache_size 0
而真正决定各组件大小的,是由一组新引入的参数决定:
SQL> l
1 select x.ksppinm Name,y.ksppstvl VALUE,x.ksppdesc DESCRIB
2 from sys.x$ksppi x,
3 sys.x$ksppcv y
4 where x.inst_id = USERENV ('Instance')
5 and y.inst_id = USERENV ('Instance')
6 and x.indx = y.indx
7* and x.ksppinm like '%pool_size%'
SQL> /
NAME VALUE DESCRIB
------------------------- -------------------- -----------------------------------------------------------------
_NUMA_pool_size Not specified aggregate size in bytes of NUMA pool
__shared_pool_size 71303168 Actual size in bytes of shared pool
shared_pool_size 0 size in bytes of shared pool
__large_pool_size 4194304 Actual size in bytes of large pool
large_pool_size 0 size in bytes of large pool
__java_pool_size 4194304 Actual size in bytes of java pool
java_pool_size 0 size in bytes of java pool
__streams_pool_size 0 Actual size in bytes of streams pool
streams_pool_size 0 size in bytes of the streams pool
_io_shared_pool_size 4194304 Size of I/O buffer pool from SGA
_backup_io_pool_size 1048576 memory to reserve from the large pool
global_context_pool_size Global Application Context Pool Size in Bytes
olap_page_pool_size 0 size of the olap page pool in bytes
这些由两个下划线开头的参数决定了当前SGA的分配,也是动态内存管理调整的参数。这些参数的更改会被记录到SPFILE文件中,在下一次数据库启动时仍然有效。
[oracle@Oracle u01]$ cat pfile
orcl.__db_cache_size=197132288
orcl.__java_pool_size=4194304
orcl.__large_pool_size=4194304
orcl.__shared_pool_size=71303168
orcl.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/orcl/adump'
*.background_dump_dest='/u01/app/oracle/admin/orcl/bdump'
*.compatible='10.2.0.1.0'
*.control_files='/u01/app/oracle/oradata/orcl/control01.ctl','/u01/app/oracle/oradata/orcl/control02.ctl','/u01/app/oracle/oradata/orcl/control03.ctl'
*.core_dump_dest='/u01/app/oracle/admin/orcl/cdump'
*.db_block_size=8192
*.db_domain=''
*.db_file_multiblock_read_count=16
*.db_name='orcl'
*.db_recovery_file_dest='/u01/app/oracle/flash_recovery_area'
*.db_recovery_file_dest_size=2147483648
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.job_queue_processes=10
*.open_cursors=300
*.pga_aggregate_target=94371840
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=285212672
*.undo_management='AUTO'
*.undo_tablespace='UNDOTBS1'
*.user_dump_dest='/u01/app/oracle/admin/orcl/udump'
Oracle的内存分配和使用
SGA_MAX_SIZE + PGA_AGGREGATE_TARGET <= Total Physical Memory * 80%
(1) 对于OLTP系统
PGA_AGGREGATE_TARGET=(TOTAL PHYSICAL MEMORY * 80%)*20%
(2) 对于DSS系统
PGA_AGGREGATE_TARGET=(TOTAL PHYSICAL MEMORY * 80%)*(20~50)%
注:在某些OS上单个进程使用的的真实内存可能远大于在Oracle中看到的PGA大小,如AIX,在AIX上通常建议Oracle使用内存不超过物理内存的70%
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25069245/viewspace-697942/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/25069245/viewspace-697942/
本文详细介绍了Oracle数据库系统全局区(SGA)的管理及优化方法,包括SGA的组成部分如Buffer Cache、Shared Pool等的功能及其配置参数。还探讨了从Oracle 9i到10g版本中SGA管理方式的变化,特别是自动共享内存管理(ASSM)的引入。
3801

被折叠的 条评论
为什么被折叠?



