【SGA】sga的物理分配

来源:互联网 发布:淘宝新店装修教程 编辑:程序博客网 时间:2024/05/18 09:54

SGA内存在物理上的分配,是通过shmget函数来分配一块共享内存,共享内存的大小为sga_max_Size参数的值大小,而数据库内部对sga中各个组件的分配是依据sga_target,也就是说一般情况下各个组件的大小之和不会超过sga_target(如果sga_target设定的size大小不够时,也会超过sga_target但最大不会超过sga_max_size)。那如果sga_target < sga_max_size,那就会导致OS分配给oracle的内存不会被充分利用。

我们可以实际的来看一下:

1. Sga_target和sga_max_size相等的情况下

1.1 SQL> startup

SQL> select * from v$sgainfo;

NAME                                                                 BYTESRESIZE

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

Fixed SGA Size                                                     2022080 No

Redo Buffers                                                        2170880No

Buffer Cache Size                                                243269632 Yes

Shared Pool Size                                                 264241152 Yes

Large Pool Size                                                     4194304 Yes

Java Pool Size                                                     4194304 Yes

Streams Pool Size                                                  4194304 Yes

Granule Size   (sga分配时的颗粒大小)                              4194304 No

Maximum SGA Size (sga_max_size)                                   524288000No

Startup overhead in SharedPool                                     46137344 No

Free SGA Memory Available(sga_max_size-sga_target)                    0

SQL>select (2022080+2170880+243269632+264241152+4194304+4194304+4194304)/1024/1024"Total(M)" from dual;

 Total(M)

----------

499.998718

SGA中各个组件之和约为500M.

 

1.2 来看看sga相关参数的大小设置

SQL> show parameter sga;

NAME                                 TYPE                   VALUE

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

lock_sga                             boolean                FALSE

pre_page_sga                         boolean                FALSE

sga_max_size                         big integer            500M

sga_target                           big integer            500M

sga_max_size和sga_target大小设置相同,均为500M

 

1.3 在从OS上看看分配给SGA的共享内存段是多大

[oracle@ballontt ~]$ ipcs -m

------ Shared Memory Segments --------

key       shmid      owner      perms     bytes      nattch     status     

0x00000000 1998849    root     644        80         2                      

0x00000000 2031618    root     644        16384      2                       

0x00000000 2064387    root     644        280        2                      

0x223f51fc 2260997    oracle   640        526385152  21                     

0x00000000 2195462    root     666        4096       0 

SQL> select 526385152/1024/1024 fromdual;

526385152/1024/1024

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

  502

526385152字节转换过来是502M,基本就是500M,与SGA_target,sga_max_size相同,均为500M.

 

2.如果SGA_TARGET小于SGA_MAX_SIZE呢?则OS上按照SGA_MAX_SIZE大小分配共享内存段,SGA各个组件大小之和为SGA_TARGET大小

2.1 增大SGA_MAX_SIZE

SQL> alter system set sga_max_size=550mscope=spfile;


SQL> shutdown immediate;

 

SQL> startup

SQL> select * from v$sgainfo;

NAME                                                                 BYTES RESIZE

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

Fixed SGA Size                                                      2022504 No

Redo Buffers                                                       2170880 No

Buffer Cache Size                                                247463936 Yes

Shared Pool Size                                                  260046848 Yes

Large Pool Size                                                    4194304 Yes

Java Pool Size                                                     4194304 Yes

Streams Pool Size                                                  4194304 Yes

Granule Size                                                       4194304 No

Maximum SGA Size                                                 578813952 No

Startup overhead in Shared Pool                                    46137344 No

Free SGA Memory Available                                         54525952

11 rows selected.

SQL> select(2022504+2170880+247463936+260046848+4194304+4194304+4194304)/1024/1024 fromdual;

(2022504+2170880+247463936+260046848+4194304+4194304+4194304)/1024/1024

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

                                                            499.999123

约为500M

 

2.2 而OS上分配的共享内存段:

[oracle@ballontt ~]$ ipcs -m

------ Shared Memory Segments --------

key       shmid      owner      perms     bytes      nattch     status     

0x00000000 1998849    root     644        80         2                      

0x00000000 2031618    root     644        16384      2                      

0x00000000 2064387    root     644        280        2                      

0x223f51fc 2293765    oracle   640        580911104  21                     

0x00000000 2195462    root     666        4096       0                      

SQL> select 580911104/1024/1024 fromdual;

580911104/1024/1024

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

                554

约为550M.

所以,为了提高内存的利用率,SGA_TARGET和SGA_MAX_SIZE应设置相等

 

3. 那前面,我们说了SGA是OS通过shmget函数来分配一块内存的,那我们来直观的感受一下shmget,自己通过shmget函数来从OS要一块内存

3.1 在vi编辑器中编辑该程序如下:

程序清单create_shm.c使用shmget函数创建共享内存

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <stdlib.h>

#include <stdio.h>

#define BUFSZ 4096

int main ( void )

{

int shm_id; /*共享内存标识符*/

shm_id=shmget(IPC_PRIVATE, BUFSZ, 0666 );

//shm_id=shmget(999,BUFSZ,0666|O_CREAT);

if (shm_id < 0 ) { /*创建共享内存*/

perror( "shmget" ) ;

exit ( 1 );

}

printf ( "successfully createdsegment : %d \n", shm_id ) ;

system( "ipcs -m"); /*调用ipcs命令查看IPC*/

exit( 0 );

}

 

3.2 在shell中编译该程序如下:

[root@ballontt ~]# gcc create_shm.c –ocreate_shm

 

3.3 在shell中运行该程序如下:

[root@ballontt ~]# ./create_shm

successfully created segment :2326535

------ Shared Memory Segments --------

key       shmid      owner      perms     bytes      nattch     status     

0x74003c75 1671168   root      600        4          0                      

0x00000000 1998849   root      644        80         2                      

0x00000000 2031618   root      644        16384     2                      

0x00000000 2064387   root      644        280        2                      

0x00000000 2097156   gdm       600        393216     2         dest        

0x223f51fc 2293765   oracle    640        580911104  20                     

0x00000000 2195462   root      666        4096       0                      

0x00000000 2326535   root      666        4096       0  

可以看到我们申请了一个共享内存段2326535

 

这是oracle 10g中的自动内存管理时的sga分配方式,在11g中使用memory_target时将会又是另一种机制。至于10g中pga的分配,是通过allocate()函数来分配,而且不会在开始时就分配好固定的大小,甚至如果需要会超过pga_aggregate_target的设置值。

那oracle在使用shmget申请共享内存段时,OS是如何选取一段内存给oracle的呢?是一段连续的空间呢,还是离散的呢?

这里给出另一篇文件来解读这个问题:

http://space.itpub.net/17203031/viewspace-707900


ballontt
2013/10/24

---The End---

微博weibo.com/ballontt
如需转载,请标明出处和链接,谢谢!

原创粉丝点击