第六章:体系结构篇


学习目标

1、什么是数据库实例?

2、内存体系结构有哪些&运行原理,后台进程有哪些&职责?


3、学完这一课后,你需要能够概括 Oracle 体系结构及其主要组件


4、查询SGA的大小,了解自动内存管理ASMM,AMM(IM除外不会自动调节)


5、程序全局区的作用

6、In-Memory 的功能和原理



解释 SGA 内存结构:数据库缓冲区高速缓存、共享池和重做日志缓冲区
解释主要的后台进程:DBWn、LGWR、CKPT、PMON、SMON
解释后台进程 ARCn 的用法
列出可选后台进程和条件后台进程

数据库内存体系组成:
系统全局区(sga)+程序全局区(pga)

sga:
1、数据库高速缓冲区缓存:
     1.1存储从数据文件中已检索到的数据块的副本
     1.2能够大幅提高获取和更新数据时的性能
     1.3通过 LRU 算法管理
     1.4主块的大小由 DB_BLOCK_SIZE 确定
      1.5 DB_CACHE_SIZE

2、重做日志缓冲区
     2.1记录对数据库数据块所做的全部更改
     2.2主要用于恢复
     2.3其中记录的更改称作重做条目
     2.4重做条目包含用于重新构造或重做更改的信息
     2.5大小由 LOG_BUFFER 定义


3、共享池:
     3.1最近执行的 SQL 语句 ;
     3.2最近使用的数据定义
     它包括以下两个与性能相关的关键内存结构:
     3.3库高速缓存 :存储有关最近使用的 SQL 和 PL/SQL 语句的信息
     3.4数据字典高速缓存:在语法分析阶段,
                     服务器进程会在数据字典中查找用于解析对象名和验证访问的信息,
                  数据库中最近使用的定义的集合:
           包括与数据库文件、表、索引、列、用户、权限和其它数据库对象相关的信息
     3.5其大小由 SHARED_POOL_SIZE 参数确定

4、large pool
     SGA 中的可选内存区
     分担了共享池的一部分工作
     用于:
     4.1共享服务器的会话内存 (UGA)
     4.3备份和恢复操作(RMAN)
     4.4并行执行消息缓冲区
     4.5不使用 LRU 列表
     4.6大小由 LARGE_POOL_SIZE 确定

SQL> alter system flush buffer_cache;



5、java pool
     5.1存储 Java 命令的服务分析要求
     5.2在安装并使用 Java 时是必需的
     5.3大小由 JAVA_POOL_SIZE 参数确定
6、In-Memory Area(内存区)12c,可选
         6.1以列的方式存储数据
     6.2优化事务处理和查询操作
     6.3 inmemory_size
     6.4 Join 联合操作的性能提升,操作转化为快速列扫描

7、查询SGA的大小
1> 显示SGA 大小
SQL> SHOW SGA
SQL> SELECT * FROM v$sga;
SQL> SHOW PARAMETER sga_target
2> 显示SGA 最大值
SQL> SHOW PARAMETER sga_max_size
3>显示PGA
SQL>show parameter pga

4>显示自动内存管理
AMM:MEMORY_TARGET

ASMM:SGA_TARGET_SIZE


8、查看后台进程

SQL> SELECT name FROM v$bgprocess WHERE paddr!='00';
或者
[oracle@oracle ~ ]$ ps -ef | grep ora_


9、PGA的功能特点
pga:
     为连接到 Oracle 数据库的每个用户进程保留的内存
     在创建进程时分配
     在终止进程时回收
     仅供一个进程使用
     排序和hash join



#####################





一: Oracle 服务器 的构成

Oracle 服务器是一个具有高性能和高可靠性面向对象关系型数据库管理系统,也是一个高效 的 SQL 语句执行环境。 Oracle 服务器具备以下的特点:
● 能够可靠的运行多用户环境下大量数据的处理,允许多用户同时访问相同的数据。
● 保证数据访问的高性能。
● 有效防止对数据的非法访问。
● 对于故障恢复提供高效的解决方案。


(一)、Oracle 服务器的总体结构


       Oracle 服务器同运行在操作系统下的很多程序一样,通过在后台运行一组可执行程序、在内存中开辟程序运行的存储区域并在磁盘上存储数据来运行运作。

      如图 1-1 所示,在传统的体系结构上,Oracle 服务器(Oracle Server)由实例(Instance)和数据库(Database)两大部分构成。实例是一组内存结构和 Oracle 后台迕程的集合;数据库在物理上由多个操作系统文件组成, 其中主要包括数据文件、控制文件和重做日志文件。
      如图 1-2 所示,在 Oracle 12c 体系结构上,在于多了 CDB+PDBS;

  • 每个PDB都有自己的一套包括system和sysaux 在内的表空间;
  • PDBs共享UNDO,REDO和控制文件;
  • 默认每个CDB都有自己一个TEMP表空间,但是每个PDB可以创建自己的TEMP表空间;Oracle 服务器 = 实例+数据

image

图 1-1(传统数据库体系结结构)


image


图 1-2(12c 数据库结构)




(二)、Oracle 实例

       如图 1-3 所示,Oracle 实例由内存结构(SGA)和 Oracle 后台进程组成的。

       当用户启动(start)实例时,Oracle 将自动地为 SGA 分配内存并启劢后台迕程,实例运行后,用户可以访问实例,由实例来访问数据库。实例相当于用户和数据库的中间层。

      当用户关闭(shut down)实例时,由操作系统负责回收内存。每个实例都有自己的 SGA、并且,每个实例同时只能访问一个数据库。

     Oracle 数据库实例(Instance) = 内存结构(SGA) + 后台进程(Background Process)。内存结构描述的是 Oracle 数据库对内存的使用构成。Oracle 内存结构被总称为 SGA (System Global Area),主要包括数据库高速缓冲区(Database Buffer Cache)、重做日 志缓冲区(Database Buffer Cache)、重做日 志缓 冲区(Redo Log Buffer)和共享池(Shared Pool)三个部分。Oracle 后台迕程主要包括 DBWn、 CKPT、LGWR、SMON、PMON、ARCn 和 RECO。

image


图 1-3



image




(三)、Oracle 数据库

      Oracle 数据库包含了用于存放数据的数据文件(DataFiles),用于保护 数据不丢失的联机重做日志文件(Online Redolog Files)和用于连接 Oracle 实例和数据库 所需要的控制文件(Control Files)。 Oracle 数据库 = 数据文件 + 控制文件 + 联机重做日志文件。 除了以上三种文件之外,Oracle 还包含了参数文件(Parameter File)、口令文件 (Password File)、归 档日志文件(Archived log Files)、以及跟踪文件(Trace File)和警 告文件(Alert Log File) 等非数据库文件。

  • 控制文件:记彔了数据库的各项信息,是连接 Oracle 实例和 Oracle 数据库的桥梁。 每个 Oracle 数据库包含 1-8 个控制文件。
  • 联机重做日志文件:记录了用户对数据的各项操作,用于保护数据不丢失。 以日志组的形式 存在。每个 Oracle 数据库至少包含两个日志组。
  • 数据文件:用于存放数据。
  • 参数文件:记录了 Oracle 实例的各项信息。分为劢态和静态初始化参数文件。
  • 口令文件:存放特定用户的口令。
  • 归档日志文件:相当于联机重做日志文件的备仹,用于保护数据不丢失。
  • 追踪文件:存放后台进程和服务器进程的跟踪信息。
  • 警告文件:警告文件由连续的消息错误组成。 可以查看到 Oracle 内部错诨、块损坏错误以及非默认的初始化参数值等 。




二、Oracle 内存结构

Oracle 的内存由系统全局区(System Global Area,简称 SGA)和程序全局区(Program Global Area,简称 PGA)组成。




(一)、系统全局区 SGA

        系统全局区(system global area,SGA)是一组包含了 Oracle 数据库数据及实例控 制信息的共享的内存结构。当多个用户并发地连接到同一个实例后,返些用户将共享此实例 SGA 中的数据。因此 SGA 也被称为共享全局区(shared global area)。 SGA 越大系统的性能越好,但 SGA 过大也会起到反作用。一般情冴下,SGA 不应超 过系统实际内存的 1/2。但从 Oracle 9i 开始支持动态 SGA 特性,即无需关闭实例就可以改 变数据高速缓冲区、共享池和大池的大小。 数据高速缓冲区、共享池的大小也可以根据工作 负载自劢调整,但 SGA 的总大小不能超过初始 化参数 SGA_MAX_SIZE 的设置。


1.SGA 的构成

   如图 2-1 所示,SGA 包括三个子缓冲区:保留缓冲区、循环缓冲区和非标准大小块缓 冲区。

  • SGA 包括以下结构: Database Buffer Cache(数据库高速缓冲区)
  • In-Memory Area(内存区)--12c 新特性
  • Redo Log Buffer(重做日志缓冲区)
  • Shared Pool(共享池)
  • Large Pool(大池)
  • Java Pool(JAVA 池) 
  • Streams Pool(流池) 
  • Fixed SGA(固定 SGA)

1.1Database Buffer Cache(数据库高速缓冲区)

        在 Oracle 中无论是读取迓是修改数据,都是由服务器进程在数据库高速缓冲区中完成的。数据库高速缓冲区的作用就是用来缓存最近从数据库中读出的数据块,并可供其他客户进程共享。用户进程查看数据时,首先检查需要的信息是否在缓冲区内,如果在缓冲区中,就可以直接访问,否则访问物理文件并读取数据块到数据库缓冲区。我们知道内存的读写速度要比物理设备的读写速 度快很多,返样就可以大大提高 Oracle 数据库的性能。

1) 数据库高速缓冲区的子缓冲区

        根据缓冲数据块的状态,Oracle 将数据高速缓冲区可划分

           ● 脏缓冲区(Dirty Buffer): 

当数据库发生DML(Insert、Update、Delete)操作时,会对缓冲区内进行修改,返样缓冲区的内容就会和相对应的数据文件不一致,返时,缓冲区标识为“脏缓冲区”。

           ● 自由缓冲区(Free Buffer):

当“脏缓冲区”的内容被写入数据文件后,因为该缓冲区不相应数据文件部分内容一致,所以将返些缓冲区称为“自由缓冲区”

         ● 忙缓冲区(Pinned Buffer):

“忙缓冲区”是指服务器进程正在访问的缓冲区。每个数据库的数据库高速缓冲区大小有限,所以一般不会把磁盘上的所有数据都可以存放在缓冲区中。为了防止数据库高速缓冲区空间不够用,Oracle 会将脏缓冲区中的数据写入对应的数据文件中,以腾出空间给新的数据。如果缓冲区不脏,即为“自由缓冲区”,它可以直接被读入新的数据块。随后访问被写入磁盘导致额外的高速缓存未命中的数据。“脏列表”的作用就是记录脏缓冲区的情况。如果某些缓冲区中的数据块被修改,就会加入该列表,只有脏列表中的缓冲区数据块需要写回数据库文件,一旦写回数据库文件,缓冲区就会从脏列表中清除。

2) 非标准块大小支持
  • 数据库块是 Oracle 数据库 I/O 的最小单位。
  • 每个数据库都可以通过参数 DB_BLOCK_SIZE 指定标准块大小(2k、4k、8k、16k、32k),默认为 8k。但是 Oracle 数据库同时支持多种块大小,我们称返些标准块以外的块为“非标准大小块”。
  • 非标准大小块的高速缓冲区大小指定以下参数(DB_nK_CACHE_SIZE):
  • DB_2K_CACHE_SIZE
  • DB_4K_CACHE_SIZE
  • DB_8K_CACHE_SIZE
  • DB_16K_CACHE_SIZE
  • DB_32K_CACHE_SIZE
  • DB_nK_CACHE_SIZE 参数丌能用于设定标准大小块的高速缓存,标准大小块的缓存尺寸由参 数 DB_CACHE_SIZE 的值决定。


3) 使用多个缓冲区


        数据库管理员(DBA )可以通过创建多个缓冲池来提高数据库缓冲区高速缓存的性能。用户 可以指定方案对象(schema object)(表,簇,索引,及分区)使用相应的缓冲池,以便控制数 据被移出缓存区的时机。

    ● 保留缓冲区(Keep Buffer Cache):用来保留在内存中最有可能重用的对象。
             保留返些对象将减少 I/O 操作,指定 DB_KEEP_CACHE_SIZE 参数的值配置。
    ● 循环缓冲区(Recycle Buffer Cache):用来保留被重用机会丌大的内存块。
             指定 DB_RECYCLE_CACHE_SIZE 参数的值配置该缓冲区的大小。
    ● 默认缓冲区(Default Buffer Cache):此池始终存在。它相当于一个实例的数据库高速缓冲区中保留和循环区以外的部分。指定参数 DB_CACHE_SIZE。注:保留缓冲区和循环缓冲区并非默认缓冲区的子集。可以使用 BUFFER_POOL 子句对对象定义默认的缓冲区。


4) 数据库高速缓冲区空间管理

        Oracle 用 LRU(Least Recently Used)算法来管理数据高速缓冲区。该算法将最近使用的数据块按照使用时间的早晚排成队列,当缓冲区占满后,调入新的数据块时,必须清除已有的数据块,来获得空闲数据块空间,那么,最合理的选择就是清除最早没有使用数据块,因为使用该块的概率相对比较小。通过规划 SGA 时合理地设置数据高速缓存的尺寸,尽量的避免缓冲区占满的情况发生,否则就会降低系统的效率。

       Oracle 将队列分成两端,分别为热端和冷端。

image

       假设新数据块 K 将要被读入,又没有空闲位置,则 Oracle 会对况端头 J 块进行判断:假设J 被访问次数为 1,Oracle 将会认为 J 不是一个经常被访问的块(冷),则会将 J 块踢出队列,将K 插入至 F 的位置,F 和其他块右移:

image

假设新数据块 L 将要被读入,又没有空闲位置,则 Oracle 会对况端头 I 块进行判断:假设 I 被访问次数为 5,Oracle 将会认为 I 是一个经常被访问的块(热),则会将 I 块放入热端头,A 和其他快右移如下图所示:

image

      这时,将对下一个冷端头块 这时,将对下一个冷端头块 H 进行判断:假设 进行判断:假设 进行判断:假设 H 被访问次数为 1,Oracle   将会认为 H 不是 一个经常被访问的块(冷),  则会将 H块踢出队列,将 L 插入至 E 的位置, E 和其他块右移:

image       但是这时,我们会发现。I 块被放入热端头,经过漫长的时间,I 块最终会被放到冷端头进行判断;如果这段时间中,即使 I 没有再被访问过,I 的访问次数也仍然是 5,返样 I 将再次回到热端头,返样就造成了死循环,I 永迖无法被踢出列表。因此,当 I 被放到热端头的时候,访问次数将会被清零。如果返段时间 I 被访问多次,则有机会回到热端头,否则,可能被踢出列表。


1.2In-Memory Area(内存区)

         一个可选的 SGA 组件,包含内存列存储(IM 列存储)。IM 列存储包含以快速扫描优化的柱状格式的表,分区和物化视图的副本。IM 列存储库补充了以传统的行格式存储数据的数据库缓冲区缓存。(单独章节介

image


1.3Redo Log Buffer(重做日志缓冲区)

       当运行 Oracle 服务器的时候,如果突然断电或者系统瘫痪,会不会造成数据的丢失?Oracle 提供了一套复杂的机制来维护数据完整性,并最终确保数据不会丢失。这就是重做日志文件的作用。重做日志缓冲区用来记彔对数据缓冲区数据进行的修改,可以循环使用。当用户运行DML(INSERT、UPDATE、DELETE)以及 DDL(CREATE、ALTER、DROP)语句时,会改变数据高速缓存中的相应缓冲区。但是在修改返些缓冲区之前,Oracle 会自动生成重做项,首先要将这些缓冲区的变化记载到“重做日志缓冲区”中。重做日志缓冲区由一条一条的重做项构成,每条重做 项记载了修改的时间、被修改的、修改位置以及新数据。缓冲区被循环使用,当重做日志缓冲区 填满时,数据库系统将重做日志缓冲区的内容写入日志文件。在系统发生故障时,可以通过重做项 重新执行对数据库的修改,实现对实例的恢复。

      重做日志缓冲区的大小由 LOG_BUFFER 初始化参数来决定。

image



1.4 Shared Pool(共享池)

       缓存各种类型的程序数据,例如:存储已解析的 SQL,PL / SQL 代码,系统参数和数据字典信息。共享池几乎涉及数据库中发生的每个操作。例如,如果用户执行 SQL 语句,则 Oracle 数据库将访问共享池。共享池分为几个子组件:图 2-2

  •  库缓存--Library Cache
  •  数据字典缓存--Data Dictionary Cache
  •  服务器结果缓存--Server Result Cache

image



1)库缓存库

      高速缓冲区又可分为共享 SQL 区和共享 PL/SQL 区。 共享 SQL 区用来存放最近执行的SQL 诧句信息,包括语句文本、解析树及执行计划。执行计划就是 Oracle 为执行特定的 SQL 语句,产生的优化的执行步骤。 库高速缓冲区由许多上下文区(Context Area)组成,SQL 语句和执行计划存放在相应上 下文区中,并丏丌同 SQL 语句分别对应于不同的上下文区。当客户端运行 SQL 语句时,服 务器进程首先检查是否存在对应于该 SQL 语句的上下文区,若存在,则按照其 执行计划直 接执行该 SQL 诧句;否则生成 SQL 诧句执行计划,并将执行计划、SQL 语句存放到相应 上下文区中,然后执行该 SQL 诧句。 在开发应用程序时,必须要注意使用标准格式来编 写 SQL 语句,使得 SQL 语句尽可能 共享上下文区,以降低 SQL语句解析次数,进而提高应 用性能。 在解析 SQL 诧句时,认为完全相同的 SQL 诧句有以下特点:

● 语句文本相同。
● 大小写相同。
● 赋值变量相同。


共享 PL/SQL 区用来存放最近执行的 PL/SQL 语句,解析和编译过的程序单元和过程(函 数、包和触发器)也存放在此区域。 类似于数据高速缓冲区,Oracle 也是使用 LRU 算法来管理库高速缓存的。通过库高速 缓存,可以最小化 SQL 语句解析次数,进而提高应用程序的性能。

  共享池中内存的分配和重用:解析新 SQL 语句时,数据库会分配共享池内存,除非该语句是 DDL,不认为是是可共享的。分配的 内存大小取决于语句的复杂程度。

通常,共享池中的项目将保留,直到数据库根据最近最少使用(LRU)算法将其删除。只要数据库有用,数据库允许许多会话使用的共享池保留在内存中。此机制最大限度地减少了 SQL 语句的开 销和处理。如果新项目需要空间,则数据库将释放不常使用的项目所消耗的内存。
该 ALTER SYSTEM FLUSH SHARED_POOL 诧句删除共享池中的所有信息。


2)数据字典

     字典是一系列保存了数据库参考信息(例如数据库结构,数据库用户等)的表和视图。Oracle 需要频繁地使用经过解析的 SQL 语句访问数据字典。数据字典信息对 Oracle 能否正常运行至关重要。

      在Oracle 数据库中,数据库的一些信息,包括账户、数据文件、表的描述、用户权限 等信息,存储在数据字典表中,数据字典表被存放在 SYSTEM 表空间的数据文件中。 因为执行任何SQL 语句都需要访问数据字典,所以为了提高数据字典的访问性能, Oracle 在共享池中与门为存放数据字典信息分配了内存空间,返些内存空间被称为数据字 典高速缓冲区。用来缓存来自于 数据字典的定义。 例如,当用户执行"SELECT * FROM emp WHERE empno=7788"语句时,Oracle 需要 查询数据字典 dba_tables 确定表 emp 是否存在;如果该表已经存在,还需要查 询数据字典 dba_tab_columns 确定列 empno 在表 emp 中是否存在,然后才能生成执行语句 的过程(执 行计划)。返些定义在首次查询时存入数据字典高速缓冲区,在后续过程中用到就可以 直接 使用,而不必重新查询数据字典。


3)服务器结果缓存
        为 SQL 查询结果缓存,PL/SQL 函数结果缓存
        SQL 执行查询时,数据库将搜索内存是否存在于结果缓存中。如果结果存在,则数据库将从 内存中检索结果,而不是执行查询。如果未缓存结果,则数据库执行查询,将结果作为输出返回, 然后将结果存储在结果缓存中。只要事务修改用于构造缓存结果的数据库对象的数据或元数据,数 据库就会自动使缓存的结果无效

       如果没有缓存,每次调用 1 次的 1000 次函数调用将需要 1000 秒。使用缓存,具有相同输入的 1000 个函数调用可能总共需要 1 秒。结果缓存的良好候选者经常是依赖于相对静态数据的调用函数。

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


1.5Large Pool(大池)

       数据库管理员可以配置一个称为大型池(Large Pool)的可选内存区域,供一次性大量的内存分配使用,例如:

  • 用于共享服务器和 Oracle XA 接口的 UGA (用于事务不多个数据库交互的接口)
  • 用于并行执行诧句的消息缓冲区
  • 恢复管理器(RMAN)I / O 的缓冲区

      如果从大型池内为共享服务器,Oracle XA,或并行查询缓冲区(parallel query buffer)分配会话内存,共享池(shared pool)就能够专注于为共享 SQL 区(shared SQL area)提供内存,从而避免了共享池可用空间减小而带来的系统性能开销。此外,Oracle 备仹不恢复操作,I/O 服务进程,及并行执行缓存所需的存储空间通常为数百 KB。与共享池相比,大型池能够更好地满 足此类大量内存分配的要求。通过从大型池分配会话内存,数据库可以避免在数据库从共享池分配 内存时可能发生的内存碎片。当数据库为会话分配大池内存时,除非会话释放该内存,否则不能释 放该内存。


注:大型池不使用 LRU 列表管理其中内存的分配不回收。


1.6Java Pool(JAVA 池)& Streams Pool(流池)

       SGA 内的 Java 池(Java Pool)是供各会话内运行的 Java 代码及 JVM 内的数据使 用的。Java 池是 SGA 的可选区域,用来为 Java 命令解析提供内存。只有在安装和使用 JAVA 时才需要 JAVA 池。 Java 池的大小由 JAVA_POOL_SIZE 初始化参数来决定。 在数据库中,管理员可以在 SGA 内配置一个被称为数据流池(Streams Pool)的内 存池供 Oracle 数据流(Stream) 分配内存。流池用于存储缓冲队列的消息、捕获过程 Oracle 数据流提供存储器和应用程序。 Streams 池由 Oracle Streams 独占使用。除非您专门配置它,否则 Streams 池的大小从零开始。管理员需要使用 STREAMS_POOL_SIZE 初 始化参数设定数据流池的容量(单位为字节)。

注:Java 编程和 Oracle 数据流的详细讨论超出了本课程的范

1.7Fixed SGA(固定 SGA)

        是一个内部区域,例如,固定的 SGA 包含:

  •         后台迕程需要访问的数据库和实例状态的一些信息
  •           进程之间传递的信息,例如有关锁的信息
  •           固定 SGA 的大小由 Oracle 数据库设置,不能手动更改。固定的 SGA 大小可以在发行版之间变化








(二)、程序全局区 PGA


         当客户进程访问 Oracle 服务器时,会在 Oracle 服务器端为用户进程分配相应的服务进程,并且为该服务进程分配相应的内存空间来存放其数据和控制信息,每一个后台进程也同 样需要 为其分配专用的存储空间,这块内存空间被称为程序全局区(Program GlobalArea 或Process
GlobalArea )。如图 1-5 表示为服务进程专门分配 PGA 存储区。 所有进程都可共享 SGA,而 PGA 是非共享的。当建立服务进程或后台进程时,Oracle 会自动为其分配 PGA;而当服务进程或后台进程终止时,Oracle 会自动释放 PGA 所占用 的内存空间.

根据与有和共享服务器模式 的不同,PGA 的内存也会发生变化,但大致可分为三部分:

1.私有 SQL 区

        私有 SQL 区(Private SQLArea)中包含绑定信 息(Bind Information)及运行时内存结构(Runtime Memory Structure)等数据。每个提交了 SQL 语句 的会话都有一个私有 SQL 区。每个提交了相同 SQL 语句的用户都有自己的私有 SQL 区,但她们使用同 一个共享 SQL 区(SharedSQLArea)。即多个私有 SQL 区可以和同一个共享 SQL 区相联系。 游标的私有 SQL 区又可以被分为两个区域,返 两部分的生命周期有所不同:

● 持续数据区(PersistentArea),包含绑定信息(Bind Information)之类的数据。 此区只在游标关闭时才会被释放。

● 运行时间区(Run-timeArea),当执行请求的第一步创建,对于 INSERT, UPDATE,和DELETE 命令,返个区域当语句执行后释放。 对于查询,只有所有行取出后或查询取消后该区域才释放。私有 SQL 区即可位于 SGA 也可位于 PGA。

● 对与有服务器模式私有 SQL 区位于服务进程的 PGA 区;

● 对共享服务器模式私有 SQL 区位于 SGA。私有 SQL 区管理由用户进程完成,一个用 户进程可以分配的游标私有 SQL 区个数由 OPEN_CURSORS 参数限定,默认值是 50.

● 专用服务器:对于每个用户,Oracle 服务器对每个用户进程执行一个与有的服务进程。

● 共享服务器:一个共享服务器进程响应多个客户端的请求。

2.会话内存(SessionMemory)

    会话内存是为会话变量和会话有关信息分配的内存。对共享服务器模式,会话内存也是共享的。


3.SQL 工作区(SQLWorkAreas)


         SQL 工作区用于排序(Sort)哈斯连接(Hash-join)位图(Bitmap)合并和位图创建。该 区域大小即可控制也可以自动调整。
         用户可以对工作区的容量进行控制与调优。一般来说,更大的工作区能够显著地提高 SQL 操 作的性能,但代价是消耗更多的内存。最理想的情冴是,工作区能够容纳 SQL 语句的全部输入数 据及额外的控制内存结构。否则语句的响应时间将增加,因为部分输入数据必须放入临时磁盘区。
在极端情冴下,如果工作区容量远小于输入数据,那么输入数据需要在临时磁盘区与工作区间多次 交换。返将显著地增加 SQL 操作的响应时间。 从 Oracle9i 开始,通过设置初始化参数WORKAREA_SIZE_POLICY(默认值为 TRUE) 和 PGA_AGGREGATE_TARGET,工作区可以自 动的进行全局管理。 PGA_AGGREGATE_TARGET 参数设置实例的 PGA 目标总量,可以动态的 修改。当设置了此参数,所有的工作区大小就变为自动修改。在 Oracle9i 之前,控制 SQL 工作 区的最大尺寸,是通过设置以下参数:  SORT_AREA_SIZE 、 HASH_AREA_SIZE 、BITMAPMERGEAREASIZE 和 CREATEBITMAPAREASIZE 完成的。


4.专用服务器和共享服务器

     某些内存分配特性不系统使用与用服务器迓是共享服务器模式有关。

      表 2-1 展现了两种情况的区别。

image






三、Oracle 进程结构

       Oracle 的进程分为用户进程、服务器进程和后台进程。 用户进程是在客户机内存上运行的程序,在用户请求连接 Oracle 数据库时建立。用户 进程不能直接同 Oracle 服务器交互,而是把操作请求提交给服务进程。服务进程是在用户 同 Oracle 数据库建立会话之后自动在服务器端创建的进程。服务进程直接同 Oracle 服务器 交互,执行用户请求并返回结果。服务进程有专有和共享之分。 后台进程属于 Oracle 实例的一部分,Oracle 的后台进程的作用是对数据迕行操 作,并 维护数据库系统,使其始终处于良好的状态。





(一)、用户进程与服务器进程

       如图 3-1 所示,如果用户要提交并执行 SQL 语句,在用户的客户机上,要运行一个程 序如SQL*Plus 戒其他应用程序,返个程序是作为用户进程(UserProcess)运行的。当用 户需要连接到 Oracle 服务器时,在 Oracle 服务器上会启劢一个不用户迕程对应的迕程来为 用户迕程服务,
返个迕程称为服务迕程(ServerProcess) 。注意,服务迕程总是运行在 Oracle 服务器上面的,
而用户迕程既可以运行在服务器上面,也可以运行在客户机上面


image


     用户进程同服务进程通讯,需要建立一个连接,最简单的情冴是用户迕程同服务进程位于同一台机器,可通过内部进程通讯机制进行连接;用户也可以通过客户服务器 (Client-Server)软件通过网络迕行连接,返时需要进行相应的网络通讯配置;比较复杂的 情况是通过三层结构,比如以浏览器作为客户端进行连接。

   如果一个客户进程对应一个服务进程,我们称该连接为专有(Dedicated)服务器连接, 如 果多个客户进程对应一个服务器迕程,我们称该连接为共享(Shared)服务器连接。

       当特定的用户同 Oracle 服务器连接成功,并通过 Oracle 服务器的身仹验证,返时用户 和Oracle 服务器之间建立了一个会话(Session) ,同一个用户可以并发的同 Oracle 数据库建 立多个会话。当用户退出或异常断开时,会话就结束



(二)、后台进程

1.LGWR 日志写入进程(Log Writer)
LGWR 日志写入进程负责将重做日志缓冲区的日志条目写入磁盘上的联机日志文件。
当运行DML 或DDL 语句时,服务器进程首先要将事务的变化记载到重做日志缓冲区,
然后才会写入数据高速缓冲区,
并且重做日志缓冲区的内容将会被写入联机重做日志文件,
以避免系统出现意外带来的数据损失
(如果操作系统断电,内存中的重做日志缓冲区的内容会丢失,
而存在磁盘上的联机日志文件则不会丢失),这项任务由LGWR 来完成。
重做日志缓冲区是一个循环结构,LGWR 将重做日志缓冲区中的重做记录写入联机重
做日志文件后,相应的缓冲区内容将被清空,
保证Oracle 有空闲的重做日志缓冲区可以写入。
在出现以下情况时LGWR 会开始工作:
● 在DBwR 进程将脏缓冲区写入数据文件之前。
//预写协议
● 在重做日志记录达到缓冲区的三分之一。
● 日志缓冲区记录的日志多于1M。
● 每隔3 秒钟。
//重做日志缓冲区是循环使用的,要腾出足够的空间给新的记录使用
● 提交事务(执行Commit)。
//提交事务相当于确定保存修改,不存入日志文件就有丢失的可能
Oracle总是先记载数据变化到重做日志缓冲区,然后才修改数据高速缓存。
与之类似,在后台进程DBWn 将脏缓冲区写入到数据文件之前,
首先要由后台进程LGWR 将重做日志缓冲区写入到重做日志中。
与数据高速缓存相比,重做日志缓冲区相对要小得多,但写入频率高的多,
Oracle 必须要确保重做日志缓冲区总有足够的空间容纳新事务,
因此每隔3 秒钟或重做日志缓冲区已有三分之一填满时LGWR 会自动工作。
另外,Oracle 采用了快速提交机制,当执行COMMIT 操作时,
并不是将“脏缓冲区”数据写入到数据文件中,
而是将重做日志缓冲区的内容写入到重做日志文件中,以确保数据库完整性。
此时即使系统出现意外情况(如掉电、系统崩溃等),
因为被提交事务已经记载到了存放在磁盘上的联机重做日志文件中,
将来在重新启动数据库时系统会自动进行实例恢复,
并将事务所修改数据写入到数据文件中,从而避免了数据丢失。


2.DBWn 数据库写入进程(Database Writer)
数据库写入进程负责将数据库高速缓冲区(脏缓冲区)的内容
写入到数据文件尽管有一个数据库写进程( DBW0 )适用于大多数系统,
但数据库管理员可以配置额外的进程(DBW0-DBW99,最0~99 个进程),
以提高写入性能,通过设置初始化参数DB_WRITER_PROCESSES 来完成。
如果你的系统修改数据严重,这些额外的DBWn 进程在单处理器系统不是非常有用。
当数据库高速缓冲区的块被修改,
它被标记为脏缓冲区并添加到以SCN
(System Change Number,系统更改号,这里可以看做“时间”)
为顺序的LRUW(LRUWriter)列表。同时,这个顺序与重做日志缓冲区的顺序一致。

在出现以下情况时DBWn 进程会开始工作:
● 系统发出检查点指令。
//同步数据,详见检查点进程(CKPT)。
● 脏缓冲区个数达到指定阀值。
● 服务进程搜索一定数目的数据块后,不能找到自由缓冲区。
● 数据写入计时时间到。
//客户端执行SELECTINSERTUPDATEDELETE 语句时,都需要访问数据库高
速缓冲区。如果是第一次访问,必须要将数据由数据文件读取到数据库高速缓冲区,所
以Oracle 必须要确保数据高速缓存总是存在足够的“自由缓冲区”以容纳新数据。
当DBWn 进程将脏缓冲区的数据块写入到数据文件后,Oracle 将把“脏缓冲区”
标记为“自由缓冲区”。
因此,为了保证有足够“自由缓冲区”来存放新的数据块,需要DBWn 进程工作。
● 表空间脱机或进入只读状态。
● 执行删除或截断表操作。TRUNCATE TABLE XXXXX;
● 执行ALTER TABLESPACE … BEGIN BACKUP 命令
//需要同步数据,原理同检查点。


3、CKPT 检查点进程(Checkpoint)
CKPT 检查点进程的作用是执行一个“检查点”,同步数据库的所有数据文件、控制文
件和重做日志文件。当执行检查点时,
系统促使DBWn 将数据缓冲区中数据的变化写入数
据文件,同时完成对数据文件和控制文件的更新,记录下当前数据库的结构和状态。
在执行一个检查点之后,数据库处于一个完整状态。
在数据库发生崩溃后,可以将数据库恢复到上一个检查点。
Oracle 数据库在执行涉及数据变化的语句时,会针对任何修改生成一个顺序递增SCN
(System Change Number)值,并且会将SCN 值连同事务的变化一起记载到重做日志缓
冲区。在数据文件、控制文件头部以及重做日志文件中都记载有该值。
Oracle 通过比较各种文件的SCN 值,确定文件是否损坏、系统是否异常,
最终确定系统是需要进行实例恢复还是介质恢复。
在发出检查点时,数据文件、控制文件和重做日志的SCN 值完全一致。
进程CKPT 在以下情况下会开始工作:
● 发生日志切换。(ALTER system switch logfile)
● 关闭实例(SHUTDOWN ABORT 除外)。
● 手工执行检查点操作。(alter system checkpoint;)
● 由初始化参数LOG_CHECKPOINT_INTERVAL 和LOG_CHECKPOINT_TIMEOUT 强制发出。


4.SMON 系统监控进程(System Monitor)
SMON 系统监控进程主要作用是强制对数据库进行恢复操作。在实例启动时,如果上
一次数据库是非正常关闭,并且重做日志文件和控制文件的SCN 值是不同的,
Oracle 将自动在重新打开数据库之前,通过执行重做日志文件的记录,
来同步所有数据文件、控制文件
和重做日志文件,确保所有数据库文件的一致性,然后才打开数据库。
如果检查点进程一例中,第四步完成后发生系统掉电、崩溃,那么数据会不会丢失呢?
当然不会。我们知道,系统掉电,导致内存中的数据(数据库高速缓冲区)的数据丢失。那
么自然上例中的第五步无法完成(无法从数据库高速缓冲区写入数据文件),
但是由于此时已写入联机日志文件。因此,此时数据将从联机日志文件中更新,
而更新的数据量是多少,自然就是由SCN 决定。
这一过程我们成为“实例恢复”。该过程不需要数据库管理员手工干预,由SMON 进程
自动完成。
该进程还负责在启动实例时清理临时段和合并区(Extent)碎片等工作。
所以SMON进程的工作归纳如下:
● 进行实例恢复
● 合并数据文件的自由空间
● 释放数据文件的临时段

5.PMON 进程监控进程(Process Monitor)
PMON 进程监控进程负责对失败的用户进程或服务进程进行恢复。当用户进程连接到
Oracle 服务器时,Oracle 将在服务器端分配相应的服务进程。
这时由PMON 进程来监视用户进程的执行情况。
当由于种种原因,用户对Oracle 数据库的连接,发生崩溃、挂起或异常终止现象时,
该进程负责清除服务进程所占用的资源,回滚没有完成的事务。
当PMON 检测到用户进程失败时,进行的工作归纳如下:
● 回滚当前用户的事务
● 释放当前用户加的表或行级锁
● 释放用户的其他资源
● 重新启动死掉的调度进程
假定我们在客户端运行SQL*Plus 并通过网络访问Oracle 服务器,那么Oracle 将在服
务器端分配相应的服务进程。假如用户异常终止SQL*Plus,
或出现网络断开或客户端死机的情况,
PMON 就必须检测到这种情况,并释放掉服务进程所占用的资源。

6.LREG
检测监听器是否正常运行,正常则将相关参数传递给它,
没有则定期(60s)尝试联系Note:
12c之前由PMON执行监听器注册;


7.ARCN:
可选的后台进程
.设置 ARCHIVELOG 模式时自动归档联机重做日志
.保留数据库的全部更改记录







四:Oracle 数据库进程


(一)、大纲

• 内存管理


• 用户进程


• 服务器进程


• 后台进程




(二)、SGA内存管理

1:SGA内存管理

手动SGA内存管理
       MEMORY_TARGET&SGA_TARGET 都设置为零
       DB_CACHE_SIZE,SHARED_POOL_SIZE…
Oracle10g及更高版本,设置SGA_TARGET参数(auto)
Oracle11g及更高版本,设置MEMORY_TARGET参数
         Tips:在oracle11gR2版本中,关闭了自动内存管理,Oracle 仍可能进行一定程度的内存充分配工作。

Oracle 提供了自动SGA 的管理(简称ASMM,Automatic    SharedMemory Management)。
Oracle 数据库会根据系统负载变化,自动调整各组件的大 小,从而使得内存始终能够流向最需要它的地方。
INMEMORY_SIZE (这个不是自动调整)

image



ASMM,一个名为MMAN(Memory Manager)的后台进程。每隔很短的一段时间,MMAN 进程就会启动,然后去询问一下Oracle 提供的各个内存组件顾问,比如有buffer cache 顾问,也有shared pool 顾问,由这些顾问根据当前的负载情况,将这5 个可以自动调整的内存池的、建议的大小尺寸,返回给MMAN。于是,MMAN 进程就会根据该返回的值,来设置各个内存池。同时,如果我们使用spfile,还会将这些顾问得出的建议值写入spfile 里。这样,下次启动实例时,就可以直接把顾问得出的建议值拿来作为启动内存池的依据了。


MEMORY_TARGET=SGA+PGA
MEMORY_MAX_TARGET分配给数据库的最大内存量

MEMORY_TARGET可以手动调整设置但不允许超过max.

image


SQL> show parameter memory

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
hi_shared_memory_address             integer     0
inmemory_clause_default              string
inmemory_force                       string      DEFAULT
inmemory_max_populate_servers        integer     0
inmemory_query                       string      ENABLE
inmemory_size                        big integer 0
inmemory_trickle_repopulate_servers_ integer     1
percent
memory_max_target                    big integer 1440M
memory_target                        big integer 1440M
optimizer_inmemory_aware             boolean     TRUE

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
shared_memory_address                integer     0
SQL> show parameter memory_target

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
memory_target                        big integer 1440M
SQL> show parameter sga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     TRUE
sga_max_size                         big integer 1440M
sga_target                           big integer 0
unified_audit_sga_queue_size         integer     1048576
SQL> show parameter pga

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_limit                  big integer 2G
pga_aggregate_target                 big integer 0
SQL>

AMM 内存自动管理 auto memory manager








(三)、Oracle 进程

1:用户进程

•用户进程:在数据库用户请求连接到 Oracle 服务器时 启动
•服务器进程:与 Oracle 例程相连接,在用户建立会话 时启动
•后台进程:在 Oracle 例程启动时启动

•请求与 Oracle 服务器交互的程序
•必须先建立连接
•不与 Oracle 服务器直接交互

image

2:服务器进程

•直接与 Oracle 服务器交互的程序
•执行生成的调用并返回相关结果
•可以是专用服务器或共享服务器

image


•专用服务器进程:
      数据库连接与服务器进程之间是一对一对应的
•共享服务器进程:
    多个会话可以共享一个服务器进程池,其中进程由oracle实例生产和管理,你所连接的是一个数据库调度器,而不是特意为该连接创建的专用服务器进程。

•维护并加强物理结构与内存结构之间的关系
–必备的后台进程:
•DBWn (主要负责数据库缓冲区的数据写入到数据文件中)     PMON   (主要负责清理工作)  CKPT (检查点)
•LGWR (体现出:redo缓冲区写到redo log)    SMON  (负责实例恢复,清理临时段)    LREG(12C)
–可选的后台进程:
• ARCn LMDn RECO
• CJQ0 LMON Snnn
• Dnnn Pnnn
• LCKn QMNn




3:DBWN


•将数据库缓冲区高速缓存中 的脏缓冲区写入磁盘;
      –出现检查点
      –脏数据缓冲区达到阈值
      –没有空闲缓冲区
      –执行了 RAC ping 请求
      –表空间处于 OFFLINE 状态
      –表空间处于 READ ONLY 状态
      –对表执行 DROP 或 TRUNCATE 操作
      –对表空间执行 BEGIN BACKUP 操作

image

image



4:LGWR

image





5:SMON

image


6:CKPT


image


7:ARCN

image




8:PMON

image


9:LREG


image







五:Oracle In-Memory

1:In-Memory

包括IM列存储,高级优化查询和高可用性解决方案。在不牺牲OLTP性能情况下,按数量级加速分析查询。
•IM列存储:表、分区以一种特殊压缩列格式复制存储使其能够最优扫描。
IM列存储储存于内存中,该区域是系统全局区域(SGA)的可选部分,不会替换基于行的存储或数据库缓冲区缓存,而是对其进行补充。该数据库使数据能够以行为基础和列式格式存储在内存中,从而提供两全其美的优势。同时IM列存储中填充的对象也不需要加载到DATA BUFFER CACHE中。

image

•高可用性:
       1)在RAC中可以在每个实例中缓存不同对象,也可以相同;
        2)Active Data Guard环境中的备用数据库支持IM列存储。
•高级优化查询:
    1)改进扫描数据的性能
        SELECT cust_id, time_id, channel_id FROM sales WHERE prod_id BETWEEN 14 and 29;
        当使用缓冲缓存时,数据库通常扫描索引以查找产品ID,使用rowid将行从磁盘提取到buffer cache中,然后丢弃不需要的列值。在buffer cache中以行格式扫描数据需要更多CPU指令,并且可能影响CPU效率。
       当使用IM列存储时,数据库只能扫描所请求的销售列,完全避免使用磁盘。以柱状格式流水线扫描数据只需要消耗指定列的cpu,从而提高了效率。
    2)改进连接性能
     内存连接
    3)改进聚合性能
(12.1)数据库提供了VECTOR GROUP BY转换传统的group by以实现高效的内存,基于阵列的聚合


image



2:IM列存储


IM列存储以列式格式对数据进行编码:每列是一个单独的结构。这些列是连续存储的,它们可以进行优化分析查询。数据库缓冲区高速缓存也可以修改填充在IM列存储中的对象。 12.2版本开始可以通过 Alter system 增加,但不能减少; 同时不会动态分配。

image


image





•无论是启用还是禁用IM列存储,数据库缓冲区高速缓存都以相同的方式存储和处理数据块。缓冲区I / O和缓冲池的功能完全相同。
•IM列存储使数据能够以传统的行格式(缓冲区缓存)和列式格式同时填充在SGA中。数据库透明地将OLTP查询(例如主键查找)发送到缓冲区高速缓存,并将分析和查询报告发送到IM列存储。在获取数据时,Oracle数据库还可以从同一查询中的两个内存区域读取数据。



3:IM列存储-内存单元


•IM列存储以最佳的存储单元管理数据和元数据,不是传统的Oracle数据块。
•IMCU:In-Memory Compression Unit
包含数据的一个或多个列的压缩,只读存储单元
列压缩单元
元数据的头
数据库使用内部机制来跟踪更改 并确保IM列存储与数据库的其余部分保持一致, 例如,如果sales表在IM列存储中填充,并且应用程序 更新了一行sales,则数据库会自动保持sales事务上 和IM列存储中表的副本保持一致。

image


•IM列存储将一个对象(表,分区,物化视图)的数据存储在一组IMCU中。IMCU存储一个且仅一个对象的列数据。

image



4:IM列存储-列压缩单元

•列压缩单元用于在IMCU单个列连续的存储。每个IMCU都有一个或多个CU。 CU以rowid顺序存储值。出于这个原因,数据库可以通过将行“拼接”在一起来回答查询。 Eg:首先扫描prod_id列中包含值的条目5。假设数据库在prod_id=5列中找到位置2 。其他也在位置2,缝合行回到一起。 每个IMCU标头都会自动为其CU 创建和管理内存存储索引(IM存储索引)

image








5:IM列存储-SMU

•内存区域的柱状池存储实际数据:IMCU和IMEU。内存区域中的元数据池存储SMU。
每个IMCU都映射到一个单独的SMU。因此,如果列式数据池包含100个IMCU,则元数据池包含100个SMU。SMU为其关联的IMCU存储多种类型的元数据,包括:
      •对象编号
      •列号
     •映射行的信息


image


•每个SMU都包含一个事务日志。数据库使用事务日志来保持IMCU的事务一致性。
•数据库使用缓冲区缓存来处理DML,就像未启用IM列存储一样。例如,UPDATE语句可能会修改IMCU中的行。在这种情况下,数据库将修改后的行的rowid添加到事务日志中,并将其标记为DML语句的SCN。如果查询需要访问该行的新版本,则数据库将从数据库缓冲区高速缓存中获取该行。
•数据库通过合并列,事务日志和缓冲区高速缓存的内容来实现读取一致性。在重新填充期间刷新IMCU时,使查询可以直接从IMCU访问最新的行。







6:IM列存储-进程

为了响应查询和DML,服务器进程扫描列数据并更新SMU元数据。后台进程将行数据从磁盘填充到IM列存储中。
•内存协调器进程(IMCO): 其主要任务是启动填充或重新填充数据进程;
•空间管理工作者流程(Wnnn): 为IMCO填充或重新填充数据;
1.IMCO启动。
2.IMCO确定是否需要填充,包括IMCU中是否存在任何陈旧条目。
3.如果IMCO发现过时的条目,那么它会触发Wnnn进程在IMCU中重新填充这些条目。
4.IMCO过了两分钟,然后返回到步骤1。






7:IN-Memory启用

ALTER SYSTEM SET INMEMORY_SIZE = 10G SCOPE=SPFILE;
重启数据库库;
SQL> SHOW PARAMETER INMEMORY_SIZE











六:In-Memory实际应用

1:实践应用一: 开启 IM 特


-- Step1>查看是否开启IM特性
SQL> show parameter INMEMORY_SIZE

-- Step2>配置参数大小,并设置丌低于100M
--12.1版本不支持动态修改参数文件,12.2版本开始支持(不低于)

 SQL> alter system set inmemory_size=200M scope=spfile;
System altered.
### alter system set inmemory_size=200M scope=both;(spfile,memory); 
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 1073741824 bytes
Fixed Size 2932632 bytes
Variable Size 801112168 bytes
Database Buffers 54525952 bytes
Redo Buffers 5455872 bytes
In-Memory Area 209715200 bytes
Database mounted.
Database opened.
SQL>

SQL> show parameter dump

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
background_core_dump                 string      partial
background_dump_dest                 string      /u01/app/oracle/product/12.1.0
                                                  /dbhome_1/rdbms/log
core_dump_dest                       string      /u01/app/oracle/diag/rdbms/orc
                                                  l/orcl/cdump
max_dump_file_size                   string      unlimited
shadow_core_dump                     string      partial
user_dump_dest                       string      /u01/app/oracle/product/12.1.0
                                                  /dbhome_1/rdbms/log

####警告日志文件:cd /u01/app/oracle/diag/rdbms/orcl/orcl/trace/ 
tail -200f alert_orcl.log
#############如果报错 
SQL> startup
ORA-00838: Specified value of MEMORY_TARGET is too small, needs to be at least 692M
SQL> create pfile='/tmp/inittem.ora' from spfile;
File created.
Vi /tmp/inittem.ora(修改参数memory_target大于1G)
SQL> create spfile from pfile='/tmp/inittem.ora';
File created.
######如果报错 
SQL> startup

ORA-00845: MEMORY_TARGET not supported on this system
image
[root@oracle ~]# mount -o remount /dev/shm 
---执行后重新startup数据库



---实践应用二:关闭IM特性:
---Step1>将INMEMORY_SIZE初始化参数设置为0,并重启数据库
SQL> alter system set inmemory_size=0 scope=spfile;
SQL> shutdown immediate;
SQL> startup



2:实践应用二:关闭IM特性:

---Step1>将INMEMORY_SIZE初始化参数设置为0,并重启数据库

SQL> alter system set inmemory_size=0 scope=spfile;
SQL> shutdown immediate;
SQL> startup








3:实践应用三:对象启用 IM:

以下对象不适用于 IM 列存储中的填充:

  •  索引
  •  索引组织表
  •  哈希集群
  •  由拥有对象 SYS 的用户,并存储在 SYSTEM 或 SYSAUX 表空间,PDBS 级别上也不支持。


如果为 IM 列存储启用表并且它包含以下任何类型的列,则不会在 IM 列存储中填充这些列:

  •  外行列(varrays,嵌套表列和外部 LOB)
  •  使用 LONG 或 LONG RAW 数据类型的 列
SQL> show pdbs;
 CON_ID       CON_NAME                     OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
 2            PDB$SEED                     READ ONLY    NO
 3            PROC1                        READ WRITE   NO

SQL> alter session set container=PROC1;
Session altered.
SQL> create user test identified by test;
User created.
SQL> grant connect,resource to test;
Grant succeeded.
SQL> alter user test quota 100M on users;
User altered.
SQL> create table test.test as select * from dba_objects;
Table created.
---打印执行计划
SQL> set autotrace on;
SQL> select count(1) from test.test;
COUNT(1)
---------- 
90940
Execution Plan
---------------------------------------------------------- 
Plan hash value: 1950795681
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
------------------------------------------------------------------- 
| 0 | SELECT STATEMENT | | 1 | 426 (1)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TEST | 90940 | 426 (1)| 00:00:01 |
------------------------------------------------------------------- 
Statistics
---------------------------------------------------------- 
1 recursive calls
0 db block gets
1530 consistent gets
1527 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
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> alter table test.test inmemory;
Table altered.
SQL> select count(1) from test.test;
COUNT(1)
---------- 
90940
Execution Plan
---------------------------------------------------------- 
Plan hash value: 1950795681
---------------------------------------------------------------------------- 
| 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| TEST | 90940 | 16 (0)| 00:00:01 |
---------------------------------------------------------------------------- 
Statistics
---------------------------------------------------------- 
12 recursive calls
0 db block gets
1544 consistent gets
1527 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
2 sorts (memory)
0 sorts (disk)
1 rows processed
--##########注意此过程涉及第一次填充,强制填充可以使用下面语句 
--########查看填充情况 









COL OWNER FORMAT a10;
 COL NAME FORMAT a25;
COL STATUS FORMAT a10;
 SELECT OWNER, SEGMENT_NAME NAME, POPULATE_STATUS STATUS FROM V$IM_SEGMENTS WHERE SEGMENT_NAME = 'TEST';
---#######强制填充语句 SQL>EXEC DBMS_INMEMORY.POPULATE('TEST', 'TEST');
---####### EXEC DBMS_INMEMORY.POPULATE('用户', '表名');



语法创建:


####创建表启用 im:
CREATE TABLE test_inmem (
 id NUMBER(5) PRIMARY KEY,
 test_col VARCHAR2(15))
 INMEMORY;
#####启用表(MEMCOMPRESS FOR QUERY 和 PRIORITY NONE。)
SQL>ALTER TABLE sh.sales INMEMORY;
#####禁用表
SQL>ALTER TABLE sh.sales INMEMORY;
#####禁用表
SQL>ALTER TABLE oe.product_information NO INMEMORY;
#####
SQL>ALTER TABLE test.product_information
 INMEMORY
 MEMCOMPRESS FOR CAPACITY LOW;
######查看表的压缩模式
SELECT v.OWNER, v.SEGMENT_NAME, v.INMEMORY_PRIORITY,
 v.INMEMORY_COMPRESSION
FROM V$IM_SEGMENTS v
WHERE SEGMENT_NAME LIKE 'P%';
########表多种启用模式
SQL>ALTER TABLE test.test
 INMEMORY MEMCOMPRESS FOR QUERY (
 id, name, category_id, supplier_id, min_price) ####压缩级别
 INMEMORY MEMCOMPRESS FOR CAPACITY HIGH (
product_description, warranty_period, product_status, list_price)
#####优先级别
NO INMEMORY (
weight_class, catalog_url);
#####不在IM列存储 
#########优先级别 
SQL>ALTER TABLE
oe.product_information
INMEMORY
PRIORITY HIGH;
#########表空间启用IM 
SQL>CREATE TABLESPACE users01
DATAFILE 'users01.dbf' SIZE 40M
ONLINE
DEFAULT INMEMORY;
#######启用虚拟列 
SQL> SHOW PARAMETER INMEMORY_SIZE
NAME                                  TYPE       VALUE
------------------------------------ ----------- -----
inmemory_size                         big integer 200M
SQL> SHOW PARAMETER INMEMORY_VIRTUAL_COLUMNS
NAME TYPE VALUE
------------------------------------ ----------- -------
inmemory_virtual_columns string DISABLE
#您向hr.employees表中添加一个虚拟列,然后指定该表是INMEMORY: 

SQL> ALTER TABLE hr.employees ADD (weekly_sal AS (ROUND(salary*12/52,2)));
Table altered.
SQL> ALTER TABLE hr.employees INMEMORY;
Table altered.
#虚拟列hr.employees: 
SQL> ALTER SYSTEM SET INMEMORY_VIRTUAL_COLUMNS=ENABLE SCOPE=SPFILE;
System altered.











二、优先级别:

image


image


三、压缩级别

image

image

SQL> desc  v$im_segments
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                              VARCHAR2(128)
 SEGMENT_NAME                                       VARCHAR2(128)
 PARTITION_NAME                                     VARCHAR2(128)
 SEGMENT_TYPE                                       VARCHAR2(18)
 TABLESPACE_NAME                                    VARCHAR2(30)
 INMEMORY_SIZE                                      NUMBER
 BYTES                                              NUMBER
 BYTES_NOT_POPULATED                                NUMBER
 POPULATE_STATUS                                    VARCHAR2(9)
 INMEMORY_PRIORITY                                  VARCHAR2(8)
 INMEMORY_DISTRIBUTE                                VARCHAR2(15)
 INMEMORY_DUPLICATE                                 VARCHAR2(13)
 INMEMORY_COMPRESSION                               VARCHAR2(17)
 CON_ID                                             NUMBER

SQL> select OWNER ,SEGMENT_NAME ,INMEMORY_PRIORITY ,INMEMORY_COMPRESSION from v$im_segments where segment_name like 'P%';

no rows selected
image


三、连接组优化

image

image


四、相关视图:

image

image




七:缓冲区原理

SQL> create table t as select * from dba_objects;

Table created.

SQL> create index idx_object_id on t (object_id);

Index created.

SQL> set autotrace on;
SQL> set timing on;
SQL> set linesize 1000
SQL> select object_name from t where object_id=29;

OBJECT_NAME
--------------------------------------------------------------------------------------------------------------------------------
C_COBJ#

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 1296629646

-----------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |               |     1 |    79 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T             |     1 |    79 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=29)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


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

SQL> select object_name from t where object_id=29;

OBJECT_NAME
--------------------------------------------------------------------------------------------------------------------------------
C_COBJ#

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 1296629646

-----------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |               |     1 |    79 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T             |     1 |    79 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=29)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
        550  bytes sent via SQL*Net to client
        551  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
---清理缓存区
SQL> alter system flush shared_pool  ;

System altered.

Elapsed: 00:00:00.04
SQL> select object_name from t where object_id=29;

OBJECT_NAME
--------------------------------------------------------------------------------------------------------------------------------
C_COBJ#

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 1296629646

-----------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |               |     1 |    79 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T             |     1 |    79 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=29)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


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

SQL> alter system flush buffer_cache;

System altered.

Elapsed: 00:00:00.05
SQL> select object_name from t where object_id=29;

OBJECT_NAME
--------------------------------------------------------------------------------------------------------------------------------
C_COBJ#

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 1296629646

-----------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |               |     1 |    79 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T             |     1 |    79 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=29)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


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

SQL> alter system flush buffer_cache;

System altered.

Elapsed: 00:00:00.02
SQL> alter system flush shared_pool  ;

System altered.

Elapsed: 00:00:00.01
SQL> select object_name from t where object_id=29;

OBJECT_NAME
--------------------------------------------------------------------------------------------------------------------------------
C_COBJ#

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 1296629646

-----------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |               |     1 |    79 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T             |     1 |    79 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=29)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


Statistics
----------------------------------------------------------
         51  recursive calls
          0  db block gets
        113  consistent gets
        220  physical reads
          0  redo size
        550  bytes sent via SQL*Net to client
        551  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          4  sorts (memory)
          0  sorts (disk)
          1  rows processed






Oracle完整后台进程&内存结构图_00




=================================================================================================

原文地址:https://www.cnblogs.com/ios9/p/10188143.html