Oracle实例

Oracle数据库主要分为两部分:

  • 静态存储结构(数据文件、参数配置文件、控制文件等)
  • Oracle实例(内存结构、后台进程)

内存

内存的划分:

  • SGA(System global area)

    SGA区包括Oracle实例需要的一系列内存组件,用于存放数据信息和数据控制I信息,比如 buffer cache,shared_pool,log buffer….

    这些内存信息被所有进程所共享(server process,background process)

  • PGA(Program global area)

    不同于SGA,PGA属于独占式内存区,它的数据和控制信息为某个会话所独有。当一个会话产生时,Oracle会为这个会话分配一个PGA内存区域。

    PGA属于单个的服务端进程或者后台进程,而实例级别说的PGA,通常指的 是所有这些会话占用的PGA的总和,也就是由参数 pga_aggregate_target设置的值。

  • UGA(User global area)

    UGA区属于SGA和PGA中的一部分,有时候属于SGA,有时候属于PGA。

    UGA中保存和当前会话相关的信息,比如pl/sql的变量、绑定变量的值或者其他和当前会话相关的信息。

  • Software code area

    这是Oracle存放自身软件代码的一部分内存区,不允许其他会话访问

SGA区

大致分为:

  • Database Buffer Cache
  • Redo Log Buffer
  • Shared Pool
  • Large Pool
  • Java Pool
  • Streams Pool
  • Fixed SGA

    SGA维护自己内存结构的区域

Database Buffer Cache

存放着从磁盘上读到内存中的数据块,这些数据块可以被所有的会话访问,是全局共享的。

其中又可以分为:

  • Default pool

    正常情况下,数据块存放的内存区域

  • Keep Pool

    这个区域(池)用于将一些数据始终固定在内存中。

    default pool 会根据一个过期算法(LRU)将过期的脏数据写到磁盘上。

  • Recycle pool

    存放一些不经常使用的数据块,避免这些数据块在Default Pool池中占据空间。

  • 2k cache,4k cache,16k cache

    这些区域用于存放不是标准大小(8k)表空间的数据块信息。

    相关SQL:

  1. -- 查看2k cache4k cache16k cache等区域的buffer cache中分配内存大小
  2. show parameter k_cache_size;
  3. -- 如果要创建一个数据块为16k的表空间,需要首先给db_16k_cache_size分配一个大小
  4. alter system set db_16k_cache_size=10M;
  5. -- 然后创建一个数据块为16k的表空间
  6. create tablespace ts_16k blocksize 16k;
  7. -- 之后读取该表空间中的数据,从磁盘读取到内存中时,就会被放到内存的16k cache区域

buffer的概念:在 database buffer cache中,一个buffer指的是用来从磁盘中读入的数据库在内存中的存放位置,可以理解为 1 buffer = 1 block

buffer(内存数据块)的3种状态:

  • unused

    这个buffer是空的,从来没有用过

  • clean

    这个buffer中有一个数据块,但是这个数据块已经没有用了,可以直接覆盖掉。

  • dirty

    这个buffer中有一个数据块,这个数据块被修改过,称为脏数据块

buffer的访问(内存中数据块的访问)的2种模式:

  • Current mode

    当前模式:一般是DML中的增删改操作,因为要修改的数据块需要修改数据块的当前状态。

    从数据库中读取了一个数据块,A进行了修改,B再修改时应该是对A修改后的当前状态的修改。

    当A在进行修改时,B不能同时进行修改,所以当前模式中会有锁阻塞。

  • Consistent mode

    一致性模式:select时候用的该模式。

    select时不一定要读取当前状态,所以不使用当前模式。

    例如:A用户在12:00发出了一条SQL查询test字段,B用户在12:01时将test字段值由1改成了0。oracle处理A用户的SQL时,于12:02才扫描到指定的test字段的数据块,此时该数据块的当前状态已经被改成了0,oracle应该通过rollback回滚段获取test数据块在12:00时间的值1,将1返回给A用户。这样就保证了查询的一致性,12:00时间查询返回的内容为12:00时间的值。

Redo log buffer

Redo log buffer 中存放着数据库产生的redo数据。

redo log buffer 以循环的方式写入,当redo log 已经写到磁盘后,就可以被后续的日志数据覆盖。

该内存区域主要关注的是设置的redo log buffer的大小。

Shared Pool

SQL执行时用来存放SQL的内存区域。

主要分为:

  • Library Cache
  • Data Directionary Cache

    字典区

  • Server Result Cache

    结果集保留区(SQL查询结果集缓存、PLSQL函数结果集缓存等)

  • Reserved Pool

    保留区域,为了维护shared pool的内存结构。

Library Cache:如果优化Shared Pool,最重要的就是优化Library Cache。

可以理解为Library Cache中存放着SQL语句(不是直接的文本SQL,是Hash_value)。

Library Cache里面保存着可执行的SQL及PL/SQL包,以及SQL的执行计划和一些控制结构(比如锁)。

当一条SQL语句被执行时,Oracle尝试到Library Cache中查找是否有相同的SQL(通过Hash_value)。如果有,将直接重用存在的SQL的信息(执行计划),这个称作软解析(Soft pase)或者叫做library cache hit;反之,SQL将被重新解析,这个过程称为hard parse或者 library cache miss。

一个SQL的解析需要消耗一些CPU,对于OLTP这类有大量的SQL要解析的数据库,重用执行计划是很有必要的。

Library cache分为:

  • Shared SQL Area

    共享SQL区(SQL Statement、执行计划、编译单元等)

  • Private SQL Area

    属于UGA

v$sql等系统视图中列出的sql就是 Shared SQL Area中的记录。所以如果数据库重启或者sql被踢出共享SQL区,那么这条SQL就无法在系统视图中找到了。

Data Dictionary Cache:数据字典区,不需要优化。

数据字典区存放Oracle的数据字典信息,这些信息包含数据库中对象的数据信息、结构信息等,这些信息在SQL解析的过程中需要频繁的被访问到。

主要有:

  • 视图(dba/all/user_tables …..、 v$…….)
  • 基表(user02-内存结构和后台进程 - 图1…..)
  • 固化表(X02-内存结构和后台进程 - 图2bh)

    x$bh会经常用到,存放的是数据块头(Block Header)信息。

Server Result Cache:

这部分内存中保留了SQL查询的结果集,这样对于后续的相同查询,Oracle无需重新加载数据块进行计算,直接使用现有的数据集。

结果集是否保留由参数 RESULT_CACHE_MODE 设定,该参数默认值为 Manual(未启用),需要使用 RESULT_CACHE hint来强制对某条Select启用。

该参数可以设置为FORCE(不建议),这样会对所有select操作生效,但是会消耗更多的shared_pool空间。

对于PL/SQL函数,对结果进行缓存。

Shared Pool是OLTP数据库性能优化的一个重要考察区域:软分析、硬分析、变量绑定….

Library Hit命中次数、Soft Parse %软分析比例、% Non-Parse CPU CPU时间内不是用于SQL分析的比例

Large Pool

Large Pool对数据的处理不使用LRU算法,比 Shared Pool 更高效的内存收取方式:

  • 在 MTS 模式下 UGA 会放在 Large Pool
  • 并行执行时会使用 Large Pool
  • Rman备份时启动并行备份方式时,使用 Large Pool

Streams Pool

Streams Pool 里面存放着流相关的信息,比如流队列信息,同时也为流复制中capture进程提供进程内存空间。

Streams Pool 只为流复制提供内存空间,如果没有手工配置,也没有配置流复制,这个空间将设置为0。

SGA其他组件

Java Pool:用于保存会话运行的java代码和信息,比如java类、方法….

Fixed SGA:

  • 保存通用的数据库和实例状态信息
  • 保存实例间通讯需要的结构,比如锁
  • 大小通常改变很小,无法手工改变

查看SGA相关信息:show sga;

响应内容:

Total System Global Area 1071333376 bytes    # SGA整体大小
Fixed Size                  1375792 bytes    # SGA固定的大小
Variable Size             897581520 bytes    # Shared Pool的大小
Database Buffers          167772160 bytes    # Database Buffer大小
Redo Buffers                4603904 bytes    # Redo Buffer大小

PGA区

PGA(Program Global Area)。

PGA主要由:SQL Work Areas(SQL工作区)和 UGA区 组成。

SQL Work Areas分为:

  • Sort Area

    用于数据排序。

    数据排序是在PGA区,不再SGA区

  • Hash Area

    Hash运算区域。

    Hash Join等

  • Bitmap Merge Area

    Bitmap索引区

UGA区分为:

  • Session Memory

    Session相关信息(session的游标、变量等)

  • Private SQL Area

    私有SQL区

private SQL Area 分为:

  • Persistent Area
  • Runtime Area

UGA区

UGA(User Global Area):保留了一点会话的信息。

UGA分为:

  • Session Variables

    登录信息、变量值、pl/sql参数…

  • OLAP Pool

    OLAP维度对象,比如cube

对于普通的连接(专有连接 Dedicated Server,一个客户端过来,oracle对应在PGA分配一个连接),UGA存放在PGA区,属于PGA的一部分。

Oracle另外还有一种 Shared Server模式(称为 MTS,类似于中间件提供的连接池)。Oracle在共享区中开辟一块区域作为连接池,叫叫做MTS,用户连接过来时,oracle通过分发器 Dispatcher Process 对应到共享的MTS中。因为连接池里的内容需要共享,所以这时候UGA不能放在PGA中,而是存放在SGA的 Large Pool中。

大多数时候,oracle数据库是普通的专有连接,UGA作为PGA的一部分。

PGA 和 UGA 区别:

PGA 是一个进程占用的内存区域,可以理解为操作系统在一个进程启动时,为它分配的内存空间,是一个操作系统含义上的内存区。

UGA 是一个会话含义的内存区,它保存着和会话相关的信息,比如会话登录信息、绑定变量的值、pl/sql包的参数信息等。

  • UGA必须保证会话能够访问到UGA当中的数据,因此UGA的位置会随数据库连接方式的不同而不同
  • 当连接使用的是专用模式(dedicated)时,因为会话是专有的,所以UGA属于PGA的一部分
  • 当连接模式为MTS时,由于会话可能会使用任意一个共享线程,因此这些进程必须能够同时访问UGA中的数据,此时Oracle会把UGA放在SGA区中(共享内存区域)。

SGA区 和 PGA区 区别

SGA的目的在于数据的共享,它的特点是:

  • 数据并发访问
  • 锁定和队列机制( latch、Lock…)
  • 对OLTP类型数据,是一个常见的性能瓶颈区
  • 是一个数据库优化经常关注的区域(data buffer hit、 library hit(hard parse, soft parse)、hot blocks….

PGA是为专有进程服务的,进程间无法进行数据共享,它的特点是:

  • 数据独占性
  • 无需锁定机制
  • 性能优化上只需考虑它的大小

进程

Oracle的进程:

  • 用户进程(User Process)
  • 服务器进程(Server Process)
  • 实例后台进程(Background Process)

客户端发出一条SQL时,客户端会出现一个用户进程。

当客户端发出一条SQL时,服务端也会开启一个服务器进程用来接收客户端请求的SQL,然后进行执行返回。

实例后台进程是Oracle自己固有的进程,用来维持实例正常工作。

Oracle的后台进程和Oracle版本、启用的oracle特性有关,查看Oracle进程:

select * from v$session where program like 'ORACLE.EXE%';
select * from v$bgprocess;

Linux下:

ps -ef | grep ora_ | grep -v grep

SMON进程

SMON的主要工作:

  • 数据库启动时的实例恢复,在RAC环境下,一个节点的SMON可以对另外一个节点做实例恢复

    实例恢复是一个自动的过程。

    RAC环境下,redo是共享的,所以一个节点可以通过redo对另一个节点做实例恢复

  • 清理和释放临时段上的数据(排序、临时表…)
  • 对于DMT(字典管理表空间),SMON可以合并连续空闲的extent
  • 维护回滚段的online/offline,以及空间的回收

PMON进程

PMON后台进程负责的一些异常情况的善后工作:

  • 进程异常终止
  • 会话被杀掉
  • 事务超过空闲时间
  • 网络连接超时
  • 将实例信息注册到监听器上

实例注册到监听器:以前的oracle启动依赖于 listener.ora文件,实例需要配置到该文件中。从oracle 9i 开始,实例可以动态进行注册,即使没有 listener.ora,oracle也可以自己将实例注册到监听器上,这个操作依赖于PMON进程。

除了PMON自动进行实例注册外,也可以将实例手工注册到监听器:alter system register;

PMON进程的善后工作中,主要清理的内容:

  • 回滚未提交的事务,释放事务相关的资源
    • 重置undo数据块上的事务表的状态为 inactive
    • 释放事务产生的 TM锁、TX锁
    • v$session中清除异常终止的会话ID

      清理终止的会话时,可能并不会直接从v$session中进行删除。而是先将该会话的状态标注为killed,等待该会话的相关资源被释放之后,再将其从会话中真正删除。

DBWn进程

主要工作:负责将 buffer cache 中脏数据块(修改过的数据)写到磁盘上,由于数据块在磁盘上的位置不连续,这个过程会比LGWR耗时更多。

DBWn触发条件:

  • 当server process在buffer cache中无法找到可用的buffer时

    buffer cache是一个列表,里面的数据按照使用是否频繁进行排序。向磁盘写入时,先写入那些使用不频繁的数据。

  • DBWn接到CheckPoint的指令时

可以通过设置多个DBWn进程加快脏数据写入磁盘的速度:DB_WRITER_PROCESSES

CKPT进程

CheckPoint的目的:

  • 减少数据库实例恢复的时间

    数据库宕机恢复时,会从最近的检查点开始恢复

  • 让内存中的脏数据及时的写到磁盘上
  • 在安全关闭数据库时,保证所有提交的数据被写到磁盘上

CheckPoint的触发条件:

  • DataBase CheckPoint(数据库级的检查点)
    • Consistent database shutdown(安全的进行一致性数据库关闭)
    • ALTER SYSTEM CHECKPOINT statement(使用alter system checkpoint指令,人工触发检查点)
    • Online redo log switch(日志切换,此时涉及到日志文件的覆盖,需要将日志中数据写入磁盘上)
    • ALTER DATABASE BEGIN BACKUP statement(使用alter database begin backup指令进行数据库备份,在oracle 8i 时用的多)
  • Taablespace and data file checkpoints(表空间级的检查点)
    • tablespace read only(将表空间设置成只读,设置成只读后表空间不允许修改,所以此时会先触发一次检查点,将表空间最后的数据都写入)
    • tablespace offline normal(表空间正常下线时)
    • shrinking a data file(收缩数据文件,涉及数据块移动,移动后数据块地址发生改变。如果不将内存中数据写入磁盘,则内存中数据将指向错误的磁盘地址)
    • alter tablespace begin backup(表空间备份)
  • Incremental checkpoints(增量检查点)

    数据库中有很多脏数据,一次只将部分脏数据写入磁盘,这样多次进行,每次增量写入,避免一次写入磁盘数据过多而占用IO)

CKPT进程并不会直接将内存中的数据写入磁盘,而是通知 DBWn进程开始将内存(Buffer cache)中的脏数据写到磁盘文件上,通知之后CKPT会再次进入idle等待状态。

CKPT负责更新数据文件的文件头和控制文件信息。在数据文件的文件头中打上一个标签,标记一个类似于当前checkpoint流水号,在该编号之前的数据oracle认为已经被写入磁盘,是安全的。为了防止数据文件文件头损坏,也会在控制文件上存入一个时间戳,用于和数据文件的文件头做比对。

LGWR进程

LGWR负责将 log buffer中的数据顺序的写到磁盘上的 online redo file,由于是顺序的写入,效率要比 DBWn 高很多。

LGWR触发条件:

  • 用户提交事务(commit)
  • 日志切换
  • 最后一次提交经过了3秒,防止内存中存储过多的redo log buffer
  • redo log buffer 容量达到 1/3 或者达到 1M 的redo数据
  • DBWn 进程在把脏数据写入磁盘之前,必须保证这些脏数据对应的日志信息已经被写入磁盘。如果发现脏数据的日志信息没有写入磁盘,DBWn通知LGWR进程写日志信息,LGWR完成后DBWn继续将脏数据写入磁盘。

Checkpoint 和 commit的区别:

commit提交的事务修改的数据产生的日志,必须立即写到磁盘上。-

checkpoint将脏数据写到磁盘上,加快数据的恢复时间,为 data buffer提供空闲空间。

  • 写到磁盘上的数据,并不一定是提交的
  • 数据写到磁盘之前,这部分数据对应的日志信息,必须提前写到磁盘上
  • 如果是 alter system checkpoint,将只把commited的数据块写到磁盘
  • 安全关闭数据库,所有的commited的数据会写到磁盘上

ARCn进程

归档进程,当数据库处于归档模式时(archive mode),ARCn负责将 online redo file 归档到目标存储位置,用于数据库的恢复,当在线日志切换时,会触发 ARCn进程将在线日志文件归档。

ARCn 进程在 Data Guard 下,负责将日志向Standy服务器发送。

其他后台进程

ASMB:ASM实例的核心后台进程,负责管理ASM的存储。

CJQ0:job任务协调进程,负责数据库中JOB的自动执行。

Jnnn:job具体执行进程,接受CJQ0分发的job任务。

MMAN:内存管理进程,负责内存的动态管理、分配和收回。

Pnnn:并行执行子进程,接受并行协调进程分配的任务并执行。

RBAL:ASM的rebalance进程,负责ASM数据的rebalance操作。

例如ASM本来有10T存储,现在增加5T,RBAL会将数据在这15T存储中做一次再平衡操作,均匀分布在这15T中。

RECO:分布式事务的恢复进程。

不同于普通的数据库恢复,普通数据库实例恢复使用的是SMON。

RECO主要针对分布式,例如两台数据库使用dblink相连,做成分布式,如果其中一个会话失败,需要对整个分布式做恢复。

Snnn:MTS下共享进程。