我的DBA之路——对内存体系的整理

  • 内存区存储信息:
1、程序代码
2、有关每个已连接会话的信息,无论其当前是否处于活动状态
3、在程序执行期间所需的信息,例如,正在索取数据的查询的当前状态
4、在多个进程之间被共享和传递的信息,如锁信息
5、缓存数据,如数据块和重做记录等,它们也存在于磁盘上
  • 基本内存结构:
1、系统全局区(SGA)
SGA 是一组称为SGA 组件的共享内存结构,其中包含一个 Oracle 数据库实例的数据和控制信息。SGA由所有服务器进程和后台进程共享。例如,SGA中存储的数据包括数据块缓存和共享 SQL区
2、程序全局区(PGA)
PGA 是一个非共享的内存区域,其中包含专门供某个Oracle 进程使用的数据和控制信息。Oracle 进程启动时, Oracle 数据库会为其创建 PGA
每个服务器进程和后台进程都存在一个PGA。所有单个PGA的集合即是总实例 PGA,或实例 PGA。数据库初始化参数设置实例 PGA的大小,而不是单个PGA的大小
3、用户全局区(UGA)
UGA 是与某个用户会话相关联的内存区
4、软件代码区
软件代码区是用来存储正在运行或可能要运行的代码的那部分内存。Oracle 数据库代码通常存储在与用户程序不同的位置, ——一个更专门或更受保护的位置


  • 内存管理方式:
1、自动内存管理
您指定实例内存的目标大小。数据库实例自动优化到这个目标内存大小,根据需要在SGA 和 PGA 实例之间重新分配内存
2、自动共享内存管理
这种管理模式是部分自动化的。您设置一个SGA 的目标大小,然后设置 PGA 总目标大小,或单独管理 PGA 的各个工作区
3、手动内存管理
你不必设置总的内存大小,但您需要设置许多初始化参数,以单独管理SGA 和PGA实例中的各个组件
  • 用户全局区 (UGA):

该 UGA 必须在数据库会话的整个存活期间是可用的。由于这个原因,当使用共享服务器的连接时,UGA 不能存储在 PGA中,因为 PGA 是特定于单个进程的。 因此,当使用共享服务器的连接时, UGA 被存储在 SGA中,以使任何共享服务器进程都能访问它。在使用专用服务器的连接时,UGA 存储在 PGA 中
  • 程序全局区(PGA):



1、私有SQL区
私有SQL 区保存了有关某个已解析的 SQL 语句的信息,和其他特定于会话的信息。当服务器进程执行 SQL 或PL/SQL 代码时,该过程使用其私有SQL 区域,来存储绑定变量值、 查询执行状态信息、和查询执行工作区
游标是指向某个特定的私有SQL 区的一个名称或句柄。 你可以将游标看成是一个从客户端指向服务器端状态信息的指针)。游标与私有SQL区密切相关,这两个术语有时可以互换使用

私有SQL区域:
a、运行时区域
此区域包含查询执行状态信息。例如,运行时区域会跟踪到目前为止在全表扫描中检索到的行数
Oracle 数据库将创建运行时区域,作为一个执行请求的第一步。对于 DML 语句,其运行时区域将在SQL 语句关闭时被释放
b、持久区域
此区域包含绑定变量的值。绑定变量是执行SQL语句时,在运行时提供给SQL语句的值。仅当关闭该游标时,持久区域才被释放
2、SQL工作区
工作区是在PGA中为内存密集型操作分配的私有内存区。例如,排序操作使用排序区来对一组行进行排序。同样,哈希联接操作将其左侧数据为输入,并使用哈希区来创建一个哈希表,而位图合并操作则使用位图合并区来合并从扫描多个位图索引检索到的数据
3、在专有和共享服务器中使用的PGA
PGA 内存分配取决于数据库是使用专用的还是共享的服务器连接。表 14-1 显示了差异之处

  • 系统全局区(SGA):
SGA 是一个可读写的内存区,与 Oracle 后台进程一起组成数据库实例。所有以用户名义执行的服务器进程,都可以读取 SGA 实例中的信息。在数据库操作过程中,有几个进程会对SGA进行写入操作
1、数据缓存区高速缓存(Database Buffer Cache)
数据库缓冲区高速缓存,也称为缓冲区高速缓存,是用于存储从数据文件读取的数据块副本的内存区域。缓冲区是缓冲区管理器用来暂时缓存当前或最近使用的数据块的主内存地址。所有同时都连接到一个数据库实例的用户,以共享方式访问缓冲区高速缓存
缓冲区高速缓存的目的:
a、优化物理I/O
数据库更新缓存中的数据块,并将有关更改的元数据存储在重做日志缓冲区。提交之后,数据库将重做缓冲区写入磁盘,但不一定会立即将数据块写入磁盘。相反,数据库写入器 (DBWn) 在后台执行惰性写入操作
b、将频繁访问的块保持在缓冲区高速缓存中,而将不常存取的块写到磁盘
当启用了数据库智能闪存高速缓存 (flash 高速缓存)时, 缓冲区高速缓存的一部分可能驻留在闪存缓存中。此缓冲区高速缓存扩展存储在闪存磁盘设备上,这是一种使用闪存的固态存储设备。通过将缓冲区缓存到闪存中,而不是从磁盘读取,数据库可以提高性能
注意:数据库智能闪存高速缓存仅在 Solaris 和 Oracle 企业 Linux 中可用
缓冲区状态:
a、未使用的
缓冲区可供使用,因为它从未使用过,或者当前未使用。这种类型的缓冲区是数据库最容易使用的
b、干净的
此缓冲区在之前曾被使用过,而现在包含某个数据块在某个时间点的读取一致版本。块包含数据但是干净的,因此它不需要将执行检查点操作。数据库可以订住该块并重用它
c、脏的
缓冲区包含已修改、但尚未写入到磁盘的数据。数据库在重用该数据块之前必须对其执行检查点操作

每个缓冲区具有两种访问模式之一: 订住的或空闲的 (未订住)。缓冲区被"订住"在缓存中,以便当其被某个用户会话访问时,它不会因为内存不足被换出内存。多个会话不能在同一时间修改某个已被订住的缓冲区
数据库使用复杂的算法以使缓冲区访问高效。最近最少使用 (LRU) 列表有一个热端和冷端,同时存在指向同一LRU上的脏缓冲区和非脏缓冲区的指针。冷缓冲区是最近未被使用的。热缓冲区是被频繁访问并在最近已使用的
注意:从概念上讲,只有一个 LRU, 但为了并发,数据库实际上使用多个LRU
缓存区模式:
a、当前模式
当前模式获取,也称为数据库块获取,这是一种对当前已出现在缓冲区高速缓存中的块的检索。例如,如果一个未提交事务已更新某个块中的两行,则当前模式获取会检索这个具有未提交行的块。数据库最常使用数据库块获取的情况是在修改语句期间,它只需更新块的当前版本
b、一致模式
一致读取获取是对某个块的一致读取版本的检索。此检索可能会使用撤消数据。例如,如果一个未提交事务已更新某个块中的两行,而在另一个独立会话中的查询请求该块,则数据库使用撤消数据来创建该块的一个读取一致版本(称为一致读取克隆),它不包括未提交的更新。通常,查询以一致模式检索块
缓冲区I/O:
逻辑I/O,也称为缓冲区 I/O,指的是读取和写入缓冲区高速缓存中的缓冲区。当在内存中找不到请求的缓冲区时,数据库将执行一个物理 I/O,将缓冲区从闪存缓存或磁盘复制到内存,然后再执行一个逻辑 I/O,以读取缓存的缓冲区
1)、缓存区写出:
a、服务器进程找不到干净的缓冲区,以将新块读入数据库缓冲区高速缓存
b、数据库必须推进检查点,即重做线程中进行实例恢复的起点
c、表空间被更改为只读状态,或脱机
2)、缓存区读取:
a、禁用了闪存高速缓存
数据库中根据需要覆盖并重新利用每个干净的缓冲区。如果以后需要重用被覆盖的缓冲区,则数据库必须从磁盘重新读取
b、启用了闪存高速缓存
DBWn 将干净缓冲区的正文写入到闪存缓存,使其内存中的缓冲区可以被重用。数据库在主内存中保留 LRU 列表的缓冲区头,以跟踪在闪存缓存中的缓冲区体的状态和位置。如果以后需要该缓冲区,则数据库可以从闪存缓存中读取它,而不用从磁盘读取
服务器在缓冲区高速缓存中的搜索顺序:
a、服务器进程在缓冲区高速缓存中搜索整个缓冲区
如果该进程发现整个缓冲区,则数据库对此缓冲区执行一个逻辑读取
b、服务器进程在闪存缓存LRU 列表中搜索缓冲区头
如果该进程找到了缓冲区头,则数据库执行一个优化的物理读取,将缓冲区正文从闪存缓存读入到内存内缓存
c、如果该进程没有在内存中找到该缓冲区(缓存未命中),则服务器进程将执行以下步骤:
1)、将该块从数据文件复制到内存中 (物理读取)
2)、对已读入到内存中的缓冲区执行一个逻辑读取

缓存区触摸计数:
数据库使用触摸计数来测量对 LRU 列表上的缓冲区进行访问的频率。这种机制使得当某个缓冲区被订住时数据库可以增加一次计数,而不用不断地移动LRU 列表上的缓冲区
缓冲区和全表扫描:
当缓冲区必须从磁盘读入时, 数据库会将缓冲区插入到 LRU 列表的中部。通过这种方式,热块可以保留在缓存中,以使他们不需要再次从磁盘读取
全表扫描顺序读取表高水位下的所有行,这可能引发一个问题。假设表段中块的总大小大于缓冲区高速缓存的大小。在此表上的全表扫描可能会清除高速缓存,致使数据库不能将频繁访问的块维持在高速缓存中
大型表的完全扫描导致将块读入数据库高速缓存,与其他类型读取的处理方式有所不同。(在完成扫描之后,这些缓冲区中的)块可以被立即重用,以防止该扫描真正地清理缓冲区高速缓存
在某些少有的情况下,若默认行为不是你所希望的,您可以更改表的CACHE属性。在这种情况下,数据库不会在缓存中强制或订住块,而是与任何其他块相同的方式,让其从高速缓存中老化移出。使用此选项时要小心,因为大表的全表扫描可能会将大部分的其他块从缓存中清理出去
缓冲区池:
缓冲池是缓冲区的集合。数据库缓冲区高速缓存被划分为一个或多个的缓冲池
a、缺省池
该池是块通常被缓存的地方。除非您手动配置单独的池,默认池将是唯一的缓冲池
b、保留池
该池用于被频繁访问的块,使其不会由于缺省池的空间不足而被移出。保留缓冲池的目标是将对象保留在内存中,从而避免 I/O 操作
c、循环池
该池用于不被频繁使用的块。循环池防止对象在缓存中占用不必要的空间

2、重做日志缓冲区(Redo Log Buffer)
重做日志缓冲区是SGA中的一个循环式缓冲区,用来存储对数据库所做更改的重做条目。重做条目包含用于重建(或重做)由 DML 或 DDL 操作对数据库所做更改所需的信息。数据库恢复将重做条目应用到数据文件,以重建丢失的更改

LOG_BUFFER 初始化参数指定了 Oracle 数据库在缓冲重做条目时所能使用的内存量。与其他的 SGA 组件不同,重做日志缓冲区和固定的 SGA 缓冲区不按颗粒划分内存
3、共享池(Shared Pool)
共享池缓存各种类型的程序数据。例如,共享池存储已解析的 SQL、 PL/SQL 代码、 系统参数、和数据字典信息。几乎数据库中发生的每个操作都涉及到共享池。例如,如果用户执行一个SQL 语句,则Oracle 数据库会访问共享池

库缓存
库缓存是存储可执行 SQL 和 PL/SQL 代码的共享池内存结构。此缓存包含共享SQL 和 PL/SQL区,以及锁和库缓存句柄之类的控制结构。在共享服务器体系结构中,库缓存还包含私有SQL区
在执行 SQL 语句时,数据库将尝试重用以前执行过的代码。如果在库缓存中存在该SQL 语句的已解析表示形式,并且是可以共享的,则数据库会重用该代码,这称为软解析或库缓存命中。否则,数据库必须为应用程序代码建立一个新的可执行版本,这称为硬解析或库缓存未命中
1)、共享SQL区:
a、共享SQL区
数据库使用共享SQL 区来处理 SQL 语句第一次发生时的情况。该区域对所有用户可访问,并包含语句的解析树和执行计划。对于每个唯一的语句,只存在一个共享SQL区
b、私有SQL区
每个发出 SQL 语句的会话在其 PGA中有一个私有SQL 区。提交同一语句中的每个用户都分别有一个私有SQL 区,但都指向同一共享 SQL 区。因此,在多个单独PGA中的私有 SQL区可能与同一共享SQL 区相关联
执行步骤:
1)、检查共享池,看是否存在某个语法和语义上都相同的语句的共享 SQL 区
a、如果存在这样一个相同的语句,则数据库为该语句的后续新实例使用这个共享SQL 区,从而减少内存消
b、如果不存在这样一个相同的语句,则数据库在共享池中分配一个新的共享SQL 区。语法相同、但语义不同的语句会使用一个子游标
2)、为该会话分配一个私有SQL 区
私有SQL 区的位置取决于该会话所建立的连接。如果会话是通过共享服务器连接的,则该私有SQL 区中的一部分被保存在 SGA中

程序单元和库缓存:
库缓存包含PL/SQL 程序和 Java 类的可执行形式。这些项目统称为程序单元
共享池中的内存分配和重用:
当解析新的 SQL 语句时,数据库将分配共享池内存。内存大小取决于语句的复杂性
通常,共享池中的项目会一直保留,直到按LRU 算法将其移除。数据库允许共享池中用于多个会话的项目被保留在内存中,只要他们还有用,即使创建该项目的进程已经终止。这一机制能最小化开销和对SQL 语句的处理
如果需要为新项目腾出空间,则数据库会释放内存中不常使用的项目。某个共享的 SQL 区可能会被从共享池中删除,即使该共享SQL 区对应于一个已打开但已有一段时间未使用的游标。如果随后又需要运行这个已打开的游标,则 Oracle 数据库重新解析该语句并分配新的共享 SQL 区
1)、从共享池中删除共享SQL区
a、如果为表、 表簇、或索引收集了统计信息,则默认情况下,数据库在一段时间后,会逐步删除所有包含引用了已分析对象的语句的共享SQL 区。下次运行某个已删除的语句时,数据库将在一个新的共享 SQL 区中对其进行解析,以反映模式对象的新的统计信息
b、如果一个模式对象在某个 SQL 语句中被引用,而之后此对象被某个DDL 语句修改,则数据库将使这个共享 SQL 区无效。当下一次运行该语句时,优化程序必须重新解析该语句
c、如果更改了全局数据库名称,则数据库将删除所有共享池信息
你可以使用ALTER SYSTEM FLUSH SHARED_POOL语句,手动删除共享池中的所有信息,以评估实例重新启动后预期的性能
数据字典缓存:
数据字典是数据库表和视图的集合,其中包含有关数据库及其结构、用户等参考信息。Oracle 数据库在解析SQL 语句期间,会频繁访问数据字典
数据字典的内存位置:
a、数据字典缓存
此缓存保存有关数据库对象的信息。此缓存也称为行缓存,因为它按行、而不是按缓冲区保存数据
b、库缓存
所有服务器进程都共享这些缓存来对数据字典信息进行访问
服务器结果缓存:
与缓冲池保存数据块不同,服务器结果缓存保存的是结果集。服务器结果缓存包含SQL 查询结果缓存和 PL/SQL 函数结果缓存,它们共享相同的基础结构
客户端结果缓存不同于服务器结果缓存。客户端缓存在应用程序级别配置,并位于客户端内存中,而不是位于数据库内存中
a、SQL查询结果缓存
数据库能在SQL 查询结果高速缓存中存储查询和查询片段的结果,将此缓存结果用于将来的查询和查询片段。大多数应用程序受益于这种性能改善
b、PL/SQL 函数结果缓存
PL/SQL 函数结果缓存存储函数的结果集。若不使用缓存功能,每次调用花1秒钟的函数,调用该函数1000次将花时间1000 秒。而缓存后,以相同的输入调用函数1000次总共仅需要时间1 秒。对于在相对静态的数据上被频繁调用的函数,结果缓存是一个很好的选择
保留池:
保留池是共享池中的一个内存区, Oracle 数据库使用它来分配大的连续内存块
从共享池中分配内存是按大块执行的。大块使得大型对象(超过 5 KB)可以被加载到缓存中,而不需要一个单一的连续区域。这样一来,数据库中由于碎片引起的连续内存不足的可能性降低了
有时,Java、 PL/SQL、或 SQL 游标也可能会从共享池中分配大于 5 KB 的内存块。为使这种分配更有效,数据库从共享池中为保留池隔离出少量内存
4、大池(Large Pool)
大池是一个可选的内存区域,它所提供的内存分配往往比共享池分配的内存更大
可提供大内存分配:
a、共享服务器的UGA,和 Oracle XA接口 (用于与多个数据库进行交互的事务)
b、并行执行语句中使用的消息缓冲区
c、恢复管理器 (RMAN) I/O 从属进程的缓冲区
通过从大池中为共享SQL分配会话内存,数据库可以避免由收缩共享 SQL 缓存引起的性能开销。通过为 RMAN 操作、I/O 服务器进程、和并行缓冲区等分配大的缓冲区内存,大池可以比共享池更好地满足大型内存请求

共享池中的保留空间与其它内存分配都使用同一LRU列表,而大池与此不同,它根本就没有LRU 列表。这些被分配的内存片断直到操作完成后才会被释放。一旦释放了一个大块内存,其他进程就可以使用它
5、Java池(Java ool)
Java 池是一个存储Java 虚拟机 (JVM) 内所有会话特定的 Java 代码和数据的内存区。此内存包括在调用端迁移到 Java 会话空间的Java 对象
对于专用服务器连接,Java 池包括每个 Java 类的共享部分,包括方法和只读内存,如代码向量,但不包括每个会话的Java 状态。对于共享服务器,Java池包括每个 Java 类的共享部分,和用于每个会话状态的一些 UGA 。每个 UGA 根据需要增长和缩小,但总的 UGA 大小必须适应 Java 池空间
6、流池(Streams Pool)
流池用于存储缓冲的队列消息,并为 Oracle 流的捕获进程和应用进程提供内存。流池专门由Oracle 流使用
如果您没有专门配置流池,则其大小从零开始。流池的大小由Oracle 流按需动态增长
7、固定SGA(Fixed SGA)
固定SGA 是内部的内务管理区域
固定SGA 包含:
a、有关数据库及其实例状态的一般信息,后台进程需要访问这些信息
b、进程间通讯的信息,如有关锁的信息
固定 SGA 的大小由 Oracle 数据库设置,且不能手动更改。固定SGA 大小可能会因为版本不同而不同
  • 软件代码区
软件代码区是用于存储正在运行或可以运行的代码的那部分内存。Oracle数据库代码的存储位置通常比用户程序更专用、更受保护
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值