内存体系结构

本章讨论数据库实例的内存体系结构。

Oracle AI Database 内存结构简介

启动实例时,Oracle AI Database 将分配内存区域并启动后台进程。

内存区存储如下信息:

基本内存结构

Oracle AI Database 包括多个内存区域,每个区域都包含多个子组件。

与 Oracle AI Database 关联的基本内存结构包括:

下图显示了这些内存结构之间的关系。

图 1:Oracle AI Database 内存结构

插图 cncpt217.png 的说明

Oracle AI Database 内存管理

内存管理涉及根据数据库更改需要使 Oracle 实例的内存结构保持最优大小。Oracle AI Database 基于内存相关初始化参数的设置来管理内存。

内存管理的基本选项如下:

如果使用数据库配置辅助程序 (Database Configuration Assistant,DBCA) 创建数据库并选择基本安装选项,则默认使用自动内存管理。

另请参见:

系统全局区 (System Global Area,SGA) 概述

SGA 是读/写内存区,它与 Oracle 后台进程一起构成数据库实例。注:服务器和后台进程不在 SGA 的范围内,而存在于单独的内存空间中。

代表用户执行的所有服务器进程都可以在实例 SGA 中读取信息。多个进程在数据库操作期间写入 SGA。

每个数据库实例都有自己的 SGA。Oracle AI Database 在实例启动时自动为 SGA 分配内存,并在实例关闭时回收内存。使用 SQL*Plus 或 Oracle Enterprise Manager 启动实例时,显示 SGA 的大小,如下例所示:

SQL> STARTUP
ORACLE instance started.

Total System Global Area  368283648 bytes
Fixed Size                  1300440 bytes
Variable Size             343935016 bytes
Database Buffers           16777216 bytes
Redo Buffers                6270976 bytes
Database mounted.
Database opened.

如图 17-1 中所示,SGA 包含多个内存组件,这些组件是用于满足特定类别的内存分配请求的内存池。除了重做日志缓冲区以外,所有 SGA 组件都以称为 granules 的连续内存为单位分配和取消分配空间。区组大小特定于平台,由总 SGA 大小决定。

可以查询 V$SGASTAT 视图以了解有关 SGA 组件的信息。

最重要的 SGA 组件如下:

另请参见:

数据库缓冲区缓存

数据库缓冲区高速缓存也称为缓冲区高速缓存,是存储从数据文件读取的数据块副本的内存区。

缓冲区是缓冲区管理器在其中临时缓存当前或最近使用的数据块的主内存地址。并发连接到数据库实例的所有用户共享对缓冲区高速缓存的访问权限。

数据库缓冲区高速缓存的用途

Oracle AI Database 使用缓冲区高速缓存来实现多个目标。

目标包括:

另请参见:

缓冲区状态

数据库使用内部算法管理高速缓存中的缓冲区。

缓冲区可以处于以下任何互斥状态:

每个缓冲区都有一个访问模式:固定或空闲(未固定)。缓冲区将“固定”在高速缓存中,以便在用户会话访问缓冲区时不会耗尽内存。多个会话无法同时修改固定的缓冲区。

缓冲区模式

当客户机请求数据时,Oracle AI Database 会以当前模式或一致模式从数据库缓冲区高速缓存中检索缓冲区。

模式不同,如下所示:

另请参见:

缓冲区 I/O

逻辑 I/O 也称为缓冲区 I/O ,指的是缓冲区高速缓存中缓冲区的读取和写入。

在内存中找不到请求的缓冲区时,数据库将执行物理 I/O 以将缓冲区从闪存高速缓存或磁盘复制到内存中。然后,数据库执行逻辑 I/O 来读取缓存的缓冲区。

缓冲区替换算法

为了提高缓冲区访问效率,数据库必须决定要在内存中高速缓存哪些缓冲区以及从磁盘访问哪些缓冲区。

数据库使用以下算法:

另请参阅:Oracle AI Database VLDB and Partitioning Guide 以了解有关基于温度的算法的更多信息

缓冲区写入数

数据库写进程 (database writer,DBW) 进程定期将冷的脏缓冲区写入磁盘。

DBW 在以下情况下写入缓冲区:

另请参见:

缓冲区读取数

当未使用的缓冲区数量较少时,数据库必须从缓冲区高速缓存中删除缓冲区。

该算法取决于是否启用了闪存高速缓存:

当客户机进程请求缓冲区时,服务器进程在缓冲区高速缓存中搜索缓冲区。如果数据库在内存中找到缓冲区,则会发生高速缓存命中。搜索顺序如下:

  1. 服务器进程在缓冲区高速缓存中搜索整个缓冲区。

    如果进程找到整个缓冲区,则数据库将执行此缓冲区的逻辑读取。

  2. 服务器进程在闪存高速缓存 LRU 列表中搜索缓冲区标头。

    如果进程找到缓冲区标头,则数据库将执行缓冲区主体从闪存高速缓存到内存中高速缓存的优化物理读取。

  3. 如果进程未在内存中找到缓冲区(高速缓存未命中),则服务器进程将执行以下步骤:

    1. 将块从磁盘上的数据文件复制到内存中(物理读取)

    2. 对已读入内存的缓冲区执行逻辑读取

图 17-2 说明了缓冲区搜索顺序。扩展缓冲区高速缓存包括内存中缓冲区高速缓存(包含整个缓冲区)和闪存高速缓存(包含缓冲区主体)。在图中,数据库在缓冲区高速缓存中搜索缓冲区,如果找不到缓冲区,则将其从磁性磁盘读取到内存中。

图 2:缓冲区搜索

插图 cncpt304.gif 的说明

通常,通过高速缓存命中访问数据比通过高速缓存未命中访问数据要快。缓冲区高速缓存命中率衡量数据库在缓冲区高速缓存中找到请求的块的频率,而无需从磁盘读取该块。

数据库可以从数据文件或临时文件执行物理读取。从数据文件读取后跟逻辑 I/O。当内存不足迫使数据库将数据写入临时表并在以后读回临时文件时,会发生从临时文件读取。这些物理读取会绕过缓冲区高速缓存,不会产生逻辑 I/O。

另请参阅:Oracle AI Database Performance Tuning Guide,了解如何计算缓冲区高速缓存命中率

缓冲区接触计数

数据库使用触摸计数测量 LRU 列表中缓冲区的访问频率。此机制允许数据库在锁定缓冲区时递增计数器,而不是不断在 LRU 列表中移动缓冲区。

注:数据库不会以物理方式移动内存中的块。移动是指针在列表中的位置的更改。

固定缓冲区时,数据库将确定其触摸计数上次递增的时间。如果计数在三秒前递增,则计数递增;否则,计数保持不变。三秒规则可防止缓冲区上的引脚出现突发,并计算任意数量的触点。例如,会话可以在数据块中插入多个行,但数据库会将这些插入视为一次触摸。

如果某个缓冲区位于 LRU 的冷端,但其触摸计数较高,则该缓冲区将移动到热端。如果触摸计数较低,则缓冲区会从高速缓存中老化。

缓冲池

缓冲区池是缓冲区的集合。

数据库缓冲区高速缓存划分为一个或多个缓冲区池,这些缓冲区池主要以相同的方式管理块。对于老化或高速缓存块,池没有完全不同的算法。

您可以手动配置单独的缓冲池,以将数据保留在缓冲区高速缓存中,或者在使用数据块后立即使缓冲区可用于新数据。然后,您可以将特定方案对象分配给相应的缓冲区池,以控制块在高速缓存中的存活时间。例如,可以将段隔离到热缓冲池、热缓冲池和冷缓冲池中。

可能的缓冲池如下所示:

数据库具有标准块大小。可以创建块大小不同于标准大小的表空间。每个非默认块大小都有自己的池。Oracle AI Database 以与默认池相同的方式管理这些池中的块。

下图显示了使用多个池时缓冲区高速缓存的结构。高速缓存包含默认池、保留池和回收池。缺省块大小为 8 KB。高速缓存包含使用非标准块大小(2 KB、4 KB 和 16 KB)的表空间的单独池。

图 3:数据库缓冲区高速缓存

插图 cncpt220.gif 的说明

另请参见:

缓冲区和全表扫描

数据库使用复杂的算法来管理表扫描。缺省情况下,当必须从磁盘读取缓冲区时,数据库会将缓冲区插入 LRU 列表的中间。通过这种方式,热块可以保留在高速缓存中,以便不需要再次从磁盘读取它们。

全表扫描会导致问题,该扫描按顺序读取表高水位标记 (high water mark,HWM) 下的所有行。假定表段中块的总大小大于缓冲区高速缓存的大小。完全扫描此表可以清除缓冲区高速缓存,从而防止数据库维护频繁访问的块的高速缓存。

全表扫描的默认模式

默认情况下,数据库采用保守方法进行全表扫描,仅当表大小占缓冲区高速缓存的很小百分比时才将小表加载到内存中。

为了确定是否应缓存中等大小的表,数据库使用一种算法,该算法包含了上次表扫描、缓冲区高速缓存的老化时间戳和缓冲区高速缓存中剩余的空间之间的间隔。

对于非常大的表,数据库通常使用直接路径读取,这种方式直接将块加载到 PGA 和完全绕过 SGA,以避免填充缓冲区高速缓存。对于中等大小的表,数据库可以使用直接读取或高速缓存读取。如果它决定使用高速缓存读取,则数据库会将块放置在 LRU 列表的末尾,以防止扫描有效地清除缓冲区高速缓存。

从 Oracle Database 12c 发行版 1 (12.1.0.2) 开始,数据库实例的缓冲区高速缓存将自动执行内部计算,以确定内存是否足以使数据库在实例 SGA 中完全高速缓存,以及访问时的高速缓存表是否有助于提高性能。如果整个数据库可以完全放入内存中,并且满足其他各种内部条件,则 Oracle AI Database 会将数据库中的所有表视为小表,并认为它们有资格进行高速缓存。但是,数据库不会高速缓存标记有 NOCACHE 属性的 LOB。

并行查询执行

在执行全表扫描时,数据库有时可以通过使用多个并行执行服务器来缩短响应时间。

在某些情况下,就像数据库具有大量内存时一样,数据库可以在系统全局区 (system global area,SGA) 中高速缓存并行查询数据,而不是使用直接路径读取到程序全局区 (program global area,PGA)。通常,由于潜在的资源使用情况,并行查询在低并发性数据仓库中发生。

另请参见:

CACHE 属性

在极少数情况下,不需要默认高速缓存行为,可以使用 ALTER TABLE ... CACHE 更改将大型表中的块读入数据库缓冲区高速缓存的方式。

对于设置了 CACHE 属性的表,数据库不会强制或固定缓冲区高速缓存中的块。相反,数据库会以与任何其他表块相同的方式将块从高速缓存中老化。在执行此选项时要小心,因为对大表的全面扫描可能会将大多数其他块从高速缓存中清除。注:执行 ALTER TABLE ... CACHE 不会导致要高速缓存的表。

KEEP 属性

对于大型表,可以使用 ALTER TABLE ... STORAGE BUFFER_POOL KEEP 将扫描将这些表的块加载到保留池中。

将表放置到保留池中会更改存储块的缓冲区高速缓存部分。数据库将块缓存到保留缓冲池中,而不是缓存默认缓冲池中的块。没有单独的算法控制来保持池高速缓存。

另请参见:

强制整个数据库高速缓存模式

为了在某些情况下提高性能,可以显式执行 ALTER DATABASE ... FORCE FULL DATABASE CACHING 语句以启用强制完全数据库高速缓存模式。

与默认模式(自动模式)不同,强制完全数据库高速缓存模式将整个数据库(包括 NOCACHE LOB)视为有资格在数据库缓冲区高速缓存中进行高速缓存。从 Oracle Database 12c 发行版 1 (12.1.0.2) 开始,此模式可用。注:启用强制整个数据库缓存模式不会强制将数据库置于内存中。相反,整个数据库符合高速缓存到缓冲区高速缓存中的条件。Oracle AI Database 仅在访问表时缓存表。

Oracle 建议仅在每个实例的缓冲区高速缓存大小大于数据库大小时启用强制完全数据库高速缓存模式。此准则适用于单实例数据库和 Oracle RAC 数据库。但是,当 Oracle RAC 应用程序分区良好时,当所有实例的组合缓冲区高速缓存(具有额外的空间来处理实例之间的重复高速缓存块)大于数据库大小时,可以启用强制完全数据库高速缓存模式。

另请参见:

DRAM 和 PMEM 缓冲区

标准 (DRAM) 数据库缓冲区与 PMEM 缓冲区不同,但它们具有相同的特征。

配置 Oracle Persistent Memory Filestore (PMEM Filestore) 时,每个数据块都会直接映射到 DRAM 中的缓冲区高速缓存。与 DRAM 缓冲区不同,PMEM 缓冲区不复制数据块的内容。相反,PMEM 缓冲区标头指向存储在 PMEM Filestore 中的数据块。对于大多数读取,数据库仅缓存块元数据,而不缓存内容。PMEM 缓冲区使用一种特殊类型的区组,其结构与标准缓冲区高速缓存区组不同。

注:初始化参数 DB_CACHE_SIZE 指定 DRAM 高速缓存的最小大小。此分配中不包括 PMEM 元数据开销。

PMEM 缓冲区可以处于以下任一状态:

PMEM 的延迟高于 DRAM。Oracle AI Database 使用基于工作负载的内部算法来确定要从 PMEM 迁移到 DRAM 的块。

另请参见:

重做日志缓冲

重做日志缓冲区是 SGA 中的一个循环缓冲区,用于存储描述对数据库所做的更改的重做条目。

重做记录是一种数据结构,其中包含重建或重做 DML 或 DDL 操作对数据库所做的更改所需的信息。数据库恢复将重做条目应用于数据文件以重建丢失的更改。

数据库处理将重做条目从用户内存空间复制到 SGA 中的重做日志缓冲区。重做条目占用缓冲区中的连续连续空间。后台进程日志写进程 (log writer process,LGWR) 将重做日志缓冲区写入磁盘上的活动联机重做日志组。图 17-4 显示了此重做缓冲区活动。

图 4:重做日志缓冲区

插图 cncpt226.gif 的说明

当 DBW 向磁盘执行数据块的分散写入时,LGWR 会按顺序将重做写入磁盘。散点写入往往比顺序写入慢得多。由于 LGWR 允许用户避免等待 DBW 完成其缓慢写入,因此数据库可以提供更好的性能。

LOG_BUFFER 初始化参数指定 Oracle AI Database 在缓冲重做条目时使用的内存量。与其他 SGA 组件不同,重做日志缓冲区和固定 SGA 缓冲区不会将内存划分为多个区组。

另请参见:

共享池

共享池可高速缓存各种类型的程序数据。

例如,共享池存储已解析的 SQL、PL/SQL 代码、系统参数和数据字典信息。共享池几乎涉及数据库中发生的每个操作。例如,如果用户执行 SQL 语句,则 Oracle AI Database 将访问共享池。

共享池分为多个子组件,其中最重要的子组件显示在 Figure 17-5 中。

图 5:共享池

插图 cncpt225.gif 的说明

此部分包含以下主题:

库缓存

库高速缓存是一种共享池内存结构,用于存储可执行的 SQL 和 PL/SQL 代码。

此高速缓存包含共享 SQL 和 PL/SQL 区域以及锁和库高速缓存句柄等控制结构。在共享服务器体系结构中,库高速缓存还包含专用 SQL 区域。

执行 SQL 语句时,数据库将尝试重用以前执行的代码。如果 SQL 语句的解析表示形式存在于库高速缓存中并且可以共享,则数据库将重用称为软语法分析或库高速缓存命中的代码。否则,数据库必须生成应用程序代码的新可执行版本,称为硬性语法分析或库高速缓存未命中。

共享 SQL 区域

数据库表示它在共享 SQL 区域和专用 SQL 区域中运行的每个 SQL 语句。

数据库使用共享 SQL 区域处理首次出现的 SQL 语句。此区域可供所有用户访问,并包含语句解析树和执行计划。唯一语句只存在一个共享 SQL 区域。发出 SQL 语句的每个会话的 PGA 中都有一个专用 SQL 区域。提交同一语句的每个用户都有一个指向同一共享 SQL 区域的专用 SQL 区域。因此,许多单独 PGA 中的专用 SQL 区域可以与同一共享 SQL 区域关联。

数据库自动确定应用程序何时提交类似的 SQL 语句。数据库考虑用户和应用程序直接发出的 SQL 语句以及其他语句在内部发出的递归 SQL 语句。

数据库执行以下步骤:

  1. 检查共享池以查看语法和语义相同的语句是否存在共享 SQL 区域:

    • 如果存在相同的语句,则数据库使用共享 SQL 区域执行该语句的后续新实例,从而减少内存消耗。

    • 如果不存在相同的语句,则数据库将在共享池中分配新的共享 SQL 区域。具有相同语法但不同语义的语句使用子游标。

    在任一情况下,用户的专用 SQL 区域都指向包含语句和执行计划的共享 SQL 区域。

  2. 代表会话分配专用 SQL 区域

    专用 SQL 区域的位置取决于为会话创建的连接。如果会话通过共享服务器连接,则部分专用 SQL 区域将保留在 SGA 中。

图 17-6 显示了专用服务器体系结构,其中两个会话将同一 SQL 语句的副本保留在自己的 PGA 中。在共享服务器中,此副本位于 MGA 中的 UGA 中。

图 6:专用 SQL 区域和共享 SQL 区域

插图 cncpt252.gif 的说明

另请参见:

程序单元和库高速缓存

库高速缓存保存 PL/SQL 程序和 Java 类的可执行形式。这些项统称为程序单元。

数据库处理程序单元的方式与 SQL 语句类似。例如,数据库会分配一个共享区域来存储 PL/SQL 程序的已解析、已编译形式。数据库将分配一个专用区来存储特定于运行程序的会话的值,包括本地、全局和程序包变量以及用于执行 SQL 的缓冲区。如果多个用户运行同一程序,则每个用户维护其专用 SQL 区域的单独副本,该副本保存会话特定的值,并访问单个共享 SQL 区域。

如前所述,数据库处理 PL/SQL 程序单元中的各个 SQL 语句。尽管这些 SQL 语句源自 PL/SQL 程序单元,但它们使用共享区域来存储其解析的表示,并为运行该语句的每个会话使用专用区域。

共享池中内存的分配和重用

解析新 SQL 语句时,数据库会分配共享池内存,除非该语句是 DDL(不被视为可共享)。分配的内存大小取决于语句的复杂性。

通常,共享池中的某个项会一直保留,直到数据库根据最近最少使用的 (LRU) 算法将其删除。数据库允许许多会话使用的共享池项在有用时保留在内存中,即使创建该项的数据库进程终止也是如此。此机制可最大程度地降低 SQL 语句的开销和处理。如果新项需要空间,则数据库将释放不经常使用的项占用的内存。

ALTER SYSTEM FLUSH SHARED_POOL 语句将删除共享池中的所有信息,更改全局数据库名称也是如此。

另请参见:

数据字典高速缓存

数据字典是包含有关数据库、数据库结构及其用户的参考信息的数据库表和视图的集合。

Oracle AI Database 在 SQL 语句解析期间会频繁访问数据字典。Oracle AI Database 经常访问数据字典,因此指定以下特殊内存位置来存储字典数据:

所有服务器进程共享这些高速缓存以访问数据字典信息。

另请参见:

服务器结果缓存

服务器结果高速缓存是共享池中的内存池。与缓冲区池不同,服务器结果高速缓存保存结果集,而不是数据块。注:客户机结果高速缓存与服务器结果高速缓存不同。客户机高速缓存是在应用程序级别配置的,位于客户机内存中,而不是数据库内存中。

SQL 查询结果缓存

SQL 查询结果高速缓存是服务器结果高速缓存的子集,用于存储查询和查询片段的结果。您可以在数据库或语句级别启用或禁用结果高速缓存。

执行查询时,数据库将确定结果是否存在于查询结果高速缓存中。如果未缓存结果,并且为查询启用了缓存,则数据库将运行查询,返回结果,然后对其进行缓存。但是,如果结果存在,则数据库会从高速缓存中检索结果,而不是执行查询。

每当事务处理修改用于构建结果的数据库对象的数据或元数据时,数据库都会自动使缓存的结果失效。下一个查询无法使用缓存的结果,因此数据库会自动计算新结果,然后缓存该结果以供后续查询使用。高速缓存刷新过程对应用程序是透明的。

实际上,查询结果高速缓存充当数据库根据需要创建和维护的“即时”实体化视图。通过高速缓存,数据库可以避免昂贵的重新读取数据块和重新计算结果操作。大多数应用程序都受益于这种性能改进。

另请参阅:Oracle AI Database Administrator’s Guide,了解如何使用查询结果高速缓存优化响应时间

PL/SQL 函数结果高速缓存

PL/SQL 函数结果高速缓存是服务器结果高速缓存的子集,用于存储函数结果集。

如果不进行高速缓存,每次调用 1 秒时 1000 次 PL/SQL 函数调用将需要 1000 秒。通过高速缓存,具有相同输入的 1000 个函数调用可能需要 1 秒的 total 。结果高速缓存的良好候选对象是经常调用依赖于相对静态数据的函数。

PL/SQL 函数代码可以包括高速缓存其结果的请求。调用此函数时,系统会检查高速缓存。如果高速缓存包含以前函数调用中具有相同参数值的结果,则系统会将结果返回给调用者,并且不会重新执行函数主体。如果高速缓存不包含结果,则系统将执行函数主体并将结果(对于这些参数值)添加到高速缓存中,然后再将控制权返回给调用者。

注:您可以指定用于计算缓存结果的数据库对象,以便更新其中的任何结果时,缓存结果将变为无效并且必须重新计算。

经常使用不同参数调用的函数可能会生成很少重复使用的结果,从而导致性能下降。Oracle AI Database 跟踪最近使用的具有 RESULT_CACHE 提示的 PL/SQL 函数。使用此历史记录,数据库仅缓存 PL/SQL 函数和参数对(如果在最近的历史记录中看到 x 次),其中 x 由内部阈值设置 )。如果由于缓存的结果过多而导致数据库需要更多内存,则一个或多个缓存的结果会过期。

RESULT_CACHE_EXECUTION_THRESHOLD 指定函数和一组特定参数在高速缓存之前必须查看的次数。请注意,如果函数具有不同的参数(例如 MYFUNC(1,2) 和 MYFUNC(1,3)),则认为函数是唯一的。只能在系统级别而非会话级别设置此参数。

另请参见:

服务器结果缓存基础结构

查询结果高速缓存和 PL/SQL 函数结果高速缓存共享相同的基础结构。

对象类型:结果、相关性和临时

在服务器结果高速缓存中,结果对象是一种数据结构,用于存储查询或 PL/SQL 函数返回的行。相关性对象存储作为结果对象存储的查询所引用的对象的元数据。

典型的查询结果很小,计算成本很高,经常重复使用,并且基于非易失性表。但是,结果有时可能很大。如果查询结果通过了大小限制,则数据库会将结果的一部分存储为临时对象,将部分结果存储为标准结果对象。临时对象是结果高速缓存元数据的集合,指向保存实际查询结果的临时表空间段。

结果子缓存

根据工作量,数据库可能会创建结果子高速缓存,以便在读/写访问期间支持更高的并发性。Oracle AI Database 使用内部算法来决定是否创建子高速缓存,如果创建,则决定创建多少子高速缓存。

服务器结果高速缓存用户界面

RESULT_CACHE_MODE 初始化参数确定是将 SQL 查询结果高速缓存用于所有可能的查询,还是仅用于提示的查询。

RESULT_CACHE_MAX_TEMP_SIZE 初始化参数控制结果高速缓存可以在 PDB 中消耗的最大临时表空间内存量。RESULT_CACHE_MAX_TEMP_RESULT 控制一个缓存的查询可以消耗的最大临时表空间内存量。

要覆盖 RESULT_CACHE_MODE 参数设置,可以使用 RESULT_CACHE hint 为查询或查询片段添加注释。从 Oracle Database 21c 开始,提示接受选项 TEMP={TRUE|FALSE},该选项控制结果是否可以存储在临时表空间中。

使用 DBMS_RESULT_CACHE 程序包可以管理由 SQL 结果高速缓存和 PL/SQL 函数结果高速缓存使用的共享池的该部分。您可以使对象、阻止列表查询和对象失效,并执行相关操作。

V$RESULT_CACHE_OBJECTS.TYPE 列指示高速缓存中的对象类型。如果查询结果存储在临时表空间中,则 TYPE 显示两个对象:Result 和 Temp。可以使用 V$RESULT_SUBCACHE_STATISTICS 和相关视图访问子高速缓存元数据。

另请参见:

保留池

保留池是共享池中的内存区域,Oracle AI Database 可使用该区域分配大型连续内存块。

数据库以块形式从共享池分配内存。通过分块,可以将大型对象(超过 5 KB)加载到高速缓存中,而无需单个连续区域。通过这种方式,数据库减少了由于碎片化而耗尽连续内存的可能性。

不经常,Java、PL/SQL 或 SQL 游标可能会从大于 5 KB 的共享池中进行分配。为了最有效地执行这些分配,数据库将保留池的少量共享池隔离起来。

另请参阅:Oracle AI Database Performance Tuning Guide,了解如何配置保留池

大型池

大型池是可选的内存区域,用于大于适用于共享池的内存分配。

大型池可以为以下项提供大内存分配:

下图描述了大型池。

图 7:大型池

插图 cncpt221.png 的说明

另请参见:

大型池内存管理

大型池对内存的管理方式与共享池不同,共享池使用 LRU 列表,以便部分内存会耗尽。

大池没有 LRU 列表。当数据库向数据库会话分配大池内存时,除非会话释放该内存,否则该内存不符合释放条件。一旦释放了部分内存,其他进程就可以使用它。通过从大型池分配会话内存,数据库可避免共享池中可能发生的碎片。

延迟插入 s 的大型池缓冲区

对于称为延迟插入的特殊插入类型,数据库将从大型池分配缓冲区。

为了快速从 Internet of Things (IoT) 应用程序中“触发并忘记”插入,数据库基础结构会产生性能开销。例如,代码路径包括缓冲区高速缓存导航、缓冲区引脚和并发保护。数组插入可最大限度地降低这些成本,但数组必须构建在客户端上,这对于 Internet of Things 应用程序来说并不典型。要解决此问题,Oracle 应用程序可以使用提示将行插入指定为 MEMOPTIMIZE FOR WRITE 的表中。

插入被延迟,因为它们被缓冲在大型池中,然后由后台进程异步写入磁盘。数据库按如下方式处理延迟插入:

  1. 应用程序将 MEMOPTIMIZE_WRITE 插入发送到中间层,中间层可以聚合数据。虽然 IoT 应用程序几乎总是向中间层发送插入,但也可以直接向数据库发送插入。例如,使用 SQL*Plus 会将插入直接发送到数据库。

  2. 中间层将插入的聚合写入数据库服务器。

  3. (可选)中间层客户机保留在上一步中写入的数据的本地副本。

  4. 服务器进程将数据写入大型池中的缓冲区或缓冲区。

    为了避免争用,每个缓冲区都有自己的内部锁定机制。此锁定机制与数据库缓冲区高速缓存对其缓冲区使用的锁定机制不同。基本写入过程如下所示:

    1. 实例启动后,第一个 MEMOPTIMIZE_WRITE 插入将从大型池分配缓冲区。

    2. 写入器从可用缓冲区列表中选择一个缓冲区。

    3. 如果所选缓冲区未锁定,并且此缓冲区具有空闲空间,则客户机将写入缓冲区,并使用特定于会话的序列号标记每个缓冲区写入。如果不是,则写入器返回到前面的步骤,然后以这种方式继续,直到找到缓冲区或在大型池中释放了足够的空间。

  5. 数据库根据缓冲数据创建服务器端阵列。

  6. 空间管理协调员 (Space Management Coordinator,SMCO) 及其辅助进程 (W nnn ) 使用标准数据块格式异步将阵列写入磁盘。

    与标准插入不同,延迟插入将自动提交,并且无法回退。数据库按插入在会话中的显示顺序将插入提交到给定对象。无法保证在对象或会话之间订购。

    数据库支持约束条件和索引维护,就像常规插入一样。但是,数据库在写入磁盘期间执行评估,而不是写入大型池。

    注:为了获得最佳性能,Oracle 建议禁用约束条件。

下图描述了延迟插入的工作流。

图 8:延迟 InsertMechanism

插图 cncpt_pb_002a.png 的说明

另请参见:

Java 池

Java 池是存储 Java Virtual Machine (JVM) 中所有特定于会话的 Java 代码和数据的内存区域。此内存包括在调用结束时迁移到 Java 会话空间的 Java 对象。

对于专用服务器连接,Java 池包括每个 Java 类的共享部分,包括方法和只读内存(例如代码向量),但不包括每个会话的每会话 Java 状态。对于共享服务器,池包括每个类的共享部分以及用于每个会话状态的某些 UGA。每个 UGA 都会根据需要增大和缩小,但总 UGA 大小必须适合 Java 池空间。

Java 池指导统计信息提供有关用于 Java 的库高速缓存内存的信息,并预测 Java 池大小的更改如何影响语法分析速率。当 statistics_level 设置为 TYPICAL 或更高版本时,Java 池指导在内部处于打开状态。关闭指导时,这些统计信息将重置。

另请参见:

固定 SGA

固定 SGA 是内部客房服务区域。

例如,固定 SGA 包含:

固定 SGA 的大小由 Oracle AI Database 设置,无法手动更改。固定 SGA 大小可以从发行版更改为发行版。

另请参见:“ Automatic Locks 概述”

可选与性能相关的 SGA 子区域

某些 SGA 子区域仅为特定性能功能启用。

本部分涵盖以下主题:

内存中区域

内存中区域是包含内存中列存储(IM 列存储)的可选 SGA 组件。

IM 列存储包含针对快速扫描而优化的列格式表、分区和实体化视图的副本。IM 列存储补充了数据库缓冲区高速缓存,该高速缓存以传统行格式存储数据。

注:要启用 IM 列存储,必须具有 Oracle AI Database In-Memory 选项。

另请参阅:Oracle AI Database In-Memory Guide 以了解有关内存区域和 IM 列存储的更多信息

内存优化池

memoptimize pool 为指定为 MEMOPTIMIZE FOR READ 的按堆组织的表存储缓冲区和相关结构。

此结构可为基于键的查询(例如 SELECT * FROM cust WHERE cid = 10)提供高性能和可扩展性。为了缩短端到端响应时间,客户机通过网络直接从 SGA 提取请求的缓冲区,从而避免 CPU 和操作系统开销。应用可以从内存优化池中受益,而无需更改代码。

memoptimize 池包含两个部分:

插图 cncpt_pb_001a.png 的说明

要启用 memoptimize 池,请将 MEMOPTIMIZE_POOL_SIZE 初始化参数设置为整数值(池默认处于禁用状态)。该值指定要分配给池的 SGA 量。MEMOPTIMIZE_POOL_SIZE 值会计入 SGA_TARGET,但数据库不会自动增大和收缩内存优化池。例如,如果 SGA_TARGET 为 10 GB,并且 MEMOPTIMIZE_POOL_SIZE 为 1 GB,则除了 memoptimize 池之外,总共 9 GB 可用于 SGA 内存。

要更改 memoptimize 池的大小,必须手动设置 MEMOPTIMIZE_POOL_SIZE 并重新启动数据库实例。无法使用 ALTER SYSTEM 动态更改池大小。

使用 DBMS_MEMOPTIMIZE 软件包可以将表显式填充到 memoptimize 池中。

另请参见:

程序全局区 (Program Global Area,PGA) 概述

PGA 是特定于操作进程或线程的内存,系统上的其他进程或线程不共享该内存。由于 PGA 是特定于进程的,因此决不会在 SGA 中分配 PGA。

PGA 是包含专用或共享服务器进程所需的会话相关变量的内存堆。服务器进程分配 PGA 中所需的内存结构。

PGA 的类比是文件职员使用的临时桌面工作区。在此类比中,文件职员是代表客户(客户机进程)进行工作的服务器进程。职员将清除台式机的一部分,使用工作区存储有关客户请求的详细信息,并对客户请求的文件夹进行排序,然后在完成工作时放弃空间。

下图显示了未为共享服务器配置的实例的实例 PGA(所有 PGA 的集合)。可以使用初始化参数设置实例 PGA 的目标最大大小。各个 PGA 可以根据需要增长到此目标大小。

图 10:实例 PGA

插图 cncpt218.gif 的说明

注:后台流程还分配自己的 PGA。本讨论仅侧重于服务器进程 PGA。

PGA 的内容

PGA 被细分为不同的区域,每个区域具有不同的用途。

下图显示了专用服务器会话的 PGA 的可能内容。并非所有 PGA 区域都会在每种情况下都存在。

图 11:PGA 内容

插图 cncpt219.gif 的说明

专用 SQL 区

专用 SQL 区域保存有关已语法分析的 SQL 语句的信息以及其他特定于会话的信息以进行处理。

当服务器进程执行 SQL 或 PL/SQL 代码时,该进程将使用专用 SQL 区域来存储绑定变量值、查询执行状态信息和查询执行工作区。

不要将 PGA 中的 private SQL 区域与 shared SQL 区域(用于将执行计划存储在 SGA 中)混淆。相同或不同会话中的多个专用 SQL 区域可以指向 SGA 中的单个执行计划。例如,一个会话中有 20 次执行 SELECT * FROM sales,另一个会话中有 10 次执行同一查询可以共享同一计划。每个执行的专用 SQL 区域不共享,并且可能包含不同的值和数据。

cursor 是特定专用 SQL 区域的名称或句柄。如下图中所示,您可以将光标视为客户机端的指针,并将其视为服务器端的状态。由于游标与专用 SQL 区域密切相关,因此这些术语有时可以互换使用。

图 12:光标

插图 cncpt324.gif 的说明

专用 SQL 区域分为以下几个区域:

客户机进程负责管理专用 SQL 区域。专用 SQL 区域的分配和取消分配在很大程度上取决于应用程序,尽管客户机进程可以分配的专用 SQL 区域的数量受初始化参数 OPEN_CURSORS 的限制。

虽然大多数用户依赖数据库实用程序的自动游标处理,但 Oracle AI Database 编程接口可帮助开发人员更好地控制游标。通常,应用程序应关闭所有不会再次使用的打开游标,以释放持久性区域并最大限度地减少应用程序用户所需的内存。

另请参见:

SQL 工作区

工作区是用于内存密集型操作的 PGA 内存的专用分配。

例如,排序运算符使用排序区域对一组行进行排序。同样,散列联接运算符使用散列区域从其左侧输入构建散列表,而位图合并使用位图合并区域来合并从多个位图索引的扫描中检索的数据。

以下示例显示了 employees 和 departments 的联接及其查询计划:

SQL> SELECT *
  2  FROM   employees e JOIN departments d
  3  ON     e.department_id=d.department_id
  4  ORDER BY last_name;
.
.
.
--------------------------------------------------------------------------------
| Id| Operation           | Name        | Rows  | Bytes | Cost (%CPU)| Time    |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT    |             |   106 |  9328 |    7  (29)| 00:00:01 |
| 1 |  SORT ORDER BY      |             |   106 |  9328 |    7  (29)| 00:00:01 |
|*2 |   HASH JOIN         |             |   106 |  9328 |    6  (17)| 00:00:01 |
| 3 |    TABLE ACCESS FULL| DEPARTMENTS |    27 |   540 |    2   (0)| 00:00:01 |
| 4 |    TABLE ACCESS FULL| EMPLOYEES   |   107 |  7276 |    3   (0)| 00:00:01 |
--------------------------------------------------------------------------------

在前面的示例中,运行时区域跟踪全表扫描的进度。会话在散列区域中执行散列联接,以匹配两个表中的行。ORDER BY 排序出现在排序区域中。

如果运算符要处理的数据量不适合工作区,则 Oracle AI Database 会将输入数据分成较小的部分。通过这种方式,数据库处理内存中的某些数据片段,同时将其余数据片段写入临时磁盘存储以供以后处理。

启用自动 PGA 内存管理时,数据库会自动优化工作区大小。您还可以手动控制和调整工作区的大小。

通常,较大的工作区可以显著提高操作员的性能,但代价是内存占用更多。理想情况下,工作区的大小足以容纳由其关联的 SQL 运算符分配的输入数据和辅助内存结构。否则,响应时间会增加,因为部分输入数据必须缓存到磁盘上。在极端情况下,如果工作区的大小与输入数据大小相比太小,则数据库必须对数据片段执行多次传递,从而显著增加响应时间。

另请参见:

专用和共享服务器模式中的 PGA 使用情况

PGA 内存分配取决于数据库是使用专用服务器连接还是共享服务器连接。

下表显示了差异。

表 1 专用服务器和共享服务器之间的内存分配差异

内存区域 专用服务器 共享服务器
会话内存的性质 专用 共享
持久性区域的位置 PGA SGA
DML 和 DDL 语句的运行时区域的位置 PGA PGA

另请参阅:Oracle AI Database Administrator’s Guide,了解如何为共享服务器配置数据库

用户全局区概览

UGA 是会话内存,这是为会话变量分配的内存,例如登录信息以及数据库会话所需的其他信息。基本上,UGA 存储会话状态。

下图描述了 UGA。

图 13:用户全局区 (User Global Area,UGA)

插图 cncpt222.gif 的说明

如果会话将 PL/SQL 程序包加载到内存中,则 UGA 包含程序包状态,这是一组在特定时间存储在所有程序包变量中的值。程序包子程序更改变量时,程序包状态会发生变化。缺省情况下,软件包变量在会话的生命周期中是唯一的且持久的。

OLAP 页面池也存储在 UGA 中。此池管理 OLAP 数据页,这些页等效于数据块。页面池在 OLAP 会话开始时分配,并在会话结束时释放。每当用户查询维对象(如多维数据集)时,OLAP 会话都会自动打开。

在会话生命周期内,UGA 必须可供数据库会话使用。因此,在使用共享服务器连接时,UGA 无法存储在 PGA 中,因为 PGA 特定于单个进程。因此,使用共享服务器连接时,UGA 将存储在 MGA 中,从而允许任何共享服务器进程访问它。使用专用服务器连接时,UGA 存储在 PGA 中。

另请参见:

托管全局区 (Managed Global Area,MGA) 概述

托管全局区 (Managed Global Area,MGA) 是一个独特的内存框架,它能够在一组可信的 Oracle 进程中共享和协调内存。

它具有可配置、弹性、模块化、按需和可恢复的共享内存区域。MGA 提供了一种在数据库中利用不同类型的共享内存区域的方法。它作为内部数据库层的名称空间公开,每个层仅属于其中一个。名称空间主要由一组共享内存段和随之而来的元数据组成。

数据库中的层可以定义名称空间的特征、作用域、生命周期和内部段大小。所有 MGA 都计入 PGA 聚合限制下。

在 Linux 上,MGA 要求 tempfs 挂载在 /dev/shm 上,并且至少配置为 PGA 聚合限制的大小。在同一台计算机上运行多个实例时,所有实例的 /dev/shm 大小必须至少为 sum(PGA_AGGREGATE_LIMIT) 。

另请参见:

软件代码区域概览

软件代码区域是存储正在运行或可以运行的代码的内存的一部分。Oracle AI Database 代码存储在通常比用户程序位置更独占和保护的软件区域中。

软件区域的大小通常是静态的,仅在更新或重新安装软件时才会更改。这些领域所需的大小因操作系统而异。

软件区域是只读的,可以安装共享区域或非共享区域。某些数据库工具和实用程序(例如 Oracle Forms 和 SQL*Plus)可以安装为共享工具,但有些工具和实用程序无法安装。尽可能共享数据库代码,以便所有用户都可以在内存中没有多个副本的情况下访问它,从而减少主内存并提高整体性能。如果同一台计算机上运行,则一个数据库的多个实例可以将同一数据库代码区与不同的数据库一起使用。注:共享软件的安装选项不适用于所有操作系统,例如,在运行 Microsoft Windows 的 PC 上。有关更多信息,请参见特定于操作系统的文档。