oracle之内存结构

ORALCE内存结构:

SGA(System Global area)
一组共享内存结构,包含数据库实例的数据以及控制信息。
PGA(Program global area)
进程或者线程独占的内存结构。当ORACLE进程启动时分配该内存。
UGA(User global area)
与用户会话相关的内存结构。

oracle内存结构图
在这里插入图片描述

SGA

SGA属于数据库实例的一部分。可通过V$SGASTAT查看各个内存区域的基本信息。

Database Buffer Cache

用于缓存当前或最近使用的从磁盘读取的数据块的拷贝,来优化数据库的I/O减少物理读/写。Oralce依据LRU算法对该内存区域进行block-level的更新。
在这里插入图片描述
当一个客户端进程请求数据时,服务端进程会首先去查找buffer cache,如果命中,数据库就进行逻辑读获取该buffer cache的数据。

如果未查找到数据,并且数据库开启了flash cache,那么服务端进程会查找 flash cache LRU List的buffer header,如果发现数据,则将flash cache中的数据加载到内存中。

当以上方式都未读取到数据时,数据库就会进行一次物理读:首先将数据库复制到内存中,然后执行逻辑读操作返回数据。

以上oracle数据库的一般数据读取流程,但是在进行Full Table Scan时,情况可能有些不同。
在默认情况下,当从磁盘读取数据时,会将读取到的缓存在LRU链表的中间位置,以此保证经常使用的数据块依然保留在buffer cache中。但是在进行全表扫描时,很有可能读取的数据块大小超过了buffer cache的大小,如果直接放进内存则会将内存中原本的数据全都age out出去,这样会导致数据库性能的下降。

在进行全表扫描时,如果一个表所需的内存占buffer cache很小的一个百分比,那么就会将其加载至内存中。对一个中等大小的表,数据库会权衡最后一次表扫描,buffer cache的老化时间戳和buffer cache中剩余空间等因素来决定是否将其加载到内存中。对于一个很大的表,那么数据库就倾向于直接使用direct path read,直接把数据加载到PGA中,避免频繁的age out buffer cache中的数据块。

当然也可以使用ALTER TABLE (table_name) CACHE来将大表的数据缓存到buffer Cache中。
当我们执行DML语句对数据进行更新的时候也是会在buffer cache中操作的,更新后的数据会在以下情况将脏数据写回磁盘:

  • 当无法找到clean buffer来读取数据块
  • 数据库执行检查点
  • 更改表空间状态为只读或离线状态

大多数时候我们说的buffer cache指的是默认的Default Buffer Pool,根据不同用途和大小,还有很多不同类型的buffer pool:

  • Default Buffer Pool:缺省情况下的Cache,大小由DB_CACHE_SIZE指定
  • Keep Buffer Pool:该内存区域用于缓存那些需要经常使用但是又总是被age out出Default * Buffer Pool的数据,其大小由DB_KEEP_CACHE_SIZE指定。可使用ALTER TABLE … STORAGE BUFFER_POOL KEEP语句来修改表的默认缓存位置为Keep Buffer Pool。
  • Recycle Buffer Pool:放在这个区域中的数据一用完就会被移出。对于那些体积巨大、偶尔使用的表,可以考虑放在这个内存中,以尽快释放内存

以上的Buffer Pool都只适用于标准大小的数据块。默认情况下创建的表空间都是使用的8K数据块,当我们创建非标准数据块的表空间(如:2K,4K,16K)这些数据块则会放进其单独的pool中。

Redo Log Buffer

redo log buffer是一个循环缓冲区,用于LGWR进程将redo record写入redo log前缓存该数据。该区域通常只有几MB,当一个进程执行DML或者DDL操作时,数据库会记录下该操作产生的Redo record,并保存到Redo Log Buffer中。以下情况,LGWR进程会把redo buffer中的数据写到redo log file中:
1、每3秒钟或redo log buffer内已达到1/3满或包含1MB数据
2、用户执行commit语句
3、DBWn进程将修改的缓冲区写入磁盘时(如果相应的重做日志数据尚未写入磁盘)

Shared Pool

Shared Pool是一块非常重要的内存区域,特别是对于OLTP系统而言,其中保存了各种类型的程序数据:PL/SQL代码,解析的查询语句,执行计划,系统参数,数据字典等。对于shared server模式,该内存区域也含括了private SQL area。
在这里插入图片描述
1、Library Cache
用来存储可执行的SQL或PL/SQL代码所对应的执行计划、解析树、Pcode、Mcode等对象以及控制结构(如,锁和库缓存句柄),当我们再次执行相同的sql时就不需要再解析。
Library cache中的对象,称为库缓存对象,oracle通过库缓存句柄来访问库缓存对象。
2、Data Dictionary Cache
则用于存储数据库对象的相关信息,在执行SQL语句解析期间会频繁的访问该内存区域。

在Library cache中,主要关注的是CRSR这类库缓存对象(SQL和匿名PL/SQL对象)称为shared cursor,涉及到SQL的解析,对于OLTP系统而言至关重要。shared cursor又可以分为parent cursor和child cursor,可以分别通过v$sqlarea和v$sql查看对应的cursor。parent cursor存储目标SQL的SQL文本,而child cursor存储解析树和执行计划。

oracle在解析目标SQL时去库缓存查询shared cursor的流程如下:

  • 根据目标SQL的hash值去寻找对应的Hash Bucket,不同的SQL有可能产生相同的hash值,相同的SQL不同的语义也会产生相同的Hash值
  • 在Hash Bucket中查找匹配的Parent cursor,解决了不同SQL产生相同hash值得问题
  • 再查找匹配的child cursor,解决相同的SQL不同的语义也会产生相同的Hash值问题
  • 找到对应的child cursor后,把对应的解析树和执行计划拿去重用

例:test_env和test_env1都有相同的表tb_table_list,执行相同的sql后,他们有共同的parent cursor但是对应的child cursor是不同的。
test_env用户执行

SQL> select count(*) from tb_table_list;

  COUNT(*)
----------
      2138

test_env1用户执行

SQL> select count(*) from tb_table_list;

  COUNT(*)
----------
      2138

接下来分别查看parent cursor和child cursor

SQL> select sql_text,sql_id,version_count from v$sqlarea where sql_text like 'select count(*) from tb_table%';

SQL_TEXT                                 SQL_ID               VERSION_COUNT
---------------------------------------- -------------------- -------------
select count(*) from tb_table_list       92t0jfpufyv5z                    2

SQL> select plan_hash_value,child_number from v$sql where sql_id='92t0jfpufyv5z';

PLAN_HASH_VALUE CHILD_NUMBER
--------------- ------------
     2263858792            0
      774255499            1

VERSION_COUNT表示某个parent cursor拥有的child cursor数量。可以看到对于相同的sql语句,所生产的parent cursor是相同的,但是对应了不同的解析树和执行计划,因为两个tb_table_list属于不同的用户。
如果在library cache中并没有找到对应SQL的解析树和执行计划,那么此时就会产生OLTP系统的万恶之源——硬解析。对于一个高并发的系统,频繁的进行硬解析会导致严重Latch和Mutex的争用,使系统性能下降。

Large Pool

Large Pool主要用于RMAN备份时I/O子系统缓存以及并发执行语句的消息缓存。

Java Pool

Java pool则用于支撑java虚拟机相关内存需求。

Fixed SGA

Fixed SGA是oracle内部管理的一块区域,不能被修改,只会因为oralce数据库版本的不同而有可能产生差异。

PGA

PGA是特定于操作系统进程或线程的内存。下图是dedicated server模式下PGA包含的区域:
1、SQL Work Area
2、Private SQL Area
3、Session Memory
在这里插入图片描述

SQL Work Area

用于排序、位图合并、哈希连接等内存密集型的操作,这些操作会首先在SQL WORK AREA中进行,当分配的内存空间不足时将部分数据写入磁盘的TEMPSPACE表空间。PGA的一大部分被分配给Work Area,用来执行如下操作:
1、基于操作符的排序,group by、order by、rollup和窗口函数
参数为sort_area_size
2、hash散列连接
参数为hash_area_size
3、位图合并
参数为bitmap_merge_area_size
4、位图创建
参数为create_bitmap_area_size
5、批量装载操作使用的写缓存

Private SQL Area

保存了当前会话的绑定信息以及运行时内存结构。每个执行sql语句的会话,都有一个private sql area。当多个用户执行相同的sql语句,此sql语句保存在一个称为shared sql area。此share sql area被指定给这些用户的private sql area。
共享服务器模式下,private sql area位于SGA的share pool或large pool中。专用服务器模式下,private sql area位于PGA中
1、Persistent Area
存储变量绑定的值,当游标关闭时释放该区域内存。
2、Runtime Area
当发起query execute请求时,首先会创建该区域,用于存储相关状态信息。例如,做全表扫描时,已检索的行数。

Session Memory

保存了会话的变量,如登录信息及其他与会话相关的信息,共享服务器模式下,Session memory是共享的。

UGA

UGA是一块用来存储会话状态相关的内存区域。取决于是否通过shared server模式还是Dedicated Server模式连接,它可能存在于SGA或者PGA中。

Shared Server – UGA存在于SGA中
Dedicated Server – UGA存在于PGA中

附:
Dedicated Server(专用服务器模式)
Oracle会为每个用户访问创建一个服务进程来进行服务,即对于每一个客户端的访问,都会生成一个新的进程进行服务,是一种类似一对一的映射关系。这种连接模式的一个很重要的特点就是UGA(用户全局域)是存储在PGA(进程全局域)中的,这个特性也很好说明了当前用户的内存空间是按照进程来进行分配的。
一般服务器内存足够的话,建议使用Dedicated Server模式。

Shared Server(共享服务器模式)
数据库初始化的时候就会创建一批服务器连接的进程,然后把这些连接进程放入一个连接池来进行管理。初始化的进程数量可以在数据库创建时手动设置。
用户连接建立时,Listener首先接受到客户端的建立连接的请求,然后Listener去生成一个叫做调度器(dipatcher)的进程与客户端进行连接。调度器把把客户端的请求放在SGA(系统全局域)的一个请求队列中,然后再共享服务器连接池中查找有无空闲的连接,然后让这个空闲的服务器进行处理。处理完毕以后再把处理结果放在SGA的相应队列中。调度器通过查询相应队列,得到返回结果,再返回给客户端。
这种连接模式的优点在于服务器进程的数量可以控制,不大可能出现因为连接人数过多而造成服务器内存崩溃。但是由于增加了复杂度以及请求相应队列,可能性能上有所下降。

————————————————
版权声明:本文为CSDN博主「我不是VIP」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。对原博文进行了修改和补充。
原文链接:https://blog.csdn.net/u010343795/article/details/89061941

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值