新博客http://www.cnblogs.com/zhjh256 欢迎访问
分类: Oracle
2008-01-06 21:36:32
Oracle服务器是什么?
在磁盘上的数据持久存储称为数据库,数据库的数据实际工作的RAM块称为实例。数据库和实例的关系通常是1:1,并且理论上来说是完全对的。但是对于RAC有点区别,多个实例可以同时打开一个数据库工作,但是RAC中的每个实例只能在一个数据库上工作,因此具体的关系如下:
一个实例只能在一个数据库上工作,但是一个数据库可以被多个实例打开。
Oracle服务器仅仅是一台安装了Oracle软件的机器,在这台机器上有一个Oracle实例在其内存中运行(提供了快速但是脆弱的数据管理能力);并且有一个Oracle数据库持久的存储在磁盘上。
用户连接到实例(注意,不是数据库)并通过SQL语句请求查看和操作数据,为了响应这些SQL语句,Oracle程序加载数据到实例,用户继续在加载到实例中的数据上工作。并且为了确保电源失败不会导致所有数据丢失,Oracle周期性的自动执行保存,将数据写入磁盘。通过这种方法,Oracle用户可以在高效的内存中工作,并且不用担心数据的丢失。
Oracle实例的结构
实例仅仅是一块分配的用来工作的内存加上一些后台进程组成。内存区域集合体称为SGA,共享池(Shared Pool),缓冲缓存(Buffer Cache), 日志缓冲(Log Buffer)这三个组件是必需的并且每个SGA都必须由这三个组件。
不管各种内存池的名称怎么样,它们仅仅是一块用来存储不同类型的数据的内存。它们的基本功能都是尽可能的缓存数据在内存中避免用户从磁盘上推进数据(是非常慢并且很昂贵的)。
共享池(Shared Pool)
当执行一个查询select * from emp时,数据库必须确定这是什么意思。是否存在一个称为EMP的表,它由什么列组成,物理上存储在什么地方,是否存在索引可以帮助快速得到结果?用户是否有恰当的权限查询表?回答所有这些问题的处理称为解析SQL语句,并且它在后台调用很多工作。
为了确定表是否存在,我们必须查询一个称为TAB$的内置表,为了确定表在磁盘上存储的物理位置,必须查询多个内置表,其中一个称为TS$(存储表空间信息)。为了确定用户的权限,需要查询USER$表和其他表。当用户执行一个简单的查询时,数据库在知道语句的意义前必须执行很多查询才能确定。这些系统执行的语句称为递归SQL。执行递归工作意味着在实际回答用户的SQL请求前执行大量的准备工作。
因此解析是非常昂贵的…因此我们都希望只解析一次然后将存储解析的结果在以后该用户或其他用户每次执行基本相同的语句时进行重用,解析的结果称为执行计划,其代表一个预处理的包指令用于回答一个SQL语句。每个新的SQL语句导致构造一个新的执行计划并被存储,执行计划被存储在称为库缓存(Library Cache)的共享池子区域。如果第二个用户执行完全相同的SQL语句,它只需要简单的查找库缓存并重用先前解出的执行计划即可。
如果必须从头到尾穿越所有的过程确定执行计划,其称为硬解析。如果可以重用先前其他用户创建的执行计划,称为软解析。
因此,可以说库缓存的作用就是帮助我们避免必须执行硬解析。
访问TAB$, USER$等字典表的代价同样是昂贵的,字典表物理上存储在磁盘的system数据文件上,因此每次必须从磁盘访问这些表是不希望的:会产生大量的磁盘读。因此一旦我们读取了这些表中的一些行,将其存储在称为字典缓存(Data Dictionary Cache)的共享池子区域以供将来访问。字典缓冲是字典表的内存拷贝,在解析操作时需要。
因此,字典缓存的作用是避免我们在每次解析SQL语句时访问磁盘上的字典数据文件。
由于这两个内存都是共享池的一部分,所以共享池的工作可以总结为尽可能廉价的解析SQL语句。
缓冲缓存(Buffer Cache)
缓冲缓存是一块物理上存储在数据库中的数据读取和更改的内存区域,当我们想要查看EMP表中的员工纪录时,它们首先从磁盘被读出然后被加载到缓冲缓存。为什么不直接读取并返回给客户端呢?因为其他人可能在你读取后也读取EMP纪录。如果我们第一次加载到缓冲缓存,第二个用户就完全不需要从磁盘读取:他们可以直接从缓冲缓存访问它们的拷贝。逻辑读不要求物理磁盘访问并且比物理读的速度快很多。因此缓冲缓存的作用可以说是最小化物理读并且帮助最大化逻辑读。
不仅仅是读,如果想要更新一条记录,将在存储缓冲缓存中的数据版本上进行更新。只有在此之后这个被更改的缓冲(脏缓冲)才会被保存回磁盘。当我们写更改的缓冲回磁盘时,内存缓冲中的内容将会和磁盘上的变得一样,并且此时我们可以称缓冲是干净的。
但是,Oracle不会读取单独的行。如果你希望更新EMP表中Jim的电话号码,Oracle不会仅仅提取Jim的纪录并定位在那里,读取和写入最小的单元是2k,4k,8k或16k。原因是我更新了Jim的电话号码,随后你可能会更新Bob的电话号码…所以我更新Jim纪录的请求帮助你取出来,因为其导致Jim周围的全部记录被加载到内存中。你随后的更新操作可能需要逻辑I/O即可,因此你随后的操作将从我先前的操作上获益。
2K, 4K, 8K,16K的数据集合称为Oracle块,并且是Oracle数据库最小的I/O单元。一个请求要查看块中的一个字节,整个块将会被读取到缓冲缓存,术语“块”实际上是描述磁盘上的集合,当一个块被从磁盘上读取到内存后,我们称之为缓冲(buffer)。实际上,块和缓冲是相同的一回事,区别是一个是物理上的,另一个是内存中的。SQL Server称之为页,块,缓冲,页…都是指相同的事情:数据被从磁盘读取到内存的最小单元,并且存储在内存中避免其他用户重新访问磁盘。
日志缓冲(Log Buffer)
对于任何数据库来说,日志缓冲通常10M是极限。
日志缓冲是内存区域中相对非常小的一块,在其中存储到数据的改变的纪录。每个更新,插入,删除都会产生一条记录描述影响的行以及行如何被改变。那条记录被写入第一个实例的SGA中的日志缓冲部分。并且在那里,记录被周期性的写入特定的磁盘文件,因此持久性的纪录在数据库上发生了什么事务。
事务记录通常称为REDO,因此我们可以说对于每个用户的每个事务,REDO首先被写入SGA的日志缓冲(由于速度需要)。
因此,Redo,简而言之就是一种Oracle的恢复机制,而日志缓冲仅仅是重做产生的第一个地方。
大池(Large Pool)
SGA的可选组件。
当在数据库上执行并行操作时,并行服务器之间的通信需要内存访问,如果没有配置大池这些内存通常从共享池分配:但是如果配置了大池,则从大池分配。由于实际上当前Oracle数据库大多用RMAN备份,因此每个数据库都应该数据要一个大池。
实际上可以不使用大池完成所有这些事情,但是这么做将意味着增加共享池的压力。其忙于最小化硬解析,而并行查询和rman备份操作立刻需要大量内存,因此大池的存在将意味着可以完全避免冲突。
因此,如果需要备份,就需要大池。这会极大的提高响应时间。
Java池
如果数据库完全不运行Java,那么Java池可以为0。
流池(Streams Pool)
在10g中,在SGA中有一个专门的内存区域用来复制数据到远程数据库。如果不需要配置流复制,则不需要配置该池。
在9i中,复制所需的内存从共享池中分配,因此大大影响了共享池的功能。
后台进程
内存区域,如SGA将是没有任何用户的,除非某些东西可以将数据写入内存或者从内存中读出来。因此,需要一个知道如何与组成Oracle SGA的各部分内存交互的进程集合。事实上,这些进程称为后台进程,因为它们在后台工作而不会以任何方式影响用户的操作。
五个必需的进程如下:
*SMON(系统监视器)
SMON在每次启动实例并尝试用其打开数据库时检查数据库的一致性和健康。如果数据库由于某些原因不一致,SMON将会完全自动进行修复如果smon能够完成,否则将会提示手工进行修复。简而言之,SMON执行或者提示某些类型的恢复操作。
有意义的问题通常是,SMON基于什么估计数据库为健康或者需要恢复?答案是检查点改变号(checkpoint change numbers)。数据库会被周期性的标上一个新的序列号。只要数据库中的每个文件都有相同的序列号,我们就可以称数据库在那个点是一致的。如果在数据库打开过程中,SMON读取的所有检查点改变号(存储在物理文件的文件头中)是相同的,那么数据库就是健康的。如果他们不完全一致,并且没有恰当的原因,数据库将会被假设为遇到了某种类型的损坏并且需要调用恢复。
*CKPT (检查点)
另一个问题是,谁写入SMON读取的检查点改变号的数据库文件的文件头?答案是称为检查点的后台进程。CKPT将其信息写入所有数据文件的文件头的事件称为检查点事件。Oracle数据库中发生的每个事务都将导致系统范围的序列号(称为SCN)增加。在检查点事件中,最近的SCN被认为是最近的检查点改变号(CCN),并且这个CCN被CKPT写入所有数据库文件的文件头。
因此可以说,在长期的数据库操作中,CKPT不断地写新的CCN到数据库文件头中,SMON在数据库打开期间确保每个数据库的组件都有相同的CCN,如果它们是一致的,那么将打开数据库,否则将调用恢复过程。
简而言之,SMON读取CKPT写入的,两个进程合作确定是否需要恢复。
*DBWn (数据库写入器)
数据库写入器负责周期性的保存更改的缓冲缓存内容到物理数据库文件中。通过写更改的缓冲缓存到磁盘上,避免各种OS失败导致的数据丢失。
因为内存中包含更改的数据的缓冲称为脏缓冲,并且因为数据库写入器的实际工作事实上是重新同步磁盘上和内存中的数据的版本,因此我们通常称数据库写入器的工作是清除缓冲。
而且因为一个干净的缓冲包含数据是从磁盘重新读入的,因此可以覆盖干净缓冲的内容。相反,脏缓冲是指包含更改的数据版本—但是没有写道磁盘上的缓冲。因此可以说数据库写入器的工作是保持缓冲缓存的循环使用:通过清除缓冲,使其可以重用。
*LGWR (日志写入器)
因为数据库写入器提取缓冲缓存的内容并将它们写入磁盘。因此日志写入器周期性的将日志缓冲的内容写入磁盘。
在处理过程中,日志写入器遵循重用日志缓冲的内容,就像写入器允许重用数据缓冲。如果内存中任何部分的内容是唯一记录数据库发生的事务的信息,将不能覆盖任何东西。一旦这些信息的副本被写入磁盘,日志缓冲中的内容就可以被覆盖重用。
永远都只有一个日志写入器,日志记录必须被串行的写入磁盘—并且这意味着只有一个进程能够知道什么需要写入磁盘。否则如果一串事务具有依赖性,将会发生逻辑中断。
虽然其确保事务发生的正确顺序,但是这通常会成为系统的颈瓶。这就是为什么日志写入器写入的文件应该放在最快的磁盘上,并且确保日志写入器的速度快于数据库写入器是非常重要的。
*PMON (进程监视器)
进程监视器用于监视所有其他进程。如果任何进程挂起或者死掉,PMON将尝试重启它们,并且有时候会成功。否则,它将采取恰当的动作—通常是安静的崩溃实例。同时进程监视器用于监视用户,如果有在处理中的事务,但是用户pc挂起了或者网络断开,PMON将会识别出非正常断开的用户并回滚正在执行中的事务,这意味着在行上的锁被删除,内存被释放,其他资源被回收。
ARCn (归档进程)
用于持久性的确保数据的可重做。
其他
如果使用Oracle RAC,将使用5个额外的进程(LMON, LMD, LMS, LCK, DIAG),如果启动一个调度的数据库作业,将会看见一个CJQ0进程。如果配置了共享模式,将会看见S000等进程。
进程/线程?
在Windows下称为进程中的线程,在linux/UNIX下则是为独立的进程,可以通过以下语句列出:
[oracle@nerva ~]$ ps -ef | grep ora
在Windows下没有等价的命令可以看到单独的进程,只能使用以下查询:
select program from v$process;
Unix和Windows上的这种架构区别不会影响Oracle数据库本身的功能。
数据库
Oracle数据库仅仅由三种类型的文件组成,它们都是二进制文件。并且具有仅Oracle实例能够识别的格式。
控制文件
每个数据库至少有一个控制文件,其是一个二进制小文件并且具有两个主要任务。首先,其包含指向所有组成数据库的文件的物理位置,这就是说,控制文件物理上存储了所有文件的全路径名和文件名。其次,其包含最新的ccn,这是由CKPT在每次检查点事件结尾写入的时间戳,即CKPT检查点。
数据库中的其他文件在每次检查点时由CKPT赋予时间戳—控制文件知道如何寻找其他数据库文件,而且这必须是数据库打开时第一个要读的文件。那意味着存储在控制文件中的时间戳首先被读取,并且假设数据库的其他文件具有相同的时间戳,因此可以说,控制文件是数据库的主时钟。
需要注意,镜像控制文件不同于控制文件副本,使用硬件镜像,实例只看到并维护一个控制文件拷贝,任何东西在那个控制文件中完成,然后硬件介入并复制到镜像拷贝。副本意味着告诉实例有多个文件需要写入,写入一个副本的控制文件事务要原原本本的写入另一个控制文件,通常控制文件事务的开销是很昂贵的,至少需要两次读取两次写入(4次串行I/O)。
数据文件
全部Oracle数据库都可以从两个数据文件开始,system和sysaux文件。确保良好的数据字典访问是非常重要的,因为每次解析SQL语句时都需要它。
任何数据文件的第一块称为数据文件头,并且在每个数据文件头中,CKPT周期性的写入最新的CCN。
虽然数据文件本身并不关心其中存储了什么数据,但是确保每个数据文件仅存出一种类型的数据是非常重要的。
在线日志文件
数据文件内部由Oracle块组成,而重做日志内部由FS块(通常为512字节)组成。
因此可以说:
Database = Control Files + Data Files + Online Redo Logs
其他关键的非Oracle数据文件
数据库文件和非数据库文件的关键区别是文件是否被连续监控和写入。
归档日志文件
密码文件
密码文件的名称通常为orapwXXX.ora,在$ORACLE_HOME/dbs目录下。在windows下,通常为%ORACLE_HOME%\database\PWDXXX.ora。
参数文件
Oracle 10g Release 2共有257个参数,其中DBA必须掌握的一些参数包括如下:
DB_BLOCK_SIZE
DB_NAME
SGA_TARGET
SGA_MAX_SIZE
SHARED_POOL_SIZE
DB_CACHE_SIZE
LOG_BUFFER
UNDO_MANAGEMENT
UNDO_TABLESPACE
UNDO_RETENTION
DB_RECOVERY_FILE_DEST
DB_RECOVERY_FILE_DEST_SIZE
这些内核参数是最为重要的核心参数。
SUMMARY
查看实例运行状态:
select status from v$instance;
如果show parameter db_cache_size显示缓冲缓存的值为0,那么表明使用自动SGA控制,在这种情况下可以使用select current_size from v$sga_dynamic_components where component ='DEFAULT buffer cache';查询察看缓冲缓存的当前值。
查掉SMON进程并观察发生的情况:
NT:
select spid, osuser, s.program from v$process p, v$session s where p.addr=s.paddr;
$orakill win102 1292
此时实例将会自动关闭;
UNIX:
[oracle@nerva ~]$ ps -ef | grep lx10
[oracle@nerva ~]$ kill -9 spid