ORACLE内存结构之SGA

时间:2021-10-29 17:40:14

SGA的管理:

SQL> show parameter sga

NAME                                 TYPE        VALUE

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

lock_sga                             boolean     FALSE

pre_page_sga                         boolean     FALSE

sga_max_size                         big integer 1584M

sga_target                           big integer 0

SGA的各个组件大小是可以动态调整的,总大小不超过参数SGA_MAX_SIZE或者SGA_TARGET的大小.

--log buffer不能被自动管理,

--share_pool_size db_cache_size large_pool_size java_pool_size streams_pool_size都可以被自动管理

SGA只需要

1、分配一个大小sga_max_size=(80%mem)*2/3

2、sga_target=<>

3、log buffer分配一个大小

4、其他可以被自动管理的也需要设置一个初始大小

SGA的分配和回收内存是由实例instance的开启和关闭来决定.

SGA是一个可读可写的内存区域,连接到实例上的用户都可以通过SGA读取数据,更新数据。ORACLE大部分操作都在内存中完成。大部分内存就是SGA了

SGA参数:

sga_max_size-->决定了granule size(<1G 4M >=1G 16M)

sga_target-->大于0为自动管理,否则为动态管理

shared_pool_size

large_pool_size

java_pool_size

db_cache_size

8i

SGA总大小由所有内存组件大小之和决定,不能直接定义SGA大小,对内部组件大小的修改必须在数据库重启后才能生效,所以叫做SGA静态管理

9i

SGA总大小由初始化参数SGA_MAX_SIZE确定,各个内存组件大小之和不能超过这个参数,在这个大小之下,SGA各个内存组件可以在不重启数据库的情况下直接修改大小,所以叫SGA动态管理

10g

SGA大小可以像9i一样动态管理,也可以实施SGA的自动管理,只需要设置初始化参数SGA_TARGET,SGA各个内存组件就可以由数据库自动设置大小,设置的一句来源于系统自动收集的统计信息.

在9i后,SGA的内部组件大小可以动态调整,也可以由数据库自动管理,在设置内存大小的时候,分配的基本单位是粒度(granule)

SGA包含的组件

Shared pool、database buffer cache、redolog buffer

Large pool、java pool、streams

Fixed size、variable size

共享池

暂存最近常用的SQL语句和相关数据字典信息

包括2个与语句解析性能相关的组成部分

库缓存

数据字典缓存

由参数SHARED_POOL_SIZE决定大小,可动态调整

Shared pool

  • 用于存储:
    • 最近执行的SQL语句
    • 最近使用的数据定义
  • 由两个与性能相关的部分组成:
    • 库缓存
      • 存储最近使用的SQL和PL/SQL语句的信息
      • 共享最常用的语句
      • 管理上遵循LRU规则
      • 包括两个部分:
        • 共享SQL区域
        • 共享PL/SQL区
      • 大小由shared pool的大小决定
    • 数据字典缓存
      • 存储在数据库中最近使用的定义
      • 包括数据文件、表、索引、用户、权限和其他的数据库对象
      • 在分析截断,服务器进程查找数据字典去验证对象的名字以及是否是合法访问
      • 对于查询和DML语句,如果数据字典的信息在缓存中能够提高响应时间
      • 大小由shared_pool的大小决定
  • 由参数SHARED_POOL_SIZE决定大小
    • shared_pool_size>0 sga_target>0

用户提交一个SQL语句

  • 通过PGA传递到SGA,oracle对语句进行分析
    • 如果以前执行过,则按照以前执行的计划执行,通常是软分析soft parse或快速软分析:
      • 通过PGA提交SQL语句-->parse语句-->soft parse-->执行语句-->通过PGA输出
    • 如果没有执行过,oracle开始分析语句的语法,语义
      • 通过PGA提交sql语句-->parse语句-->hard parse-->分析与得到优化方案【CBO或RBO】-->根据优化方案指定执行计划-->执行语句-->通过PGA输出

Open cursor

-->Found SQL in library cache?

-->Yes------------------------>Bind variable?

-->no-->Parse-->Define-->Bind variable?

-->Yes-->Bind-->Parallelize

-->No------------>Parallelize

-->execute

-->fetch

-->close cursor

怎么用有限的内存保留经常被使用的SQL语句呢?LRU算法

LRU算法确定共享对象的持续保存期,长期不用的SQL保存信息会在LRU中释放.

如果不想释放,就调用dbms_shared_pool.keep存储过程将该过程或包驻留在shared pool中,以减少重新载入的开销.

dbms_shared_pool提供以下功能将object或sql statement pin到shared pool…

keep过程可以将对象pin入shared_pool,而不进入LRU机制;

k).

  • 数据高速缓存区由多个独立的子缓存池构成,可以独立的设置大小:
    • default池

      DB_CACHE_SIZE

      如果没有指定数据块给哪个缓冲区,就会使用default池

      keep池

      DB_KEEP_CACHE_SIZE

      将对象数据库保留在内存中,这些数据一直保存在内存中,不会被LRU淘汰

      recycle池

      DB_RECYCLE_CACHE_SIZE

      数据不需要时,从内存中去掉

  • 只有default池可以被SGA自动管理
  • Database buffer cache里的内存存在2个状态:
    • 干净的状态,没有被修改过的列表
    • 脏的状态,可写的列表,保留的已经被修改过的数据,叫脏的列表,通过DBWR根据需要写到磁盘去。
    • Cache Hit:内存中有,直接在内存中读
    • Cache miss:内存中没有,需要PGA从磁盘中读取到内存中

    重做日志缓冲区

    Redo buffers

    重做日志缓冲区

    暂存数据库中所有数据块的改变

    内存管理方式是FIFO

    重做日志被用于提供数据恢复功能

    暂存重做日志的目的是为了提高语句的执行速度

    大小由参数LOG_BUFFER决定,但这个内存区不能动态调整大小

    show parameter log_buffer

    SQL> show parameter log_b

    NAME                                 TYPE      VALUE

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

    log_buffer                           integer   6774784

    java池

    java池也是一个系统全局区中可选内存区

    用于java程序的解析和执行

    大小由参数JAVA_POOL_SIZE决定,也可以动态调整

    如果granule是4M,就默认设置是24M,如果granule是16M,就默认设置大小是32M

    如果数据库创建时选了安装JVM组件,那么这个池必须配置

    streams池

    streams池

    流池

    缓冲一些高级队列的东西

    一般设置12M就可以了

    streams池在11gr2后才可以自动管理,之前需要手动设置

    大型池

    large_pool

    大对象缓存时使用

    大池是系统全局区中可选的一个内存区

    • 主要在下面这种情况使用
      • 共享服务器的用户全局区UGA(如果不是共享服务器,UGA是存在PGA里)
      • 并行进程
      • 使用RMAN 作备份恢复(如果大池没有设定大小,备份时就会使用共享池的空间)
    • 大小由参数LARGE_POOL_SIZE决定,也可以动态改变大小,虽然可以动态设定,但还是会优先使用共享池,所以还是要设定一个大小为好
    • 一般分配12-64M

    SQL> show parameter large_pool_s

    NAME                                 TYPE      VALUE

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

    large_pool_size                      big integer 0

    SQL>

    SQL> alter system set large_pool_size=10m;

    System altered.

    SQL> show parameter large_pool_s

    NAME                                 TYPE      VALUE

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

    large_pool_size                      big integer 16M

    SQL>

    注意,虽然设置池的大小是10M,但是分配时是16M,因为我们内存的粒度是16M.

    粒度的大小设置可以通过如下数据字典查看.

    SQL> select name,bytes/1024/1024 from v$sgainfo;

    NAME                             BYTES/1024/1024

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

    Fixed SGA Size                        2.14937592

    Redo Buffers                            6.765625

    Buffer Cache Size                            624

    Shared Pool Size                             256

    Large Pool Size                               32

    Java Pool Size                                16

    Streams Pool Size                              0

    Shared IO Pool Size                            0

    Granule Size                                  16

    Maximum SGA Size                      1576.91797

    Startup overhead in Shared Pool       192.447815

    NAME                             BYTES/1024/1024

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

    Free SGA Memory Available                    640

    12 rows selected.

    Fixed size And variable size

    Fixed size

    SGA中有一部分数据是后台进程需要的,他们包含了数据库的跟实例的一些状态的数据,这部分数据叫做固定的SGA区域,这部分区域的内容是不能更改的,是当实例启动时就分配了,一旦启动后这部分内存区域是固定不变的,这部分内存不能进行共享,主要是后台进程需要的内存区,主要是用来关联数据库跟实例的一些状态或一些控制信息用的.

    SQL> show sga

    Total System Global Area 1653518336 bytes

    Fixed Size                  2253784 bytes

    Variable Size            1224739880 bytes

    Database Buffers          419430400 bytes

    Redo Buffers                7094272 bytes

    Variable size

    可变区域

    内存可以被共享,根据用户访问请求需要进行分配和回收