第二章 架构
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.ora
这个参数文件中有很多对数据库至关重要的配置参数.
有两类参数, 有文档记载的以及一些以’_’开头的隐藏参数, 一般情况下, 不推荐使用这些参数, 尽管有些时候可能会带来某些好处, 但是大多数情况下, 其副作用更大, 仅供ORACLE内部使用. _TRACE_FILES_PUBLIC = TRUE, 这个参数使trace file对所有用户可读, 而不仅仅是DBA Group的人.
该文件的路径:
$ORACLE_HOME/dbs (Unix)
%ORACLE_HOME%DATABASE (Windows)
这个文件并不一定要放在某一特定路径下, 因为我们启动数据库的时候可以指定参数文件:
startup pfile = filename.
数据文件
数据文件与重做日志文件是ORACLE两种最重要的文件。
段(Segment)简单来讲就代表数据库中需要消耗存储空间的数据对象, 表, 索引, 回滚段等. 创建一个表的时候会创建一个数据段, 分区别会为每个分区创建一个段, 索引会有索引段等.
Segment又由Extent组成, Extent是数据文件上的一段连续空间. 每个Segment至少有一个或者两个Extent. 当一个Extent满了以后, 就分配第二个Extent, 但接下来的Extent不一定与第一个Extent在物理上连续, 甚至不必在一个文件上. 一个Extent小到一个block, 大到2G.
Extent由block组成, block是ORACLE中的最小空间分配以及读取单位.
Block的大小在数据库创建的时候就已经定下来.
Block结构:
Block大致分为3部分: block header, free space, used space
Block header又包含
Header: block类型, transaction信息, block在磁盘的位置
Table Directory: 该block包含的行所在table的信息
Row Directory: 指向block中行的指针
总结:
1. 数据库由多个表空间组成
2. 一个表空间由一个或多个数据文件组成, 表空间包含segments
3. 一个segment由一个或多个extent组成, 一个segment存在于一个table space中, 但是可能分布在多个数据文件中
4. Extent是此盘上一系列连续的block, 一个extent属于唯一的一个表空间, 并且存在于表空间的一个文件中
5. Block是数据库中最小的分配单位, 也是最小的I/O单位
表空间的字典管理与本地管理
在ORACLE8.1.5之前, ORACLE中仅有一种管理表空间中extent分配的方式, 字典管理. 字典管理就是通过数据字典来管理extent的分配, ORALCE会有两个列表, 一个用来存放已经使用的磁盘空间信息, 另外一个用来存放未使用的磁盘空间信息. 分配或释放资源的时候, 都需要对这两个数据字典进行操作. 这种为了进行存储空间管理而进行的后台操作就成为递归SQL, 是一种额外的cost.
在ORACLE7.3的时候, 出现了一种临时表空间的概念, 这种表空间的管理方法稍由不同, 空间一旦分配, 就不会被释放, 当下一个空间分配请求出现的时候, 会首先查找已经分配而未被使用的空间, 如果没有, 才按照以前的方式来分配新的空间.
本地管理, 不再使用数据字典, 而是每个数据文件有一个位图的部分, 一旦一个extent被分配使用, 仅仅将位图中的一个标志位置未1, 如果释放则置回为0.
临时文件
临时文件是ORALCE中一类特殊的数据文件, 用来存放诸如大的排序操作的中间结果, 因为我们没有足够的内存来存放它们. 普通的永久性数据文件是绝对不会被存放在临时文件中的, 但是临时文件可能回包含一些临时table, 临时index的数据.
在ORALCE中, 处理临时文件的方法也有点特殊, 对普通数据文件的操作一般都会产生重做日志, 但临时文件不会. 尽管临时文件也可能会有UNDO的产生, 例如在全局临时表的情形下, 你可能需要rollback这个session之前做的动作.
强烈推荐用本地管理方式来管理临时表空间.
绝对不要将普通的表空间改为临时表空间, 而要使用”CREATE TEMPORARY TABLESPACE”来创建临时表空间.
控制文件
控制文件是一种很小的文件, 包含ORACLE必须的其它文件的所在路径.
参数文件告知ORACLE实例控制文件在哪, 而控制文件则告诉实例数据文件以及在线重做日志文件在哪, 控制文件还包含一些其它信息, 注入已发生的check point信息, 数据库名称, 数据库创建的时间戳, 归档重做日志历史等. 控制文件丢失了对oracle来说并不是致命的, 只是会带来些许麻烦.
重做日志文件
重做日志文件对ORACLE来说至关重要, 它们是ORACLE的事务日志. 它们仅仅用在数据恢复上.
严格来讲, 在数据库中的每一个动作都会产生重做日志, 包含那些对数据字典进行管理递归SQL.
有些操作可能会已尽可能少产生重做日志的方式运行, 比如创建一个INDEX的时候制定了NOLOGGING属性, 代表该index的初始不会被记日志, 但是该动作产生的递归SQL依然会产生重做日志.
有两种不同的重做日志: 在线重做日志以及归档重做日志.
在线重做日志
每个数据库至少有2个重做日志文件, 这两个重做日志文件固定大小并且循环使用.
从一个重做日志切换到另外一个重做日志成为日志切换. 日志切换的时候, Performance差的系统有可能会导致数据库的暂时中止, 因为oracle要保证一个重做日志文件中的内容不需要再使用, 才能重写它. 如果ORACLE不能确定这一点, 它就需要将数据库的其它动作暂时挂起, 先来确保这一点.
数据库缓冲存储区(buffer cache)是数据库用来临时存储block的地方, 这是SGA的一个结构, 当一个block被读取的时候, 它将被存储在缓存中, 这样我们再次读取这个block的时候就有希望直接从内存中读取它. 当我们更改一个block的内容的时候, 我们更改的是缓冲区中的block数据, 而能够重做这个动作的信息则存储再在做日志缓存(redo log buffer)里面, 这是另外一个SGA结构. 如果我们commit这个更改, 希望使起永久更改, oracle不会将SGA中所有我们更改的数据写到磁盘中去, 相反, oracle将重做日志缓存中的内容写到在线重做日志中. 这样一旦数据库down掉, 缓存都会被清除, 而我们的更改在缓存里面而不是在磁盘上, 所以我们需要在线重做日志. 这样数据库重启的时候, oracle会利用在线重做日志中的文件, 重做我们先前的transaction, 所以只要我们的更改还在缓存而不是此盘上, 我们就需要在线重做日志, 这个重做日志文件就不能被重写.
DBWn(Data Block Writer)是ORACLE的一个后台进程, 它的职责是管理分配缓冲区当它被充满的时候, 更重要的是, 它负责执行checkpoints. Checkpoint就是将缓冲区中的脏数据(被修改的数据)写到磁盘中去. 很多事件都能够处罚checkpoint, 最重要的就是日志切换. 当我们从日志1切换到日志2的时候, oracle会启动一个checkpoint, 将日志1所保护的数据缓存都写到磁盘中去. 在这个动作完成之前, 这个重做日志文件是不能被重写的. 当我们试图重写一个还未完成checkpoint的日志时, 我们会得到以下错误:
Checkpoint not complete
这个时候, oracle中的所有进程都回暂停, 集中精力来首先完成这个checkpoint. 因为日志切换会导致checkpoint, 所以我们需要考虑我们的程序是否写了过多的redo log, 或者我们的在线重做日志是否够多, 又或者大小是否合适. 决策支持系统比联机处理系统产生更小的重做日志, 频繁的blob镜像转换将更快的填满重做日志.
归档重做日志
Oracle数据库可以以两种模式运行, 归档日志模式以及非归档日志模式.
不同点仅仅在于在重写一个在线重做日志的时候是将该日志简单重写还是先将其归档.
通常production环境都应该在归档模式下运行, 因为我们无法承担数据丢失的损失, 尽管这可能会要多一些额外的耗费.
[@more@]来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/767125/viewspace-996864/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/767125/viewspace-996864/