In-Memory Column Store的优势

In-Memory Column Store 具有三个明显的优势:

  • 查询运行得更快:所有数据都可以以压缩的列格式填充到内存中。不需要和使用索引。由于采用列式压缩格式,查询的运行速度至少比从缓冲区缓存中获取数据快 100 倍。
  • DML 更快:分析索引可以被替换为表的 IM 列存储表示的扫描。
  • 任意即席查询以良好的性能运行,因为表的行为就像所有列都被索引

数据库如何从 FastStart 区读取

FastStart 区域定义了重新打开数据库时加载的数据,但不定义加载时加载的数据。
人口由优先级设置控制。
当数据库重新打开时,标准的 PRIORITY 规则确定人口。
例如,数据库按需填充具有 PRIORITY NONE 的对象。
优先级为 CRITICAL 的对象在自动填充队列中的位置高于优先级为 LOW 的对象。

例如,在单实例数据库中,销售、客户和产品表在 IM 列存储中使用 PRIORITY NONE 填充。
每次重新填充时,数据库都会将这些表的 IMCU 保存到 FastStart 区域。
假设实例意外终止。
重新打开数据库时,IM 列存储为空。
如果查询扫描 sales、customers 或者 product 表,则数据库会将此表的 IMCU 从 FastStart 区域加载到 IM 列存储中。

大多数情况下,FastStart 区域会增加填充速度。
但是,如果存储在 FastStart 区域中的任何 CU 达到 DML 活动的内部阈值,则数据库将从数据文件而不是从 FastStart 区域填充行数据。

内存中快速启动

每当数据库实例重新启动时,就会填充 IM 列存储,这可能是 I/O 密集型和 CPU 密集型的缓慢操作。
In-Memory FastStart 通过将 In-Memory 压缩单元直接存储在磁盘上来优化 In-Memory 列存储中数据库对象的数量。

启用 IM FastStart 后,数据库会定期将列状数据的副本保存到磁盘,以便在实例重新启动期间更快地重新填充。
如果数据库在关闭后重新打开,那么数据库会从 FastStart 区域读取列数据,然后将其填充到 IM 列存储中,确保所有事务的一致性得到维护。

IM FastStart 表空间需要在数据库打开和运行时间歇性 I/O。
当数据库重新打开时会出现性能提升,因为数据库避免了 CPU 密集型的数据压缩和格式化。

概括

  • Oracle Database 12.2 中引入了对 In-Memory 列存储的 FastStart 增强。
  • 每当数据库实例重新启动时,就会填充 In-Memory 列存储。这可能是 I/O 和 CPU 密集型的缓慢操作。
  • IM FastStart 通过将 IM 压缩单元 (IMCU) 直接存储在磁盘上来优化 IM 列存储中的对象填充。这会导致在实例重新启动期间更快地重新填充
  • 如果数据库在关闭后重新打开,则数据库从 FastStart 区域读取列数据。然后将其填充到 IM 列存储中,确保维护所有事务一致性。

启用内存中快速启动

FastStart 区域是一个指定的表空间,IM FastStart 其中存储和管理 INMEMORY 对象的数据。
Oracle 数据库无需 DBA 干预即可管理 FastStart 表空间。
每个 PDB 或者非 CDB 只允许一个 FastStart 区域和一个指定的 FastStart 表空间。
当表空间是指定的 IM FastStart 表空间时,我们不能更改或者删除该表空间。
在 Oracle RAC 数据库中,所有节点共享 FastStart 数据。

DBMS_INMEMORY_ADMIN 包提供了启用和禁用 IM FastStart 以及将 IM FastStart 迁移到另一个表空间的过程,以及检索当前指定为 IM FastStart 区域的表空间名称的函数。
使用 DBMS_INMEMORY_ADMIN.FASTSTART_ENABLE 过程启用 FastStart 表空间。

SQL> exec DBMS_INMEMORY_ADMIN.ENABLE_FASTSTART ('fs_tbs')

空间管理工作进程 (Wnnn) 创建一个名为 SYSDBinstance_name_LOBSEG$ 的空 SecureFiles LOB

欢迎来到之路教程(on itroad-com)

内存列存储和 Oracle RAC

Oracle RAC 环境中的每个节点都有自己的内存中 (IM) 列存储。
Oracle 建议我们对每个 Oracle RAC 节点上的 IM 列存储设置相同的大小。
对于不需要 IM 列存储的任何 Oracle RAC 节点,请将 INMEMORY_SIZE 参数设置为 0。

可以在每个节点上填充完全不同的对象,或者将更大的对象分布在集群中的所有 IM 列存储中。
也可以在每个节点的 IM 列存储中出现相同的对象(仅在工程系统上)。
对象在集群中跨 IM 列存储的分布由 INMEMORY 属性的两个添加子条款控制;分发和复制。

DISTRIBUTE 子句可用于指定对象在集群中的分布方式。
默认情况下(DISTRIBUTE AUTO),使用的分区类型(如果有)决定了对象的分布方式。
如果对象未分区,则按 rowid 范围分布。

或者,我们可以指定 DISTRIBUTE BY 子句来覆盖默认行为。
DISTRIBUTE 子句支持 BY ROWID、BY PARTITION、BY SUBPARTITION 和 FOR SERVICE:

SQL> ALTER TABLE lineorder INMEMORY DISTRIBUTE BY PARTITION;
SQL> ALTER TABLE sales INMEMORY DISTRIBUTE FOR SERVICE sales_ebiz;

DUPLICATE 子句用于控制如何跨集群中的 IM 列存储复制对象。
如果我们仅指定 DUPLICATE,则数据的一个镜像副本将分布在集群中的 IM 列存储中。
如果要复制集群中每个 IM 列存储中的整个对象,请指定 DUPLICATE ALL。

内存列存储

内存中 (IM- In-Memory ) 列存储是 Oracle 数据库 12.1 版补丁集 1 中引入的 SGA 中的新池。
填充到 IM 列存储中的段被转换为列格式。
In-Memory 段在事务上与缓冲区缓存一致。

In-Memory Column Store 使对象(表、分区和其他类型)能够以称为列格式的新格式存储在内存中。
这种格式使扫描、连接和聚合的执行速度比传统的磁盘格式快得多,为 OLTP 和 DW 环境提供快速报告和 DML 性能。

内存中的列格式不会取代磁盘或者缓冲区缓存格式。
这意味着当诸如表或者分区之类的段被填充到 IM 列存储中时,磁盘格式段会自动转换为列格式并可选择进行压缩。
列格式是一种纯内存格式。
磁盘上没有列格式存储。
它永远不会导致另外的磁盘写入,因此不需要任何日志记录或者撤消空间。

所有数据都以传统的行格式存储在磁盘上。
此外,段的列格式是该段在磁盘或者缓冲区缓存中的事务一致性副本。
维护两个池之间的事务一致性。

如果在 SGA 中为 IM 列存储分配了足够的空间,则访问填充到 IM 列存储中的对象的查询的执行速度会快得多。
改进的性能允许直接在实时交易数据上执行更多的临时分析查询,而不会影响现有的工作负载。
缺少 IM 列存储空间不会阻止对可能已填充到 IM 列存储中的表执行语句。

DBA 必须根据对段执行的查询和 DML 的类型决定哪些段应定义为非内存段,哪些段应定义为内存段。
DBA 还可以更精确地定义哪些列适合 IM 列存储:

  • 仅以行格式:OLTP 样式查询经常访问的段,对返回许多列的少数行进行操作是缓冲区缓存的良好候选者。这些段不一定要定义为内存中的段,而只会发送到缓冲区缓存。
  • 同时采用双格式:分析式查询经常访问的段,对返回很少列的多行进行操作是 IM 列存储的良好候选者。如果一个段被定义为内存段但有一些列被定义为非内存列,那么选择任何非内存列的查询将被发送到缓冲区缓存,而那些只选择内存列的查询将被发送到IM 列存储。任何 fetch-by-rowid 都是通过缓冲区缓存在段上执行的。

对这些对象执行的任何 DML 都通过缓冲区缓存执行。

内存中的 FastStart 架构

在启用 FastStart 区域后的第一次填充期间,数据库会创建 FastStart 区域。
数据库自动管理FastStart区域如下:

  • 每当发生对象的填充或者重新填充时,数据库将其列数据写入 FastStart 区域。空间管理工作进程 (Wnnn) 将 IMCU 写入名为 SYSDBinstance_name_LOBSEG$ 的 SecureFiles LOB。数据库将 FastStart 元数据写入 SYSAUX 表空间,该表空间必须在线。根据 CU 发生的 DML 活动的数量,FastStart 区域中的 CU 与 IM 列存储中的 CU 之间可能存在滞后。 CU 越“热”,数据库将其填充到 IM 列存储并将其写入 FastStart 区域的频率就越低。如果数据库崩溃,则在 IM 列存储中填充的某些 CU 可能不存在于 FastStart 区域中。
  • 如果填充对象的属性更改为 NOINMEMORY,则数据库会自动从 FastStart 区域中删除其 IMCU。
  • 如果 FastStart 表空间空间不足,则数据库使用内部算法删除最旧的段,并继续写入 FastStart 区域。如果没有剩余空间,则数据库停止写入 FastStart 区域。

上图显示了在 IM 列存储中填充的 PROD、CUST 和 SALES。
启用FastStart 区域时,数据库还将这些段的IMCU 写入fs_tbs 中的FastStart 区域。
如果数据库重新打开或者实例重新启动,则数据库可以验证 IMCU 的修改以确保事务一致性,并重用 IMCU。
无论是否启用FastStart 区域,数据库都会在users 表空间的磁盘上存储数据块和段。

内存列存储人口

并非 Oracle 数据库中的所有对象都需要填充到 IM 列存储中。
IM 列存储应填充数据库中对性能最关键的数据。
对性能要求较低的数据可以驻留在成本较低的闪存或者磁盘上。
当然,如果数据库足够小,我们可以将所有表填充到 IM 列存储中。
In-Memory 为表和物化视图添加了新的 INMEMORY 属性。
只有具有 INMEMORY 属性的对象才会填充到 IM 列存储中。
INMEMORY 属性可以在表空间、表、(子)分区或者物化视图上指定。
如果在表空间级别启用它,则默认情况下将为 IM 列存储启用表空间中的所有新表和物化视图。

默认情况下,具有 INMEMORY 属性的对象中的所有列都将填充到 IM 列存储中。
但是,如果需要,可以使用 NO INMEMORY 子句仅填充列的子集。
此子句还可用于指示对象不再是候选对象并将其从 IM 存储中删除:

ALTER TABLE sales MODIFY PARTITION SALES_Q2_2008 NO INMEMORY;

概括

只有具有 INMEMORY 属性的对象才有资格进行填充。
INMEMORY 属性可以在表空间、表、分区或者物化视图上指定。

SQL> ALTER TABLE sales INMEMORY

具有 INMEMORY 属性的对象中的所有列都将填充到 IM 列存储中。
要排除特定列:

SQL> ALTER TABLE sales INMEMORY NO INMEMORY(prod_id);

如果在表空间级别启用,则默认启用表空间中的新物化视图和表:

SQL> ALTER TABLESPACE ts_data DEFAULT INMEMORY;

实现内存列存储

在将表或者物化视图填充到 IM 列存储之前,我们必须为数据库启用 IM 列存储。
在此之前,我们必须确保数据库已打开并且 COMPATIBLE 初始化参数设置为 12.1.0 或者更高版本。
要启用 In-Memory 列存储:

  1. 在 SQL*Plus 或者 SQL Developer 中,使用管理权限登录数据库。

  2. 将 INMEMORY_SIZE 初始化参数设置为非零值。
    最小设置为 100M。
    当我们使用 ALTER SYSTEM 语句在服务器参数文件 (SPFILE) 中设置此初始化参数时,我们必须指定 SCOPE=SPFILE。

SQL> ALTER SYSTEM SET INMEMORY_SIZE = 1G SCOPE=SPFILE;
  1. 关闭数据库,然后重新打开它以在 SGA 中初始化 IM 列存储。

  2. 查看当前为 IM 列存储分配的内存量:

SQL> SHOW PARAMETER INMEMORY_SIZE
NAME                                  TYPE        VALUE
----------------------------------- -----------   ----
inmemory_size                        big integer   1G

如果兼容级别为 12.2 或者更高,则可以使用 SQL ALTER SYSTEM SET INMEMORY_SIZE 命令动态增加 IM 列存储。
例如:

SQL> ALTER SYSTEM SET INMEMORY_SIZE = 2G SCOPE=BOTH;

请注意,IM 列存储的大小不能动态减小。
如果我们希望这样做,我们必须发出 ALTER SYSTEM SET INMEMORY_SIZE...SCOPE=SPFILE 命令,然后重新启动数据库。

Oracle RAC 中的 FastStart 区

FastStart 区域在所有 Oracle RAC 节点之间共享。
此功能可实现跨集群的最大共享和可重用性。
FastStart 区域中只有一个 IMCU 副本。
例如,如果为四节点集群中的对象指定了 DUPLICATE ALL,则 IM 列存储中存在该对象的四个副本。
但是,数据库仅将一份副本保存到 FastStart 区域。

Oracle RAC 集群中的任何数据库实例都可以使用 FastStart 区域中的 IMCU。
该特性提高了 Oracle RAC 环境中实例重启的性能。
例如,sales 表可能有三个分区:sales_2014. sales_2015 和 sales_2016,每个分区都填充在不同的实例中。

发生实例故障,其中一个实例无法重启。
如果 IM 列存储中有足够的空间可用,则幸存的实例可以读取先前填充在无法访问的实例中的 IMCU。
因此,所有三个销售表分区都可用于应用程序。

RAC 中的 Oracle Database In-Memory

内存中的优先级

填充对象的顺序由关键字 PRIORITY 控制,它有五个级别。

优先级描述
CRITICAL打开数据库后立即填充对象
HIGH如果 IM 列存储中仍有可用空间,则在填充所有 CRITICAL 对象后填充对象
MEDIUM在填充所有 CRITICAL 和 HIGH 对象后填充对象,并且 IM 列存储中的空间仍然可用
LOW如果 IM 列存储中仍有可用空间,则在填充所有 CRITICAL、HIGH 和 MEDIUM 对象后填充对象
NONE如果 IM 列存储中有可用空间,则仅在第一次扫描对象后填充对象(默认)

我们可以指定数据库在数据库实例启动时或者访问 INMEMORY 对象时填充 IM 列存储中的对象。
填充算法还取决于我们使用的是单实例还是 Oracle RAC。

DDL 语句包括一个 INMEMORY PRIORITY 子句,它提供对填充队列的更多控制。

对象在数据库打开后或者第一次扫描(查询)后立即以优先列表的形式填充到 IM 列存储中。
填充对象的顺序由关键字 PRIORITY 控制,它有五个级别(见上文)。
默认优先级为 NONE,这意味着仅在第一次扫描对象后才填充对象。
必须先填充给定优先级的所有对象,然后才能开始填充任何较低优先级的对象。
但是,如果扫描没有 PRIORITY 的对象,则可以取代填充顺序,触发其填充到 IM 列存储中。

内存列存储池

In-Memory 区域细分为两个池:一个 1MB 池,用于存储填充到内存中的实际列格式数据,以及一个 64K 池,用于存储有关填充到 IM 列存储中的对象的元数据。
每个池中的可用内存量在 V$INMEMORY_AREA 视图中可见。
两个池的相对大小由内部启发式决定;大部分 In-Memory 区域内存分配给 1MB 池。

sql> select pool, alloc_bytes,   used_bytes,   population_status from V$INMEMORY_AREA;
POOL          ALLOC_BYTES    USED_BYTES   POLULATE STATUS
----------   -----------     ----------   --------------
1MB POOL      1710227456      16777216       DONE
64 KB POOL     419430400       1900544       DONE

SGA 中 In-Memory 区域的大小由初始化参数 INMEMORY_SIZE(默认为 0)控制。
In-Memory 区域的最小大小必须为 100MB。
In-Memory 区域的当前大小在 V$SGA 中可见。
从 12.2 开始,假设 SGA 中有空闲内存,可以通过 ALTER SYSTEM 命令增加 INMEMORY_SIZE 参数来动态增加 In-Memory 区域的大小。
INMEMORY_SIZE 参数必须增加 128MB 或者更多才能使此更改生效。
无法即时缩小内存中区域的大小。
在重新启动数据库实例之前,减小 INMEMORY_SIZE 参数的大小不会生效。
请务必注意,内存中区域不受 Oracle 自动内存管理 (AMM) 的影响或者控制。

日期:2020-09-17 00:11:31 来源:oir作者:oir