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:
-- 查看2k cache、4k cache、16k cache等区域的buffer cache中分配内存大小
show parameter k_cache_size;
-- 如果要创建一个数据块为16k的表空间,需要首先给db_16k_cache_size分配一个大小
alter system set db_16k_cache_size=10M;
-- 然后创建一个数据块为16k的表空间
create tablespace ts_16k blocksize 16k;
-- 之后读取该表空间中的数据,从磁盘读取到内存中时,就会被放到内存的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$…….)
- 基表(user…..)
- 固化表(Xbh)
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下共享进程。