ORACLE BEER WOLF

欢迎来到ORACLE BEER WOLF>>   | 首页 资源中心 | PL/SQL | ORACLE EBS | LIFE | 一般分类 | ITPUB论坛

Oracle Reading Note(六)

发表人:wolfyuan | 发表时间: 2008年一月30日, 00:31

RECO 分布式数据库的恢复

RECO有一个核心的任务, 就是恢复在两段式提交过程中由于崩溃或者失去连接而遗留下来的一些处于准备状态的transaction. 2PC(两段式提交)是一个分布式协议, 它允许那些修改多个异构数据库的动作作为整体提交或者回滚. 它回尽量的减少提交前事务失败的机会. 在多个DB2PC过程中, 有一个数据库, 通常是客户端连接并初始化的那个DB, 会作为一个协调者. 它会询问其它的数据库是否准备好提交, 其它数据库会报告它们的准备状态, Yes or No, 只有所有的DB都回答Yes, 这个事务才能提交, 否则就需要Rollback.

在某些情况下, 其中一些DB报告了Yes, 但是在它得到提交的指令之前, 由于网络失败或者其它某些错误, 这个事务就处于一种不确信分布式状态”, 2PC会尽量减少这种事情的发生, 但是不能完全避免, 当这个时候, 确实有某些错误发生, 这个事务就必须由RECO来处理了, RECO会试图连接那个协调者, 分析其状态, 在它联系到协调者之前, RECO必须要保持这个事务的状态, 既不回滚也不提交.

我们应当知道, 如果这种状态维持时间太长, 我们可能需要手动去提交或者回滚. 因为要知道这些状态的事务会导致写阻塞读”, 这是Oracle里面唯一发生这种状况的时候. 当发生这种状况的时候, 你们的DBA就需要联系其它DBA, 查询这些事务的状态, 然后决定提交或者回滚, 来释放RECO的任务.

CKPT check point进程

CKPT并非如其名字那样, check point的动作(将脏数据写回磁盘), 它只是协助执行check point动作的进程DBWn更新数据文件的文件头, 在以前CKPT只是一个可选的进程, 但是从8.0, 这个进程一般都启动了. 更新数据文件头的动作以前是LGWR的任务, 但是随着文件数量的增多, 这个任务成了LGWR的负担, 于是CKPT将其接了过来.

DBWn Data Base Block Writer

DBWn是负责将缓存中的脏数据写回到磁盘的后台进程. 这个进程的Performance这关重要, 因为如果这个不够快, 我们将看到很多”FREE_BUFFER_WAITES”, “Write Complete Waites”.

我们配置多于一个DBWn进程, 实际上可以多到10, 如果配置多个DBWn, 不要忘了DB_BLOCK_LRU_LATCHES参数.

通常情况下, DBWn做的是异步读, 与操作系统文件读写进程异步, 可以增进performance.

DBWn进程进行的是随即读写, LGWR进程进行的是连续读写.

LGWR进程

LGWR进程进行的顺序写, DBWn进行的随即写要快很多, 这就是为什么以开始就设计成重做日志, 而不是直接将数据写到磁盘, 前台LGWR进程进行快速的顺序写, 后台DBWn进行缓慢的随机写, 这就使Oracle Performance的关键.

ARCn 存档进程

ARCn进程的任务就是将在线重做日志拷贝到另外的位置, 作为归档日志. 主要是为了防止磁盘毁损或者其它意外的数据丢失.

BSP进程

BSP主要运行与OPS环境下, OPS指多个instance挂载同一个数据库. 通常情况下, 是运行于集群内不同机器上的instance读写同一个数据库. 这样必须保证各instance SGA Block buffer内数据的一致性. 这就使BSP进程的主要目的. OPS的早期版本, 这是通过’PING’来完成的.

LMON进程

LMON进程监控OPS环境下所有的instance, 检测某些instance的故障.OPS环境下某一个instance挂掉了以后, LMON需要与DLM(分布式锁管理器)一起来管理遗留下来的全局锁.

LMD

LMD也是运行在OPS环境下, 主要用来管理集群内的对于block buffer的全局锁以及全局资源. 其它进程可能会像本地的LMD发出请求, 请求release某些锁或者找出是谁锁住了, LMD同时还要处理全局死锁.

LCKn

LCKn的作用与LMD很像, 不同的是, 它管理的是对所有的全局资源的请求而不是block buffer.


Oracle Reading Note(五)

发表人:wolfyuan | 发表时间: 2008年一月18日, 01:15

后台进程

后台进程分为2, 有专一任务的, 以及能够执行多种任务的.

UNIX环境下面, 我们通过PS命令就可以很容易看到后台运行的ORACLE进程, 但是在Windows下面却每这么简单, 因为Window下面它们是以线程的方式出现的, 分布在一大块内存里面, 属于唯一的一个进程Oracle.exe.

PMON, 进程监控器

这个进程主要负责连接断开后的清理工作. 例如, 某个专注服务进程失败, PMON会负责释放资源, 回滚transaction, 释放锁, 释放SGA资源等. 除了清理工作, PMON还负责监控其它后台进程, 并且在必要的时候重启它们. 例如如果一个共享服务器或者分发器失败, PMON就会介入, 清理失败进程后将它们重启. PMON会监控这其它进程, 并且在合适的时候重启或者结束掉它们. 例如, 当写日志的进程失败, PMON就会重启Instance, 因为这是非常严重的错误.

PMON的另外一个任务就是向NET8 Listener注册Instance, ini.ora文件中的LOCAL_LISTENER参数可以控制该Instance的在哪个端口监听.

SMON, 系统监控器

SMON做的事情是其他人都不愿意做的, 它被成为Oracle捡垃圾的人”.

它的工作主要有:

1. 临时空间清理, 随着真正的临时表空间的使用, 这种工作在减少, 但并没有消失. 例如, index的时候, 那些被分配的索引extent会被标记为Temporary, 一旦出错, 这些extent就需要被清理. SMON还负责清理一些其它进程产生临时extent.

2. 崩溃的恢复

3. 自由空间的连接

如果你使用的是字典管理表空间, SMON就需要负责将table space中未使用的extents连接起来, 形成一个大的区域. 这仅仅在字典管理表空间并且存储参数PCTINCREASE设为了非零值.

4. 对于文件不可得的transaction活动恢复

在数据库down掉进行恢复的时候, 可能由于文件不可得而跳过, SMON就负责这种恢复工作

5. OPS失败节点的恢复

OPS中某一个节点down, 其它节点会使用down掉节点的重做日志, 进行数据恢复工作

6. OBJ$的清理

OBJ$是一个底层的数据字典表, 这个表中可能会包含很多无用的object信息, SMON就负责清理掉它们

7. 回滚段的收缩

8. 脱机回滚段管理

DBA有时候会手动使一些回滚段脱机, 但是这些回滚段可能存在活动的事务, 这个时候, 这些回滚不会真正脱机, 而只是标记为Pending Offline, SMON需要尝试将它们真正脱机.

SMON周期性的启动或者被其它进程激活来做家务.


Oracle Reading Note(四)

发表人:wolfyuan | 发表时间: 2008年一月16日, 01:05

进程

Oracle进程主要分为3,

服务进程, 服务与客户端请求的进程

后台进程, Oracle启动一起运行, 执行一些维护型任务

附加进程

服务进程

我们知道Oracle Server可以有两种运行模式, 专注模式与共享模式

在专注模式下, 客户端进程与服务器端进程有一个一对一的关系, 二者之间通过NET8进行连接(服务器端的Listener进程), 在服务器端进程接受到客户端查询请求, 则进行Parse, 有可能的话会在Share Pool中找到已ParseSQL, 执行, 读取block, 可能从block buffer也可能从磁盘, 然后返回给客户端.

这种两层架构好处很明显:

1. 可以远程执行

2. 地址空间的隔离, 如果二者地址空间相连, 则客户端进程的错误很容易导致服务器进程的异常.

但实际情况下是不一定需要NET8, 即当客户端与服务器端同在一台server上时, 我们不需要启动Listener服务, 我们的sqlplus就可以访问数据库, 这个时候我们可以看到, 是有sqlplus的进程创建了dedicated server的进程. 共享模式则必须有NET8的存在.

专注服务 VS 共享服务

下面我们来讨论一下这两种运行模式.

oracle默认是以专注模式运行, 如果需要以共享模式运行, 可能需要一些额外的步骤, 但是二者的主要区别却不在这里. 因为使用专注模式, 客户端请求与服务进程是一对一的, 而共享模式却是多对一的情况, 所以在使用共享模式的时候, 你必需要很小心不使你的请求长期占用服务器的某一资源, 因为这样会使其它的请求挂起. 所以, 使用共享模式的首要规则就是你的操作不能过长, 频繁不要紧. 所以OLAP系统将很适合使用共享模式.

OLAP情形下, 共享模式主要有以下好处,

1. 减少服务进程, 因为如果并发很多的话, 使用专注模式将使服务器端产生过多的服务进程. 例如说我可能有5000个并发的user, 但是同意时间活动的user肯能只有50, 这样, 我们指需要50个共享进程就可以达到专注模式的效果

2. 我们可以人工减少并发带来的performance下降

测试发现, 当我们增加并发user的时候, 数据库每秒处理的transaction数量开始会上升, 然后趋于平稳, 当并发user达到一定数量的时候, transaction数据又会下降, 这个时候的user数量就是当前服务器状况下所能容纳的最大并发数. 知道了这个限制, 我们就可以采取措施, 努力使并发保持在这个限制以下, 或者改善服务器, 增加共享进程.

3. 减少系统需要的内存

因为在共享模式下, UGA是包含在SGA, 所以可能导致SGA很大. 而在专注模式下, 每个session的很多内容都是保存在各自的进程中. 既然这部分内存都是需要的, 至少分配在哪的关系, 那么从哪减少呢? 以上面的案例来说, 当使用共享模式的时候, 我们相当于省下了剩下的4500session分配的内存.

建议, 除非有特殊原因要用共享模式, 一般还是推荐用专注模式, 因为专注模式很简单, 并且tuning也相对容易. 使用共享模式, 一定要多进行测试, 找出你的允许最大并发量. 万一你还有耗时过长的操作, 你还可以尝试使用AQ(Advanced Queue)来将长的操作换成短的操作.


Oracle Reading Note(三)

发表人:wolfyuan | 发表时间: 2008年一月15日, 23:50

Share Pool

共享池是SGA一个至关重要的组成部分, 这是Oracle缓存程序数据的地方, 主要可能有以下几个部分:

执行计划(parse query的结果), 系统参数, 数据字典缓存. 而与开发者关系最大的就是第一部分, 我们提倡的就是尽量多的使用绑定变量, 这样Oracle才能更多的使用共享池中的重用SQL, 从而提升performance. 要尽量少使用hard codedSQL.(这点至关重要)

Ini.ora中与此相关的参数有:

CURSOR_SHARING, SHARED_POOL_SIZE

通常

select sum(bytes) from v$sgastat where pool = shared pool;

看到的结果会比

show parameter shared_pool_size

看到的要大, 这是因为前者还包含一些其它的部分, 这里不讨论.

Large Pool

Oracle8i以前, 所有的程序内存分配都是放在share pool中做的, 但是有时候我们需要分配大片的内存, 但是又不想share pool中那样, 能够被重用, 这时候, 就不适合用share pool来管理了, Large Pool就是引入用来达到这个目的的. 我们可以看到Large PoolShare Pool的关系有点类似于Block BufferRecycle PoolKeep Pool的关系.

Large通常会在以下几个情形下用到:

MTS, 并发, 备份

如果DBWn_IO_SLAVES或者PARALLEL_AUTOMATIC_TUNING

这两个参数有设置, Large Pool的会默认有一个大小, 通常推荐手动Large Pool的大小, 因为默认的通常不适合你自己的情况.

JAVA POOL

Java Pool是最新才出现在Oracle SGA中的pool, oracle的不同运行方式下, Java Pool会包含不同的内容. 在专注服务模式下, Java Pool包含所有Java类的共享部分, 这些部分实际上会被每个session用掉. 所以在专注服务模式下, Java Pool的大小大致可以由我们可能会用到的Java类的数量推断出来. 需要注意的是在专注服务模式下, SGA中不会有每个session所特有的那些信息, 那些会包含在UGA, 而在专注服务模式下, UGA又是PGA的一部分

MTS模式下, Java Pool包含有

1. Java类的共享部分

2. UGA的一部分, 用来存储session特有的状态

注意到在MTS模式下, Java Pool由于包含有一些跟session相关的内容, 所以随着并发session的增大, Java Pool可能变得很大.


Oracle Reading Note(二)

发表人:wolfyuan | 发表时间: 2008年一月15日, 00:18

内存结构

3种主要的内存结构

SGA, System Global Area

PGA, Process Global Area

UGA, User Global Area, 存在于SGA(MTS模式)种或者UGA(专注服务模式)

PGA是一个ORACLE进程专属的内存区域, 它不能被其它的进程访问. PGA绝对不会超过SGA的区域.

UGA事实上就是你的session状态, 你的这个session可以访问的内存区域. UGA的位置取决于你配置的Server怎样接受连接, 如果是MTS模式, 那么UGS必须在一个所有用户都可以访问的内存区域中, SGA, 如果是专注服务模式, 那么UGS就基本等于PGA.

PGAUGA二者在大小上的差别最大之处应该取决与ini.ora或者是session级别的参数: SORT_AREA_SIZE, SORT_AREA_RETAINED_SIZE. 这两个参数控制了ORACLE在将数据写到磁盘之前用来排序数据的内存空间大小, 以及排序完毕以后由多少内存段依然保留. SORT_AREA_SIZE将会将会被分配在PGA里面, SORT_AREA_RETAINED_SIZE则在UGA.

exec dbms_session.free_unused_user_memory;强行释放内存

SGA

每个ORACLE实例都会有一大块的内存, 称为SGA, 这块内存区域所有的ORACLE进程都可以访问. UNIX环境下, 可以实实在在的看到这么一大块内存, 但是在WINDOWS环境下, 这块内存是依附于ORACLE.EXE进程下的. 我们可以通过数据字典V$SGASTAT大致查看SGA.

SGA可以分为以下几个区域:

JAVA: 为数据库的java虚拟机分配

大池: MTS用来管理session内存, 并发时候的消息缓冲, RMAM的磁盘缓冲

共享池: 共享游标, 存储过程, 实体状态, 字典缓存

其它: block buffer, redo log buffer, ‘fixed SGA’

ini.ora文件中对SGA影响最大的几个参数分别是:

JAVA_POOL_SIZE

SHARED_POOL_SIZE

LARGE_POOL_SIZE

DB_BLOCK_BUFFERS

LOG_BUFFER

除了SHARED_POOL_SIZE, LOG_BUFFER以外, ini,ora中参数值于实际内存中相应SGA区域的大小是一一对应的.

Fixed SGA

Fixed SGASGA的一个固件, 并且随着大小随着平台以及版本的不同而不同, 其中存储的是一系列的变量以及指向SGA其它部分的指针. Oracle安装的时候这部分就已经固定下来, 我们可以将这一部分看作是SGA引导区”.

Redo Buffer

Redo Buffer (Redo Log Buffer, Log Buffer)

那些需要贝写到在线重做日志的数据在写到磁盘之前会临时保存在这个区域中, 数据不会在这里存太久, 在以下情况中, Redo Buffer中的内容会被刷新到在线重做日志中:

1. 3

2. 有人commit

3. 达到1/3满或者缓存了1M以上的重做数据

所以数10MRedo Buffer通常是浪费内存, 因为根本不会被用到.很少有系统需要用到几M以上的Redo Buffer

Redo Buffer的默认大小(ini.oraLOG_BUFFER参数控制), 512K(128K * cpu数量)中的较大者, 最小值是当前操作系统支持的最大block大小的4.

select * from v$sgastat where name = ‘log_buffer’;

可以看到这个大小, 但是其实际大小:

select * from v$sga where name = ‘Redo Buffers’;

可能会稍微大一点.

因为它需要一些额外的空间来保护其自己.

Block Buffer Cache

这是SGA中一块最大的区域. 这个区域中通常管理着两个列表, “Dirty”(脏数据, 未写到磁盘)以及”No Dirty”(未更改的数据), “No Dirty”的算法比较复杂, 通常是最近用到的以及比较多用到的会比较靠前, 有一个”Touch Count”的概念, 我们可以在一些X$表中看到相关的缓存block信息.

X$BH表中的tch指的就是这个Touch Count.

Oracle8i以前整个Block Buffer就是一大块, 没法再分开. 但是后来添加了一个”Multiple Buffer Pool”的特性. 利用这个特性, 我们可以开辟出一块指定的空间来缓存我们制定的一些segment, 在这个区间中的block, 指会与制定的那些segment竞争, 而不需要与普通的data block竞争.我们称这一部分空间为Keep Pool. 另外, 我们还可以开辟出一块空间”Recycle pool”, 这块空间中的block管理机制与其它的不同, 其它pool我们都是保存最近使用最多的block, 而在这块空间中, 会尽快的淘汰那些没有使用的block. 这种机制对于那些大但又很少会读到的table很有用处, 因为将它们单独管理, 可以避免它们将那些其它的block buffer中的block冲掉.


Oracle Reading Note(一)

发表人:wolfyuan | 发表时间: 2008年一月08日, 00:12

第二章 架构

ORACLE架构由3部分组成: 文件, 内存结构, 物理进程

SERVER:

数据库与实例的概念:

一个数据库可以同时被多个实例挂载或者打开

一个实例在任何时候只能打开一个数据库

实例每次启动的时候, 不一定每次都打开的是统一个数据库

实例就是一系列的操作系统进程以及内存,而数据库是由一系列的文件组成(数据文件,临时文件, 重做日志文件, 控制文件)

大多数情况下, 数据库与实例是一对一的关系, 但是在OPS(ORACLE PARALLEL SERVER)情况下, 可能存在多个实例对应一个数据库的情况。

SGA, UNIX来说, 可能实际分配一大块物理内存, 这块内存可以被很多程序并发访问。

而在windows环境下, 可能仅仅使用C程序malloc()函数分配一大块内存, 这块内存是实际属于某一个进程的.

ORACLE实例的进程, 我们在Unix下面, 使用PS命令可以看到很多后台进程, ORACLE启动一直到结束。但是, 它们仅仅只是进程, 不是程序, UNIX上面只有一个ORACLE程序。 WINDOWS, 我们只会看到一个进程ORACLE.EXE, 但是我们却能从其中找到很多线程代表不同的ORACLE进程。

ORACLE Instance服务外部请求有两种方式, 专注示与共享式, 在专注式的情况下, 每一个用户登陆, oracle都会为期创建一个进程, 用来为其服务。 而在共享式的情况下, 可能是一个服务器进程服务多个客户端请求。

二者的主要区别是, 在共享式的情况下, 会有一个专门的Dispatcher的进程, 用来分派客户端的请求, 当一个请求送达, Dispatcher会将其放到SGA的一个请求队列中, 当这个请求到达第一位的时候, 会有首个空闲的共享服务器进程来处理, 处理完毕以后, 同样把处理结果放到一个应答的队列当中, Dispatcher将结果取回并传回给客户端.

文件:

ORACLE实例相关的是参数文件,

组成数据库的文件有: 数据文件, 重做日志文件, 控制文件, 临时文件, 密码文件。

最重要的是数据文件以及重做日志文件

参数文件: 有很多种参数文件, 最重要的就是数据库参数文件(init.ora), 一般默认名称为:

init<ORACLE_SID>.ora

这个参数文件中有很多对数据库至关重要的配置参数.

有两类参数, 有文档记载的以及一些以’_’开头的隐藏参数, 一般情况下, 不推荐使用这些参数, 尽管有些时候可能会带来某些好处, 但是大多数情况下,