12c in memory-1

以前在乙方做服务的时候,公司会要求每个季度写一篇文章来记录一下学习的过程,之前也不一直没有去写博客,所以本文是对之前写的文章的复制和整理。本文整理自oracle 12c in memory的白皮书以及自己的一个实验测试。

概述

Oracle 12c的新特性In-Memory在12.1.0.2版本中出现了,这个特性既可以优化分析系统也可以提升混合workload的OLTP系统。
Oracle 12c的in-memory提供了一种独一无二的双重格式架构,既可以将表的数据在内存里以传统的行模式的方式展现,也可以用新特性的in-memory列格式展示。Oracle的优化器可以自动的将分析查询转变成列模式,将传统的OLTP查询转换成行模式。数据库自动维护行模式和列模式的事务的连续性,就像维护表和索引一样。列模式是完全IN-MEMORY的,不是固有的存放在磁盘上,所以不会存在额外的存储开销和存储同步的问题。

Real-Time Performance

Oracle In-Memory特性对in-memory扫描 、join和聚合使用了state-of-the-art算法。这些改进使oracle数据库可以使查询惊人的快。

Mixed Workload OLTP

Mixed workload数据库除了传统的OLTP事务,还运行报表和ad hoc查询。为了加速报表查询对比较重要的表上创建很多索引是很常见的。In-Memory列格式消除了这种需要对每列都建索引的情况的发生。分析类的索引的去除加速了OLTP的操作,因为分析类的索引不再需要被每一个事务维护了。

Unlimited Scale

In-Memory不需要把所有的数据都装进内存,用户可以选择对性能要求比较敏感的表来装载。

Trivial to Adopt

开启In-Memory跟设置in-memory列存储和将表加载进内存一样简单。在数据库开启并且方可以访问的时候,后台进程将数据加载进in-memory列。

In-Memory简介

In-Memory区域是在SGA中的一个静态池,它的大小由初始化参数INMEMORY_SIZE控制,
the inmemory area is defined as a sub-heap of the top level SGA heap;
Inmemory area size is allocated as sub-heaps very similar to the shared pool sub-heaps.
这个参数的默认值是0.

[oracle@oel12c1 ~]$ sqlplus "/as sysdba"
SQL*Plus: Release 12.1.0.2.0 Production on Thu Aug 28 21:25:20 2014
Copyright (c) 1982, 2014, Oracle.  All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options

show parameter INMEMORY_SIZE
NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------
inmemory_size                        big integer 0
INMEMORY_SIZE的当前大小是可以在v$SGA视图中可见的。对INMEMORY_SIZE参数的修改都需要重启数据库,并且不会受AMM的影响或控制。In-Memory区最小要设置为100M。

In-Memory区被分成2个池:

a 1MB pool used to store the actual column formatted data populated into memory;
and a 64K pool used to store metadata about the objects that are populated into the IM column store.

startup
ORACLE instance started.
Total System Global Area  947912704 bytes
Fixed Size                  2931184 bytes
Variable Size             402654736 bytes
Database Buffers          327155712 bytes
Redo Buffers                5455872 bytes
In-Memory Area            209715200 bytes

select * from v$inmemory_area;
POOL                       ALLOC_BYTES USED_BYTES POPULATE_STATUS                CON_ID
-------------------------- ----------- ---------- -------------------------- ----------

1MB POOL                     166723584          0 DONE                                1
64KB POOL                     25165824          0 DONE                                1
1MB POOL                     166723584          0 DONE                                2
64KB POOL                     25165824          0 DONE                                2

1MB POOL                     166723584          0 DONE                                3
64KB POOL                     25165824          0 DONE                                3
6 rows selected.
show parameter INMEMORY_SIZE
NAME                                 TYPE        VALUE

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

inmemory_size                        big integer 200M

跟传统的内存数据库不一样,oracle不需要把所有的对象都放在IM 列存储中.当然,如果数据库足够的小,也可以把所有的表都放在IM column store中.IN-MEMORY对表和物化视图增加了一个新的属性—INMEMORY,只有具有这个属性的对象可以加载进IM column store,这个属性可以指定在tablespace/表/表分区/物化视图等.
如果在表空间一级开启这个特性,那么这个表空间上所有的表和物化视图默认都具有了IM column store的特性。

Alter tablespace TBS_IM INMEMORY;
加载表但是不加载其中的某列

ALTER TABLE sales INMEMORY NO INMEMORY(prod_id);

从IM column store移除某个对象

ALTER TABLE sales MODIFY PARTITION SALES_Q1_1998 NO INMEMORY;

对象的populated顺序是由关键词PRIORITY

ALTER TABLE customers INMEMORY PRIORITY CRITICAL;

PRIORITY说明

Priority Level Description
CRITICAL Object is populated immediately after the database is opened
HIGH Object is populated after all CRITICAL objects have been populated, if space remains available in the IM column store
MEDIUM Object is populated after all CRITICAL and HIGH objects have been populated, and space remains available in the IM column store
LOW Object is populated after all CRITICAL, HIGH, and MEDIUM objects have been populated, if space remains available in the IM column store
NONE Objects only populated after they are scanned for the first time (Default), if space is available in the IM column store

IM的限制

1)下面的数据库对象是不能populated到IM column store的

Any object owned by the SYS user and stored in the SYSTEM or SYSAUX tablespace

Index Organized Tables (IOTs)

Clustered Tables

2)下面的数据类型是不支持的

LONGS (deprecated since Oracle Database 8i)

Out of line LOBS

不支持的数据类型的查询是经过buffer cache。

小于64KB的对象不支持,因为IM的分配单元是1MB的chunk。

当前的oracle发行版本ADG不能使用IM column store,但是可以使用在逻辑DG和OGG中。

In-Memory压缩

传统的压缩是以节省空间为目的。Oracle 12c中数据加载到IM column store采用了一个新的算法,既可以节省空间也可以提高性能。新的In-Memory压缩格式允许查询直接查询压缩列。这意味着scan和filter操作只针对一小部分数据,只对结果集进行解压缩。

In-memory压缩通过关键词MEMCOMPRESS指定。压缩有6个等级,每个等级代表着不同的压缩和性能。

Compression Level Description
NO MEMCOMPRESS Data is populated without any compression
MEMCOMPRESS FOR DML Minimal compression optimized for DML performance
MEMCOMPRESS FOR QUERY LOW Optimized for query performance (default)
MEMCOMPRESS FOR QUERY HIGH Optimized for query performance as well as space saving
MEMCOMPRESS FOR CAPACITY LOW Balanced with a greater bias towards space saving
MEMCOMPRESS FOR CAPACITY HIGH Optimized for space saving

 

例如

CREATE TABLE employees

( c1 NUMBER,

c2 NUMBER,

c3 VARCHAR2(10),

c4 CLOB

)
INMEMORY MEMCOMPRESS FOR QUERY
NO INMEMORY(c4)
INMEMORY MEMCOMPRESS FOR CAPCITY HIGH(c2);

ORACLE Compression Advisor

DBMS_COMPRESSION这个包已经进行了增强,对12.0.1.2的IN-MEMORY进行支持
用dbms_compression.Get_compression_ratio查看MEMCOMPRESS的影响

DECLARE
l_blkcnt_cmp PLS_INTEGER;
l_blkcnt_uncmp PLS_INTEGER;
l_row_cmp PLS_INTEGER;
l_row_uncmp PLS_INTEGER;
l_cmp_ratio PLS_INTEGER;
l_comptype_str VARCHAR2(100);
comp_ratio_allrows NUMBER := -1;
BEGIN
dbms_compression.Get_compression_ratio (
-- Input parameters
scratchtbsname => 'TS_DATA',
ownname => 'SSB',
objname => 'LINEORDER',
subobjname => NULL,
comptype => dbms_compression.comp_inmemory_query,
-- Output parameter
blkcnt_cmp => l_blkcnt_cmp,
blkcnt_uncmp => l_blkcnt_uncmp,
row_cmp => l_row_cmp,
row_uncmp => l_row_uncmp,
cmp_ratio => l_cmp_ratio,
comptype_str => l_comptype_str,
subset_numrows => dbms_compression.comp_ratio_allrows);
dbms_output.Put_line('The IM compression ratio is ’|| cmp_ratio);
END;
/

IM-MEMORY scan

In-Memory Storage Index

访问的数据量的进一步的减少是因为In-Memory Storage Indexes,他在每一列上(IM COLUMN STORE)都是oracle自动创建和维护的。Storage  index使得SQL基于filter谓词发生数据的裁剪。In-Memory Storage Index跟踪IMCU(In-Memory Compression Unit)中每一列的最大值和最小值。

当一个查询发送过来的时候,通过WHERE语句的谓词条件, 基于引用列上的In-Memory Storage Index将会被检查用以去确认是否在每一个IMCU中存在where条件指定的列的值,检查的方法就是去比较当前谓词指定的值与storage index维护的最大值和最小值。如果这个谓词列的值不在最大值和最小值之间,那么这个IMCU的扫描就不会发生了。

当基于字典的压缩被使用的时候,对于equality,in-list和其他一些range类型的谓词,其他级别的数据裁剪可以通过每个IMCU的元数据字典达到。元数据字典包含了一系列针对每一列(IMCU中)的不同的值,所以基于裁剪的数据字典允许oracle数据库确认正在被扫描的数值是否存在在IMCU中,确保必要的IMCU被扫描。

SIMD向量处理机制

对于确实需要被扫描的IM column store的数据,IN-MEMORY使用SIMD向量处理机制(Single Instruction processing Multiple Data values)。
与一次只估算一列中的实体相反,SIMD向量处理机制允许在一个单CPU指令下评估估算一个集合的列值。SIMD机制使oracle数据库IN-MEMORY可以每秒扫描几百万行数据。

IM-MEMORY JOIN

多表关联的SQL语句也可以通过IM column store得到处理性能的提升,原因是他们可以收益于Bloom Filters. Bloom Filters把join转换成对filter,使其成为应用于大表的扫描的一部分。Bloom Filters首先在oracle 10g中引入,用于增强HJ的性能,所以对于oracle数据库的IM-MEMORY并没有特别之处。然而,通过SIMD处理机制,他们可以有效的应用于列模式的数据。

IM-MEMORY聚合

分析类的查询通常不是简单的filters和joins。他们进行复杂的聚合和汇总操作。在oracle 12.1.0.2中引入了叫vector group by的优化器转换机制,用来确保可以使用新的CPU-efficient算法来处理更复杂的分析查询。

vector group by转换是一个two-part process,不同于星型转换.

DML和IN-MEMORY COLUMN STORE

Bulk Data Loads

当direct path load提交之后,IM column store立即就会知道对象的所有数据并没有全部populated.missing的数据大小可以通过查询v$im_segments视图的bytes_not_populated列获得。如果对象制定了优先级,那么新加载进来的素具会自动populated into IM COLUMN STORE;否则当下次对象被查询的时候,数据库后台进程会被触发去populated这些missing的数据(这里假设有足够的IM column store)

Partition exchange loads

如果希望在分区交换后,分区具有INMEMORY的属性,那么必须在交换发生前就在temporary table上制定这个属性,在空的分区表上制定是不够的。

事务处理

在OLTP类型的改变中,单条记录的DML操作发生在buffer cache中,这和没有IM是一样的,但是如果发生DML操作的对象在IM COLUMN STORE中是populated的,那么这些变更同样在他们发生的过程中影响着IM COLUMN STORE的。Buffer cache和column sote通过IN-MEMORY Transaction Manager保持事务的连续性。
All logging is done on the base table just as it was before, no logging is needed for the In-Memory Column store.
对IM COLUMN STORE的每一个IMCU,事务的journal都是自动创建和维护的。当一个DML语句改变了对象(the object is populated into the IM column store)中的一行,这行相应的条目信息被标记为stale,然后拷贝这行的一个新版本到im-memory的事务journal中。在IMCU中的原来的entry不会被理解取代换掉,以用来提供读一致性和保持数据压缩。在DML发生之前,任何针对IM COLUMN STORE中对象发生的事务都需要去查看这些entries的原始版本。在IM COLUMN STORE中的读一致性是通过SCN来管理的,跟没有im的数据库版本一样。当一个对象上发生了一次查询,这次查询带有更新的SCN号,那么他就会去读取在IMCU中列的所有entries(除了stale状态的)。这些stale状态的entries既可以从事务journal中获取也可以从基表(buffer cache)中获取。

Repopulation

当IMCU中存在越多的stale entries,那么IMCU的扫描就会越慢,因此,当在一个IMCU中stale entries的个数达到一定的阀值,oracle数据库就会repopulate这个IMCU。

阀值是由启发式算法来确定的,考虑了IMCU访问的频率和在IMCU中的stale状态行的数量。对于IMCU访问比较频繁或者具有较高数量的stale rows的情况,repopulation是很频繁的。IMCU的repopulation是通过后台worker进程在线执行的。在repopulation的过程中,IMCU中数据是一直可用的,并且对rows做的任何改变都是自动记录的。

除了标准的repopulation算法,还有一个算法使用低优先级的后台进程去清理所有的stale entries,就是IMCO(IN-MEMORY Coordinator)进程。IMCO后台进程会对在IM column store中IMCU进行trickle repopulation,这些IMCU可以是含有一些stale entries但是当前并没有达到staleness的阀值。Trickle repopulation是一个持续的后台活动进程。

IMCO进程每2分钟醒来一次去检查是否存在population的任务需要去完成。

IM 事务连续性的开销

保持IM事务连续性的开销主要根据应用的类型具有以下几类:
变更的频率;
in-memory压缩的等级;
变更的行记录的位置;
进行的操作的类型
具有较高压缩等级的表的开销也会比低等级压缩要高一些.

对于具有较高DML操作频率的表,建议采用MEMCOMPRESS FOR DML压缩方式,如果可以的话,对表进行分区则更好。

RAC中的In-Memory Column Store

Rac环境中每一个节点都有自己的IM column store,推荐设置是在每个rac节点中都设置一样大小的IM column store,对于不需要这个特性的可以通过设置参数IMMEMORY_SIZE为0来关闭。在每个节点中可以有完全不同的对象处于populated状态;或者某些个大对象分布在集群中所有节点的IM column store中;又或者在每个节点的IM column store中存在相同的对象(这种是针对Engineered Systems)。数据库对象分布在集群的IM column store中是通过2个sub-clause来控制,分别是DUPLICATE和DISTRIBUTE。

在RAC环境下,只有具有INMEMORY属性的对象可以分布在集群中所有的IM column store,这个对象如果分布在集群中是受DISTRIBUTED sub-clause控制。默认情况下oracle来决定最好的方式在集群中对数据库对象进行分布。

你也可以通过指定DISTRIBUTE BY ROWID RANGE来按照rowid range来分布,DISTRIBUTE BY PARTITION来分布分区到不同的节点,或者DISTRIBUTE BY SUBPARTITION去分布子分区到不同的节点。

例如

ALTER TABLE TABLE_NAME INMEMORY DISTRIBUTE BY PARTITION;

对于没有分区的表或者采用DISTRIBUTE BY PARTITION会使数据倾斜的情况适用ROWID RANGE模式。

如果对象很小(一个IMCU大小),那么这个对象将只能populated到集群中一个节点的IM column store中。

在Engineered System中,通过DUPLCATE sub-clause,每一个populated到IM column store中IMCU都有一个镜像拷贝在集群中的其他节点中。这种特性保证了im-memory的容错能力,确保了即使一个节点离线,通过IM column store访问数据的方式还是能够正常使用的。

实验

RAC分区表IN-MEMORY分布

create table blue.blue
(OWNER              VARCHAR2(128),
OBJECT_NAME         VARCHAR2(128),
SUBOBJECT_NAME      VARCHAR2(128),
OBJECT_ID           NUMBER,
DATA_OBJECT_ID      NUMBER,
OBJECT_TYPE         VARCHAR2(23)
)
INMEMORY PRIORITY NONE MEMCOMPRESS FOR QUERY LOW
DISTRIBUTE AUTO NO DUPLICATE CACHE;

insert into blue.blue select 
OWNER          ,
OBJECT_NAME    ,
SUBOBJECT_NAME ,
OBJECT_ID      ,
DATA_OBJECT_ID ,
OBJECT_TYPE    
from dba_objects;

create table blue.p_blue partition by range (object_id) (partition "P1" values less than (5000), partition p2 values less than (10000), partition p3 values less than (maxvalue)) as select * from blue.blue;

SQL> create table blue.p_blue partition by range (object_id) (partition "P1" values less than (5000), partition p2 values less than (10000), partition p3 values less than (maxvalue)) as select * from blue.blue;

Table created.
SQL> select count(*) from blue.p_blue partition (p1);

  COUNT(*)
----------
      4997
SQL> select count(*) from blue.p_blue partition (p2);

  COUNT(*)
----------
      4955
SQL> select count(*) from blue.p_blue partition (p3);

  COUNT(*)
----------
     80991
SQL> alter table blue.p_blue inmemory;

Table altered.
SQL> select count(*) from blue.p_blue;

  COUNT(*)
----------
     90943
SQL> select inst_id,SEGMENT_NAME,bytes/1024/1024,INMEMORY_SIZE/1024/1024 from gv$im_segments;

   INST_ID SEGMENT_NAME         BYTES/1024/1024 INMEMORY_SIZE/1024/1024
---------- -------------------- --------------- -----------------------
         1 P_BLUE                             8                   3.125
         1 P_BLUE                             8                   1.125
         2 P_BLUE                             8                   1.125


SQL> select INST_ID,SEGMENT_NAME,PARTITION_NAME,INMEMORY_SIZE from gv$im_segments;
   INST_ID SEGMENT_NAME         PARTITION_NAME                 INMEMORY_SIZE
---------- -------------------- ------------------------------ -------------
         2 P_BLUE               P2                                   1179648
         1 P_BLUE               P3                                   3276800
         1 P_BLUE               P1                                   1179648

SQL> alter table blue.p_blue inmemory distribute by rowid range;

Table altered.

SQL> select count(*) from blue.p_blue;

  COUNT(*)
----------
     90943

SQL> select INST_ID,SEGMENT_NAME,PARTITION_NAME,INMEMORY_SIZE from gv$im_segments;

   INST_ID SEGMENT_NAME         PARTITION_NAME                 INMEMORY_SIZE
---------- -------------------- ------------------------------ -------------
         2 P_BLUE               P3                                   3276800
         1 P_BLUE               P2                                   1179648
         1 P_BLUE               P1                                   1179648

可以看到分区的分布变化了。

IN-MEMORY性能的提升

表没有IN MEMORY

SQL> select count(*) from blue.blue;

  COUNT(*)
----------
     90947

Elapsed: 00:00:00.42

Execution Plan
----------------------------------------------------------
Plan hash value: 1460787118

-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   204   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| BLUE | 90947 |   204   (0)| 00:00:01 |
-------------------------------------------------------------------


SQL> select * from blue.blue;

90947 rows selected.

Elapsed: 00:00:02.32

Execution Plan
----------------------------------------------------------
Plan hash value: 193663003

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      | 90947 |  3996K|   205   (1)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| BLUE | 90947 |  3996K|   205   (1)| 00:00:01 |
--------------------------------------------------------------------------


Statistics
----------------------------------------------------------
        139  recursive calls
          0  db block gets
       6856  consistent gets
        716  physical reads
          0  redo size
    5867680  bytes sent via SQL*Net to client
      67244  bytes received via SQL*Net from client
       6065  SQL*Net roundtrips to/from client
          9  sorts (memory)
          0  sorts (disk)
      90947  rows processed

表IN MEMORY

SQL> select count(*) from blue.blue;

  COUNT(*)
----------
     90947

Elapsed: 00:00:01.04

Execution Plan
----------------------------------------------------------
Plan hash value: 1460787118

----------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |     1 |     8   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE             |      |     1 |            |          |
|   2 |   TABLE ACCESS INMEMORY FULL| BLUE | 90947 |     8   (0)| 00:00:01 |
----------------------------------------------------------------------------


Statistics
----------------------------------------------------------
         28  recursive calls
          0  db block gets
        746  consistent gets
          0  physical reads
          0  redo size
        544  bytes sent via SQL*Net to client
        551  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          5  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> SELECT * FROM V$INMEMORY_AREA;

POOL                       ALLOC_BYTES USED_BYTES POPULATE_STATUS
-------------------------- ----------- ---------- --------------------------
    CON_ID
----------
1MB POOL                     166723584    3145728 DONE
         3

64KB POOL                     25165824     131072 DONE
         3

SQL> SET AUTOT TRACE
SQL> select * from blue.blue;

90947 rows selected.

Elapsed: 00:00:02.64

Execution Plan
----------------------------------------------------------
Plan hash value: 193663003

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

| Id  | Operation                  | Name | Rows  | Bytes | Cost (%CPU)| Time
  |

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

|   0 | SELECT STATEMENT           |      | 90947 |  3996K|     9  (12)| 00:00:0
1 |

|   1 |  TABLE ACCESS INMEMORY FULL| BLUE | 90947 |  3996K|     9  (12)| 00:00:0
1 |

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

Statistics
----------------------------------------------------------
         11  recursive calls
          0  db block gets
         31  consistent gets
          2  physical reads
          0  redo size
    4541856  bytes sent via SQL*Net to client
      67244  bytes received via SQL*Net from client
       6065  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      90947  rows processed


对于全表的扫描,没有in-memory的时候select * from blue.blue,造成的consistent gets是6856,开启in-memory的话是31.
性能提升非常明显。

Multitenant环境下的IN-MEMORY Column store

在12c中,通过CDB和PDB的关系,允许了PDBS们可以共享common CDB的SGA区和后台进程,同样的,PDBs也共享一个IM Column store。

实验

SQL> set linesize 200
SQL> col PDB_NAME for a20
SQL> SELECT PDB_ID, PDB_NAME, STATUS FROM DBA_PDBS ORDER BY PDB_ID;

    PDB_ID PDB_NAME             STATUS
---------- -------------------- ---------
         2 PDB$SEED             NORMAL
         3 PDBRAC               NORMAL

SQL> show parameter inmemory
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
inmemory_clause_default              string
inmemory_force                       string      DEFAULT
inmemory_max_populate_servers        integer     1
inmemory_query                       string      ENABLE
inmemory_size                        big integer 200M
inmemory_trickle_repopulate_servers_ integer     1
percent
optimizer_inmemory_aware             boolean     TRUE

inmemory_size在这里我设置了200M。

SQL> alter session set container=PDBRAC;

Session altered.

SQL> select con_id,dbid,name,open_mode from v$pdbs;

    CON_ID       DBID NAME                           OPEN_MODE
---------- ---------- ------------------------------ ----------
         3 2507872820 PDBRAC                         MOUNTED

SQL> startup
Pluggable Database opened.
SQL> select con_id,dbid,name,open_mode from v$pdbs;

    CON_ID       DBID NAME                           OPEN_MODE
---------- ---------- ------------------------------ ----------
         3 2507872820 PDBRAC                         READ WRITE

SQL> show parameter inmemory

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
inmemory_clause_default              string
inmemory_force                       string      DEFAULT
inmemory_max_populate_servers        integer     1
inmemory_query                       string      ENABLE
inmemory_size                        big integer 200M
inmemory_trickle_repopulate_servers_ integer     1
percent
optimizer_inmemory_aware             boolean     TRUE
可以看到pdb继承了cdb的inmemory_size大小。

查看在pdb级可以修改的参数
SQL> select name from v$system_parameter where ispdb_modifiable = 'TRUE' and name like 'inmem%';

NAME
--------------------------------------------------------------------------------
inmemory_size
inmemory_clause_default
inmemory_force
inmemory_query

对inmemory_size进行修改设置
SQL> alter system set inmemory_size=20M;

System altered.
后台的告警日志中的信息输出如下
Opening pdb PDBRAC (3) with no Resource Manager plan active
Pluggable database PDBRAC opened read write
Completed: ALTER PLUGGABLE DATABASE  OPEN 
Thu Sep 18 20:42:55 2014
ALTER SYSTEM SET inmemory_size=20M SCOPE=BOTH;


SQL> show parameter inmemory

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
inmemory_clause_default              string
inmemory_force                       string      DEFAULT
inmemory_max_populate_servers        integer     1
inmemory_query                       string      ENABLE
inmemory_size                        big integer 20M
inmemory_trickle_repopulate_servers_ integer     1
percent
optimizer_inmemory_aware             boolean     TRUE

创建对象
SQL> alter user blue default tablespace TBS_12C;

User altered.

SQL> create table blue.blue as select * from dba_objects;
create table blue.blue as select * from dba_objects
                                        *
ERROR at line 1:
ORA-01950: no privileges on tablespace 'TBS_12C'


SQL> alter user blue quota unlimited on TBS_12C;

User altered.

SQL> create table blue.blue as select * from dba_objects;

Table created.

SQL> alter table blue.blue inmemory;

Table altered.


SQL> select count(*) from blue.blue;

  COUNT(*)
----------
     90939

SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name = 'BLUE';
SEGMENT_NAME         BYTES/1024/1024
-------------------- ---------------
BLUE                              13

SQL> select SEGMENT_NAME,bytes/1024/1024,INMEMORY_SIZE/1024/1024 from v$im_segments;

SEGMENT_NAME         BYTES/1024/1024 INMEMORY_SIZE/1024/1024
-------------------- --------------- -----------------------
BLUE                              13                   4.125

SQL> select segment_name,INMEMORY_PRIORITY,INMEMORY_DISTRIBUTE,INMEMORY_DUPLICATE,INMEMORY_COMPRESSION from v$im_segments;

SEGMENT_NAME         INMEMORY INMEMORY_DISTRI INMEMORY_DUPL INMEMORY_COMPRESS
-------------------- -------- --------------- ------------- -----------------
BLUE                 NONE     AUTO            NO DUPLICATE  FOR QUERY LOW

SQL> alter system set inmemory_size=300M;
alter system set inmemory_size=300M
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-02095: specified initialization parameter cannot be modified

不能比CDB中的值设置的大。

SQL> set autotrace on
SQL> select count(*) from blue.blue;

  COUNT(*)
----------
     90939


Execution Plan
----------------------------------------------------------
Plan hash value: 1460787118

----------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |     1 |    16   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE             |      |     1 |            |          |
|   2 |   TABLE ACCESS INMEMORY FULL| BLUE | 90939 |    16   (0)| 00:00:01 |
----------------------------------------------------------------------------

控制IN-MEMORY的初始化参数
INMEMORY_SIZE
INMEMORY_QUERY
INMEMORY_MAX_POPULATE_SERVERS
INMEMORY_CLAUSE_DEFAULT
INMEMORY_TRICKLE_REPOPULATE_SERVERS_PERCENT
INMEMORY_FORCE
OPTIMIZER_INMEMORY_AWARE

OPTIMIZER
The only thing the INMEMORY hint does is enables the IM column store to be used when the INMEMORY_QUERY parameter is set to DISABLE.

此条目发表在Infrastructure分类目录。将固定链接加入收藏夹。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s