SGA_MAX_SIZE,SGA_TARGET以及PRE_PAGE_SGA参数

10g引入ASMM后SGA_TARGET取代shared_pool_size,db_cache_size等参数,成为DBA关注的主要SGA内存管理参数;有不少情况下SGA_TARGET参数会设置为一个小于SGA_MAX_SIZE的值(这样做在多实例情况下更具灵活性)。但不少人会问,这样岂不是要浪费一部分物理内存吗?Oracle会为实例分配SGA_MAX_SIZE大小的内存的,SGA_TARGET要设得和SGA_MAX_SIZE一样大才合理啊! 让我们来看看实际的情况: ?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 SQL>  select  from  v$version; BANNER ---------------------------------------------------------------- Oracle  Database  10g Enterprise Edition Release 10.2.0.4.0 - 64bi PL/SQL Release 10.2.0.4.0 - Production CORE    10.2.0.4.0      Production TNS  for  Linux: Version 10.2.0.4.0 - Production NLSRTL Version 10.2.0.4.0 - Production /*  linux上的10.2.0.4  */ SQL> show parameter sga NAME                                  TYPE        VALUE ------------------------------------ ----------- ------------------------------ lock_sga                             boolean      FALSE pre_page_sga                         boolean      FALSE sga_max_size                         big  integer  3600M sga_target                           big  integer  368M SQL> col component  for  a25; SQL>  select  component, current_size / 1024 / 1024, last_oper_type    2     from  v$sga_dynamic_components    3    where  current_size != 0; COMPONENT                 CURRENT_SIZE/1024/1024 LAST_OPER_TYP ------------------------- ---------------------- ------------- shared pool                                   96  STATIC large pool                                    16  STATIC java pool                                     16  STATIC DEFAULT  buffer cache                         224 INITIALIZING /* 此时的SGA_TARGET为368M,而SGA_MAX_SIZE为3600M */ /* 我们来看一下实际的物理内存使用情况  */ /* 以root用户登录,因为我们需要用到清理文件系统缓存的命令 */ [maclean@rh2 ~]$ su - root Password : [root@rh2 ~]# sync [root@rh2 ~]# sync /* sync 命令用以写出文件系统脏缓存,类似于Oracle的 checkpoint 手动检查点 */ [root@rh2 ~]# echo 3 > /proc/sys/vm/drop_caches [root@rh2 ~]# echo 3 > /proc/sys/vm/drop_caches /*  将proc文件系统下的drop_caches文件置为3,清理文件系统缓存,以免其干扰我们的实验 */ [root@rh2 ~]#  free               total       used        free      shared    buffers     cached Mem:       4046352     429328    3617024          0        296     176100 -/+ buffers/cache:     252932    3793420 Swap:     10241428          0   10241428 /*  4g内存中仅有419M处于使用状态,其他均为 free 。可见Oracle没有为实例分配大小等于SGA_MAX_SIZE的内存空间,而接近于SGA_TARGET_SIZE的大小 */ [root@rh2 ~]# ps -ef|grep pmon|grep -v grep maclean   6361     1  0 18:35 ?        00:00:00 ora_pmon_YOUYUS [root@rh2 ~]# pmap -x 6361 6361:   ora_pmon_YOUYUS Address           Kbytes     RSS   Dirty Mode   Mapping 0000000000400000  100412    7300       0 r-x --  oracle 000000000680f000     544     180      64 rwx --  oracle 0000000006897000     148     104     104 rwx --    [ anon ] 000000001e9d0000     672     532     532 rwx --    [ anon ] 0000000060000000 3688448    1044     388 rwxs-    [ shmid=0x390005 ] /* 利用pmap工具探测Oracle后台进程的内存地址空间,可以看到这里虚拟共享内存段(也就是SGA)的大小为3602M */ [root@rh2 ~]# ipcs -m ------ Shared Memory Segments -------- key         shmid      owner      perms      bytes      nattch     status 0x74018366 3112960    root      600        4          0 0x00000000 3473409    root      644        80         2 0x74018365 3080194    root      600        4          0 0x00000000 3506179    root      644        16384      2 0x00000000 3538948    root      644        280        2 0x1cdd16e8 3735557    maclean   640        3776970752 15 /* 使用ipcs 命令也可以观察到这个大小为3602M的共享内存段 */ /* 可以猜测Oracle在这里使用malloc函数或类似的方法实现虚拟内存的分配,没有像calloc函数那样对空间中的每一位都初始为0,保证了不浪费物理内存  */ /*  我们动态修改SGA_TARGET参数来看看*  / SQL>  alter  system  set  sga_target=3000M; System altered. SQL>  select  component, current_size / 1024 / 1024, last_oper_type    2     from  v$sga_dynamic_components    3    where  current_size != 0; COMPONENT                 CURRENT_SIZE/1024/1024 LAST_OPER_TYP ------------------------- ---------------------- ------------- shared pool                                   96  STATIC large pool                                    16  STATIC java pool                                     16  STATIC DEFAULT  buffer cache                        2864 INITIALIZING /*   BUFFER_CACHE 的空间大幅增加 * / SQL> ! free               total       used        free      shared    buffers     cached Mem:       4046352    3187784     858568          0        536    2889920 -/+ buffers/cache:     297328    3749024 Swap:     10241428          0   10241428 /* used mem部分上升到3113M,随着SGA_TARGET的动态增长而增长了 */ /* 如果我们改小SGA_TARGET呢? */ SQL>  alter  system  set  sga_target=368M; System altered. SQL>  select  component, current_size / 1024 / 1024, last_oper_type    2     from  v$sga_dynamic_components    3    where  current_size != 0; COMPONENT                 CURRENT_SIZE/1024/1024 LAST_OPER_TYP ------------------------- ---------------------- ------------- shared pool                                   96  STATIC large pool                                    16  STATIC java pool                                     16  STATIC DEFAULT  buffer cache                         224 SHRINK /* 可以看到BUFFER CACHE最近执行了SHRINK收缩操作, SIZE 下降到224M */ QL> ! free               total       used        free      shared    buffers     cached Mem:       4046352    3204608     841744          0       1596    2912888 -/+ buffers/cache:     290124    3756228 Swap:     10241428          0   10241428 /* 此时OS层仍认为used memory部分为3130M;但可以放心,它们是可被其他进程复用的  * /
官方对pre_page_sga参数的定义是"PRE_PAGE_SGA determines whether Oracle reads the entire SGA into memory at instance startup. Operating system page table entries are then prebuilt for each page of the SGA. This setting can increase the amount of time necessary for instance startup, but it is likely to decrease the amount of time necessary for Oracle to reach its full performance capacity after startup." 它决定Oracle是否在启动阶段将整个SGA读入内存,实际上在启动阶段SGA的内容是十分稀疏的,当pre_page_sga为TRUE时Oracle所要做的是向OS所要SGA_MAX_SIZE大小的实际物理页。 我们来看一下这个参数的实际效果: ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 SQL>  alter  system  set  sga_max_size=2500M scope=spfile; System altered. SQL>  alter  system  set  pre_page_sga= true  scope=spfile; System altered. SQL> startup  force  ; ORACLE instance started. Total System  Global  Area 2634022912 bytes Fixed  Size                   2086288 bytes Variable  Size             2382367344 bytes Database  Buffers          234881024 bytes Redo Buffers               14688256 bytes Database  mounted. Database  opened. [root@rh2 ~]# echo 3 > /proc/sys/vm/drop_caches SQL> show parameter sga NAME                                  TYPE        VALUE ------------------------------------ ----------- ------------------------------ lock_sga                             boolean      FALSE pre_page_sga                         boolean      TRUE sga_max_size                         big  integer  2512M sga_target                           big  integer  368M SQL> ! free               total       used        free      shared    buffers     cached Mem:       4046352    2895256    1151096          0        648    2623692 -/+ buffers/cache:     270916    3775436 Swap:     10241428     104936   10136492 /*  设置pre_page_sga参数为 true 后,Oracle实际分配的物理内存不再局限于SGA_TARGET,而是在实例生命周期内几乎恒等于SGA_MAX_SIZE指定的值了 * / /*  当SGA_TARGET配合pre_page_sga使用时,这的确可能造成一种浪费 ! * /

10g中Oracle已经强烈不建议使用pre_page_sga参数了,在ASMM下它带来的问题可不小!

本文转自maclean_007 51CTO博客,原文链接:http://blog.51cto.com/maclean/1277136


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部