学习学习再学习&&思考思考再思考

实践实践再实践@@复盘复盘再复盘

"汽车中的前置箱"SGA是怎么进行内存管理的?_SGA



每个oracle数据库实例都有一个很大的内存结构,称为系统全局区(System Global Area),这是一个大型的共享内存结构,每个oracle进程都会访问它。在Linux/Unix操作系统上,SGA是一个物理实体,使用操作系统命令能“看到它”。



01

它被物理地划分为一个共享内存段,进程可以附加到这段独立的内存上。你可以把SGA想象成小汽车的前置箱,在这个前置箱里面会有发动机进程,轴转动进程等。SGA也是可以脱离Oracle进程而存在的,正如即使发动机,转轴不装载到前置箱里面,前置箱也可以独立存在。但是,在生产环境中,如果真的只有SGA而没有任何Oralce进程,那说明数据库以某种方式奔溃了,这种情况类似小汽车已经静止不能动态运转了。我们可以通过ipcs -m|grep ora查看SGA:"汽车中的前置箱"SGA是怎么进行内存管理的?_自动内存管理_02

在数据库内部,无论在什么操作系统平台(可以类比为马路),可以通过动态性能视图v$sgastat来查看:

"汽车中的前置箱"SGA是怎么进行内存管理的?_自动内存管理_03

"汽车中的前置箱"SGA是怎么进行内存管理的?_手动内存管理_04



02

一份oracle骨骼剖解,请查收中我们说过SGA包括share_pool,db_buffer,cache_buffer,java_pool,large_pool,stream_pool六大组件,前三个为核心组件,后三个为非核心组件。对SGA整体大小影响最大的参数是以下这些。

java_pool_size:控制java池的大小。

shared_pool_size:在某种程度上控制共享池的大小。

large_pool_size:控制大池的大小。

streams_pool_size:控制流池的大小。

db_*_cache_size:共有8个cache_size参数,控制各个可用的缓冲区缓存的大小。

log_bufer:在某种程度上控制重做日志缓冲区的大小。

sga_target:在oracle DB 10g及更高版本中用于自动SGA内存管理,可动态调整。

sga_max_size:用于控制SGA的大小。

memory_target:在oracle DB 11g及更高版本中用于自动内存管理。

memory_max_size:在oracle DB 11g及更高版本中对于采用自动内存管理的数据库,使其PGA和SGA的内存总用量尽可能达到(并且不超出)memory_max_size的值。这些参数的设置和优化就涉及到了oracle的SGA的管理和优化。



03

需要注意的是,不论是使用手动内存管理还是自动内存管理,都会发现各个池的内存是基于一种被称为颗粒granule的单位来分配的。一个颗粒大小为4MB,8MB,16MB的内存区。比如你想要一个5MB的java池,而你的颗粒大小为4MB,oracle实际上会为这个java池分配8MB。通过查询V$SGA_DYNAMIC_COMPONENTS,可以查看各个池中的颗粒大小。

SQL> show parameter sga_target;

NAME                                 TYPE        VALUE

sga_target                           big integer 1020M
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

COMPONENT                                                        GRANULE_SIZE
---------------------------------------------------------------- ------------
DEFAULT 32K buffer cache                                       4194304
ASM Buffer Cache                                                      4194304

13 rows selected.


sga大小决定了颗粒的大小。可以通过调整sga_tartet的大小来实验一把:

SQL> alter system set sga_target=1035m scope=spfile;

System altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area 1090519040 bytes
Fixed Size                  2083304 bytes
Variable Size             301991448 bytes
Database Buffers          771751936 bytes
Redo Buffers               14692352 bytes
Database mounted.
Database opened.

再次查看sga_target大小:
SQL> show parameter sga_target

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
sga_target                           big integer 1040M

现在再来看看sga各组件颗粒度:

"汽车中的前置箱"SGA是怎么进行内存管理的?_自动内存管理_05


可以看到,SGA为1.01G时,会以16MB的颗粒为池分配空间,所以池大小都将是16MB的某个倍数。这充分证明了SGA的大小决定了颗粒的大小。