洋芋疙瘩贺东所有歌曲:深度对比Oracle与SQL Server

来源:百度文库 编辑:偶看新闻 时间:2024/05/11 02:49:41
一般的公司通常会在他们的信息系统架构中引入多种数据库平台,同时引入三到四种不同的RDBMS解决方案的中大型公司也并不少见,当然这些公司里面的DBA们通常也需要同时拥有管理多种不同平台的技能了。只在一种平台上展开工作的数据库专家们也通常会期待着在他们的下一份工作中能学到点不一样的东西,那些有勇气的人们则愿意花时间、金钱和精力去学习新的东西,也有其他因为换了新公司或者是为了找新的工作而去学习新的系统的人们,毋庸置疑的一点就是公司老板和人力专家们会更加青睐于那些拥有多个领域经验的求职者。依我个人的经验来看,在学习一个新的数据平台的时候,最好的方法就是在新的环境中去发现那些你已知的东西,这样学习起来会简单很多。当然,当中也会遇到一些全新的概念需要去学习,或者是忘掉一些你现在已知的概念,但不管怎么说你不是从零开始的。比如说一个做SQL Server开发人员在要写Oracle存储过程的时候可能会先去找那些内置的函数然后比较它们之间不同点,她也可能会去比较变量声明以及错误处理的异同。本系列文章中我将尝试对Microsoft SQL Server和Oracle RDBMS(以10g及以后的版本为主)进行一个深入的比较。我会主要集中于这两种数据库之间架构上的比较,当然不要期望我会给你一个详尽的比较清单,但是我会尽我所能的让你看清这两种当今世上应用最广的数据库之间的相同和相异之处。本文是以一个SQL Server DBA的角度去构思和写作的,不过相信这对Oracle专家门了解SQL Server这一面也是很有参考价值的。废话少说,开工吧。
top操作系统的支持
Microsoft SQL Server向来都从属于Windows大家族中的一员,要让Microsoft发布一个支持其它操作系统版本的可能性当然是小之又小的了。当前来说SQL Server可以在XP、Vista、Windows Server 2000、2003、2008上运行,同时也有针对于32位和64位版本Windows的数据库版本。对Oracle来说,它支持多种不同的操作系统平台,包括Windows(32位和64位),另外还有支持Linux和不同分支的Unix(Solaris、HP-UX、AIX等等)
top版本和发行版
在本写作时,Microsoft数据库产品的最新版本是SQL Server 2008,即将推出的下一版本是SQL Server 2008 R2,现在已经在CTP阶段了,它的上一个版本,SQL Server 2005,相对于再之前的SQL Server 2000的一个大升级。不过对很多公司来说SQL Server 2005还是有点新,因为他们现在还是在大量的使用着SQL Server 2000.另一方面Oracle一路走来最新版本已经到了11gR2了,现在主流应用的版本10gR2已经发行有一段时间,已经是公认的领头羊了。Oracle在10g中第一次提出“网格计算”的概念。当然现在还有公司依然在依赖于Oracle 9i处理业务。说到发行版,SQL Server 2008 R2现在提供下面这么些版本:企业版
企业版包含所有的高级特性,适用于大规模、高容量的数据库需求。
标准版
标准版为那些不需要包含企业版高级特性的公司提供了一个相对便宜的数据库平台,大部分公司使用的都是标准版的数据库。
工作组版
工作组版适用于小的部门级别的应用。
Web版
这个适用于作为Web应用的低成本的后台解决方案。
Express版
这是一个很小的内嵌式的SQL Server引擎,通常用于本地数据存储或是小规模的系统开发。Express版可以免费下载并且自由分发。
Compact版
Compact版可以让用户开发Windows桌面或者是手持设备的应用。
开发版
所有企业版所拥有的功能开发版都有,不过它仅仅授权单个用户访问,主要用于开发或是测试目的。
除了企业版,SQL Server 2008 R2还为数据中心和数据仓库提供两个“白金版”,这两个版本分别称为数据中心版(Datacenter Edition)和并行数据仓库版(Parallel Data Warehouse Edition)。对于Oracle 11g R2,发行版是这么样的:企业版
这个版本提供了顶级的性能,同时价钱也是顶级的。像SQL Server的企业版一样,所有这个产品能提供的特性在这个版本里面都有。
标准版
这个和SQL Server标准版很像,Oracle标准版包含了大部分业务应用所需要的大部分特性。
标准版1
这个版本为小型工作组应用而设计,授权最小的用户为5。
Express版
这个目标客户是小规模应用或者是数据库开发入门,可以免费分发。现在Express版还处于10g R2版本。
下表提供了SQL Server和Oracle数据库发行版的直观的对比:SQL Server Oracle
Enterprise Edition Enterprise Edition
Standard Edition Standard Edition
Workgroup Edition Standard Edition One
Express edition Express Edition
Web Edition X
Compact Edition X
Developer Edition Enterprise Edition
top实例、数据库和表空间
SQL Server和Oracle之间第一个架构级别的差异就在于对实例(instance)和数据库(database)概念的定义了。SQL Server中,实例一词用来代表一个包含了操作系统文件、内存结构、后台进程以及注册表信息的独立的应用服务。在Windows系统中用一个存在着停止和运行状态的服务来代表一个实例,当处于运行状态时,实例要占用一定的服务器内存以及生成一定数量的后台进程。SQL Server实例的中心是数据库。一个SQL Server数据库指的是一个资料库以及操作数据所需要的程序代码,当实例没有运行时,实例中的数据库就不能够访问。SQL Server有两种数据库:系统数据库(system databases)和用户数据库(user databases)。在一个SQL Server实例安装完成之后,将会自动创建5个系统数据库:master, model, msdb, tempdb和resource。如果一个机器上面安装了多个SQL Server实例时,没有实例都会有自己单独的一套系统数据库。除了msdb数据库之外,其它数据库不能访问或是被损坏都会导致实例无法启动。相比之下用户数据库由DBA或者是开发人员在数据库实例安装完毕、系统数据库都启动之后所创建的,这些数据库中保存着公司的业务资料。简而言之,一个SQL Server实例总是要包含一些数据库(尽管有时只是那些系统数据库),一个数据库也总是要有一个(且仅有一个)与之关联的实例。从物理角度说,一个SQL Server数据库表现为存储于磁盘上面的一组操作系统文件的集合。数据库文件分为两种:数据文件(data file)和事务日志文件(transaction log file)。一个数据库至少要包含一个数据文件和一个事务日志文件,SQL Server数据库的资料主要是存在于数据文件中,事务日志文件用来记录发生在这些数据上面的变更记录,SQL Server在执行系统恢复的时候要用到它。一个数据文件或事务日志文件只能隶属于一个特定的数据库,不存在两个数据库共用一个数据文件或者是日志文件的情况。一个数据量很大的数据库可以使用多个数据文件,这些数据文件能够被逻辑的组合成一个称为文件组(file group)的逻辑组。在Oracle中,这一切看起来都有点反着来了。当Oracle启动时,它和SQL Server一样要先占用一些服务器内存用于执行操作,这个内存区域——著名的SGA(System Global Area)——被分为数个不同的结构,在创建SGA的同时也会启动一系列的后台进程用于和SGA进行交互,在这里这些分配的内存空间和后台进程组合起来就是Oracle实例了。请注意现在我们没有见到数据库的影子还,实际上Oracle实例在没有数据库或是数据库不能访问时也是跑的很好的,在安装Oracle时,我们可以选择只安装软件,完了之后再安装数据库。Oracle中的数据包含了一组操作系统文件。不像SQL Server数据库,Oracle数据库并不能代表数据库对象的逻辑分组,它更像是表示包含多个存在于磁盘上的用来保存数据的文件的一个单个的集合名词。组成Oracle数据库的文件可以分成三个类型:数据文件(data file)、重做日志文件(redo log file)和控制文件(control file)。数据文件保存数据,Oracle中可以存在任意数量的数据文件;重做日志文件跟SQL Server的事务日志文件一样用来保存对数据更改的记录,在系统恢复阶段需要用到;控制文件是一些特别的小文件,用来保存一些至关重要的关于数据库的信息,没有这个文件的话,实例就无法打开数据库。除了数据文件、重做日志文件、控制文件之外,数据库还包含参数文件(parameter file)、密码文件(password file)和可选的归档日志文件(archive log files),后面很快会对这些文件类型展开讨论。Oracle系统启动时,首先在内存中创建数据库实例,然后由实例找到保存在磁盘中的数据库,最后打开数据库让用户操作。当系统关闭时,实例会从内存中清除掉:整个内存结构和后台进程都会消失,但是数据库依然存在于磁盘上,只是处于关闭的状态。之前也说过,Oracle实例可以在不打开数据库的情况下运行——这是与SQL Server数据库最大的不同,SQL Server实例是不能够离开系统数据库而运行的。不过和SQL Server一样Oracle数据库在实例没有启动的情况下也是不能访问的。一般来说Oracle实例和数据库之间是一对一的关系。一个实例对应着一个数据库,但是一个数据库却可以同时由多个实例去访问它。一个独立的Oracle安装包含一个实例和一个供实例操作的数据库,而配置成RAC(Real Application Cluster)的安装则可以允许多个存在于不同机器上的实例访问存在于一个共享磁盘上面的数据库。那Oracle中数据库对象的逻辑分组在那儿呢?在SQL Server中逻辑分组由数据库自己来完成,而在Oracle中,这项工作由表空间(tablespace)完成,Oracle表空间是用来对表、视图、索引和其他数据库对象进行分组的逻辑结构。例如,你的Oracle产品库可以给HR应用一个单独的表空间,支付应用则使用另外一个。一个数据库可以逻辑的分成若干个表空间,这些表空间在物理上则由一个或者多个数据文件组成。因此在Oracle中与SQL Server数据库等价的是表空间。由于这两种结构在功能上相当类似,在SQL Server中建立数据库的过程和在Oracle中建立表空间的过程也非常相似。不管是建立数据库还是表空间,DBA都要首先指定一个名字,然后给新建的数据库或者表空间分配一个或多个数据文件,并为每个数据文件指定初始大小和数据增长情况。在SQL Server中可以做到让一个用户数据库离线或是只读,Oracle的用户表空间也一样可以。在SQL Server中可以让一个用户数据库中的一个或者多个数据文件只读,而Oracle用户表空间中的一个或者多个数据文件也同样能标记为离线。不过数据库和表空间在某些方面还是有差别的:SQL Server中,数据文件可以用文件组逻辑的进行分组,而Oracle表空间就没有类似的概念。
SQL Server的每个数据库都有自己的事务日志文件,而且在创建数据库的时候就要指定这些日志文件的属性。而在Oracle中整个数据库(意为所有的表空间)的事务日志都是记录在同样的一样重做日志中,因此也不存在说给每个表空间建立一个单独的日志文件的说法。
SQL Server中,数据库可以设置成简单恢复模式(simple recovery mode),简单恢复模式指的是活动的数据库日志在checkpoint操作完成之后就会截断。Oracle也有类似的概念,这个稍后会说到,不过不能在表空间级别上进行这样的设置。 top实例名和SID
SQL Server和Oracle都允许在同一个机器上面同时运行多个实例,多个实例的执行环境是完全独立的:就单个的数据库引擎而言,它并不知道也不关心有没有其他的实例在这个机器上运行着。在SQL Server中这种机制通过实例这个概念来实现,SQL Server可以作为一个命名的(named) 或是 默认(default) 的实例来运行,默认实例的名字和运行它的Windows服务器的名字一样,显然一个系统的默认实例只可能存在一个,不过在一个机器上可以存在多个命名的实例,命令实例的名字格式为 HOSTNAME\INSTANCE_NAME ,同一个主机上每个运行实例的 INSTANCE_NAME 必须是唯一的,每个实例都有着自己的一套程序文件以及一些与其它实例共享的通用组件。而Oracle也差不多,在安装Oracle的时候,DBA就需要指定一个 全局数据库名(Global Database Name)和系统标识符(SID, System Identifier)。Oracle中实例和数据库是完全不同的东西,一个全局数据库名用来在网络上唯一的识别一个数据库的存放位置,一个完整的名字通常是下面的格式database_name.network_domain_name。SID则是用来识别一个与数据库关联的实例,大都数情况下一个实例关联一个单个的数据库,数据库名和SID名字会是一样。RAC环境中就不一样了,RAC允许多个实例访问放在共享存储中的同一个数据库,此时的实例名和数据库名字将不一样。当然和SQL Server一样,一个Oracle数据库服务器上面是不允许两个实例使用同一个SID的,另外一点类似的就是在安装时一旦指定,不管是SQL Server实例名还是Oracle SID都是不能再修改了(译注:实际上Oracle从9i开始就提供一个叫nid的工具用来修改数据库名了)。SQL Server DBA可以通过下面的语句查询当前登录系统的实例名:1 SELECT @@SERVERNAME Oracle DBA用来查询实例名和数据名的语句如下: 
1 SELECT INSTANCE_NAME, HOST_NAME, VERSION, DATABASE_STATUS FROM V$INSTANCE;  2 SELECT NAME, DATABASE_ROLE, CREATED FROM V$DATABASE;
top系统数据库和系统表空间
一个SQL Server实例需要有5个系统数据库(2005之前的是4个):master, model, msdb, tempdb和resource,一个Oracle数据库则最少需要3个系统表空间才能正常操作,它们是:SYSTEM, SYSAUX和TEMP。master和resource数据库集中保存了SQL Server自身管理所需要的所有信息,里面保存了诸如系统配置,数据库列表和文件路径、终结点、连接服务器和用户帐户(或“登录”信息),系统级别的对象存储在只读的数据库”资源(resource)”中。在Oracle中,SYSTEM表空间等价于master数据库,SYSTEM表空间包含了数据字典(data dictionary),也就是关于Oracle自身的元数据(metadata),这里的数据字典可以和SQL Server中的resource数据库进行类比。到这里你也许猜到了:如果SYSTEM不存在或是损坏了的话Oracle数据库是打不开的。对于一个SQL Server实例,model数据库用作这个实例中所有新建的数据库的“模板”,对model数据库的任何修改都会反应到之后新建的其它数据库里面。在Oracle中就没有这样的模板,不过在你新建一个表空间的时候,你可以指定这是一个永久的表空间或者是其他类似TEMP和UNDO一样的表空间,永久表空间才是用来保存用户数据的。SQL Server的tempdb用作整个实例的“试验田”,每次实例重新启动的时候tempdb都会重新创建。Oracle的TEMP表空间的作用类似:用来包括大的排序操作的中间结果。当然SQL Server的tempdb还能用来保存行版本(row versioning)所需要的信息,当行版本启用后,行版本特性可以保证数据库引擎能将数据行的每次的修改记录保留下来,修改之前的行会保存在tempdb里面的版本库中,一般查询会返回一个数据行上最后提交的版本,当一个使用了特定隔离级别的依赖行版本的读操作不再会阻塞其它修改同样数据的事务,这是因为读操作不会在数据行上使用共享锁。不过这个特性需要在单个数据库上单独启用。Oracle中使用一个单独的表空间——著名的UNDO表空间——来达成同样目的。UNDO表空间保存着被DML语句修改的数据块的读一致性的副本。当用户开始对数据进行修改的时候,修改之前的数据块会被保存到UNDO表空间中,当另外一个用户需要查询这些数据的时候,他取到的实际上是UNDO表空间中查出来的读一致性的版本。不像SQL Server的行版本,Oracle的UNDO不需要启用——因为它是属于Oracle并行访问机制的一部分。最后一个要介绍的SQL Server中的msdb数据库,SQL Server代理服务需要操作这个库。SQL Server代理负责计划任务、警告、复制、日志传送以及其它的很多东西,代理服务的正常运行离不开msdb数据库。在Oracle没有明确与mdsb数据对应的东西。SYSAUX表空间也是一个系统表空间,在安装过程中(译注:准确说应该为“数据库创建过程中”)创建,它里面保存了诸如Oracle AWR(Automatic Workload Repository)信息、多维数据和多媒体数据,XML数据库等等。v数据库实例结构当Oracle实例启动之后,所看到的就是在服务器内存上的一个个不同内存块加上产生的与这些内存交互的后台进程。Oracle文档将这些内存结构和进程收的很详细。由Oracle实例所占用的内存块成为SGA(System Global Area),它的大小可以通过调整Oracle初始化参数(initialisation parameter)进行修改,在SGA里边至少会创建3个不同的区域,它们分别是:数据块缓存区(Database Buffer Cache)
这里缓存的是数据块。和SQL Server一样,用户不会直接的访问数据文件上的数据:当读取数据时,相关的数据块会从数据文件中拷贝到内存中;修改数据时也是修改内存中的数据,然后再由单独的进程将数据缓存区中被修改的数据写入到数据库中。
重做日志缓存(Redo Log Buffer)
SGA中的这个区域连续的记录着数据缓存区数据修改的记录,重做日志缓存中的内容会被写入到在线日志文件中去。
共享池(Shared Pool)
SGA中有一大块的内存用作共享池,共享池等价于SQL Server中的执行缓存(Procedure Cache)。它的主要作用就是缓存数据库中最近执行过的SQL语句。共享池由下面的模块组成:
数据字典缓存(Dictionary Cache)
数据字典缓存缓存了Oracle最近使用的数据字典信息。
库缓存(Library Cache)
这个区域包含了最近执行的SQL和PL/SQL语句和对应的执行计划。SQL区还能进一步分成共享区和私有区:共享SQL区保存的语句可以由多个用户使用而私有区保存的则是跟各个连接对应的绑定变量的信息。PL/SQL是Oracle对于行业标准SQL的程序扩展,当PL/SQL程序执行时,它的代码会拷贝到库缓存中的共享PL/SQL区中。除了缓存执行代码和执行计划外,库缓存还包含锁、阀以及字符集等信息。
根据你所使用的组件的不一样,Oracle的SGA中也可能存在其它一些可选的内存区域。在Oracle中使用Java应用时要使用到Java池(Java Pool),Oracle内置的备份恢复工具RMAN(Recovery Manager)要用到大池(Large Pool),当使用Oracle高级队列机制时要用到流池(Steams Pool)。上面介绍的各个内存区域都是属于SGA的一部分,它们是通过一序列的进程(process)来和数据库进行交互。下面就开始介绍包括用户进程和服务器进程在内的Oracle进程了。当用户或者是应用连接到Oracle数据库时就会产生一个用户进程(user process)。在一个两层的系统架构中,用户进程存在于客户端机器上;而在一个三层的系统架构中,用户进程由中间层产生。一旦用户进程连接到Oracle监听服务(Listener Service)时,监听器就会为这个用户会话产生一个服务器进程(server process)。再说详细点就是,Oracle监听器是一个负责为Oracle处理近来连接的网络组件,监听器本身是一个单独的进程,负责监视着从客户端过来的连接请求,如果监听器没有运行的话,数据库也就无法连接了。一旦连接建立,由监听器产生的服务器进程就开始接手处理用户操作数据库的请求了。大多情况下每个用户连接会产生一个独立的服务器进程,不过Oracle也能配置成一个运行着多个预先创建好的服务器进程池的模式,此时用户进程连接到数据库实例之后将会直接从进程池中分配一个进程。任何时候Oracle实例中都会有多个后台进程在运行着,不过,有5个必须要有的。写数据库(Database Writer)进程或称DBWn负责将数据缓存区中被修改的数据库写入到数据文件中。为提高系统系能Oracle可以最多创建20个这样的进程,DBWn中的n代表着一个单独的进程:n取值范围是0到9和a到j。在DBWn进程将脏块写入到数据文件的同时,一个叫日志写入(Log Writer, LGWR)的进程也在降日志缓存中的日志写入到在线日志中去。LGWR执行的要比DBWn进程频繁得多,主要原因有两点:首先是要尽快的将事务信息写入到磁盘当中,以保证当意外宕机等事件发生时数据库能正常恢复,在一个就是日志缓存中的日志信息记录的不是实际的变化的数据,但是却是能够反应数据的变化——因此相比之下也就要小得多了。检查点(Checkpoint, CKPT)进程负责定期的将SGA中的内容同步到数据库中。当执行检查点时,它会调用DBWn进程将所有的脏块写入到数据文件中,同时将重做日志缓存中的内容写入到在线日志文件中,然后更新数据文件头和控制文件的相关信息。如果某个访问数据库的进程意外的死掉的话,那进程监视器(Process Monitor, PMON)就会在后台悄悄的清理掉这个死掉的进程,所进行的操作包括释放相应的锁、回收分配的资源已经将这个进程从活动进程中清理出去。PMON进程有点像一个UNIX的daemon进程:它会定期的唤醒以检查看是否有清理工作要做。在必要的时候也能启动一个别的进程或被其他的后台进程使唤。在一个实例崩溃之后重启时,Oracle会自动的调用系统监视器(System Monitor, SMON)进程,SMON会利用在线日志文件来完成崩溃恢复操作。归档进程(Archiver, ARCn)是Oracle实例中可选的几种进程之一,这里的n和之前说的一样都是代表着单个的进程。只有在数据库开启了归档模式(archive log mode)之后才会启动ARCn进程,在在线日志中的内容满了之后,在Oracle覆盖这些记录之前ARCn进程会将这些内存保存到磁盘上,这些文件称为归档日志(archive log),这样的话在线日志内容就不会丢掉了。下图显示的是Oracle实例结构的一个简化版。 最后,你可以通过下面语句来查看SGA各个组件的情况:1 SELECT * FROM V$SGAINFO  下面的命令用来查看分配给Oracle实例的总内存数:1 SHOW PARAMETER SGA_MAX_SIZE; 要查看一个实例上运行的Oracle进程情况可以使用下面的语句:1 SELECT NAME, DESCRIPTION FROM V$BGPROCESS ORDER BY NAME  在一个运行着的Microsoft SQL Server实例上,同样维护者一些内部的内存结构和后台进程,不过不像Oracle那样,SQL Server并没有公开的详细解释内部工作和架构的文档。自2005版以后,SQL Server引入了一个叫SQLOS(SQL Operating System)的东西,不过跟名字所显示的不一样的是,这个东西既不是一个操作系统,也不是对于OS API的一个封装。它并不是一个通向非Windows平台的桥梁或是一个用于框架开发的类库。SQLOS是一套用于通过优化与Windows系统接口而为SQL Server存储和数据库引擎提供关键服务的软件,Windows是一个通用的OS:它并没有为SQL Server而做特别的优化。SQLOS则担当替代Windows而为SQL Server和管理核心系统服务的,SQLOS提供的服务包括:内存管理
资源管理
检测和管理死锁
异常处理
CLR组件托管
包括专用管理连接(Dedicated Administrator Connection, DAC)和动态管理视图(Dynamic Management Views, DMV)在内的诊断功能
调度管理(马上开讲)
Windows下的应用程序都是运行在独立的、受保护的内存空间上,这些内存空间被称为虚拟地址空间(Virtual Address Spaces, VAS)。因为每个应用的VAS都是不一样的,因此一个应用是不能往另外一个应用的地址空间做写入操作的,这样保证了程序不会因为严重的违规访问而崩溃。分配给应用的VAS可能来自于物理内存或者是页面文件,又或者是两者都有。页面文件(paging file)又称交换文件(swap file)是一个被Windows内存管理器用来存放那些无法放进物理内存的数据的,这些数据被写入到交换文件中,在应用需要的时候被读取出来。当中所涉及到的虚拟内存地址与物理内存地址之间的转换(在RAM和页面文件中)时由Windows内存管理器完成。从应用的角度来说,它并不关心它的内存究竟是存在什么地方的。对32位的Windows系统,OS所能寻址的最大的VAS地址空间是4GB,默认情况下这当中的2G供操作系统内核使用,剩下的2G提供给像SQL Server之类的应用使用。不过通过修改boot.ini中的开关(3G开关)设置可以让Windows只给自己分配1G而剩下3G给应用使用。要想在32位的机器上使用超过4GB内存的话,SQL Server可以通过地址窗口化扩展插件(Adress Windowing Extension, AWE)机制利用超出限制的内存。在64位的系统上面Windows的内存寻址通常就不是个问题了,因为此时的Windows可寻址的VAS空间达16TB。作为同样是Windows应用的SQL Server,自然也是无法独立于VAS规则之外的了。当SQL Server启动之后,数据库引擎就只能看到自己的VAS空间,缓存池(buffer pool)也就放在这个空间里面。缓存池缓存的是SQL Server数据:它由8KB大小缓存组成,缓存了来自数据文件的数据页,这个类似于Oracle的数据块缓存区。在VAS中的数据库引擎由SQLSERVER.EXE程序,各个DLL库以及线程结构组成。缓存池的大小受限于两个组件:机器可用的物理内存和SQL能访问的VAS。为避免缓存池无限扩展最终会吃掉所有的VAS而导致SQL Server意外死掉,SQL Server会让缓存池留下一部分VAS内存作为“保留区”。另外SQLOS内存管理器还保证缓存池可以满足其他SQL Server内部组件需要:缓存池中的内存页可以用来缓存连接数据、SQL优化器数据、还要做最重要的执行缓存之用。因为分配给这些组件的内存是不能再用作存储数据了,因此这些页又叫做被盗用页(stolen pages)。下图简要的展示了SQL Server VAS的各个组件。 前面提到的资源监视器(resource monitor)属于SQLOS的一个组件。资源监视器的工作之一就是检查和监听操作系统发出的低内存通知,当资源监视器检测到低内存情况时,它会将这一情况记录到一个称为环缓冲区(Ring Buffer)的结构中,然后再将这个信息广播给SQL Server引擎,这样所有SQL相关的组件接到广播之后能减少它们的内存使用。SQLOS的内存管理器(Memory Manager)组件也同样会监视可用的虚拟内存和物理内存以及通过一个叫内存专员(memory clerk)的通知机制对内存压力做出响应。在涉及到任务执行(查询编译、执行等等)的时候,SQLOS使用到一个叫做调度器的机制。调度器(scheduler)可以看成是SQL Server对于每个单个CPU的抽象表示,举个例子来说,一个运行SQL Server的机器有2颗4核的CPU的话那就能看到8个调度器。每个调度器都会和一定数量的工作线程(worker thread)相关联。例如在数据库上面执行的一个查询任务,这个任务会被分割成解析、编译、生成执行计划等一序列的子任务,每个这样的子任务都会由不同的线程来执行。当SQL Server启动的时候,只会启动有限数量的线程。线程的总数取决于运行SQL Server的机器的CPU数量以及架构(x86还是x64)。一个少于4个CPU的x86系统,所创建的线程数量为256;超过4个CPU之后每个增加的CPU会多创建8个线程。对于少于4个CPU的x64系统,初始线程数量为512;超过4个CPU之后每个增加的CPU会多创建16个线程。也就是说机器的CPU越强大,SQL Server创建的线程就会越多。当用户连接到SQL Server系统执行任务时,每个任务都会被分配给一个调度器。在SQL Server 2005之前,任务是按照轮流的方式分配的。自SQL Server 2005开始,任务分配则由SQLOS执行:任务会分配给最闲的调度器。和Oracle一样,在SQL Server也是可以查看那些运行中的后台进程的。只要在数据库实例上执行sp_who2命令就可以看到那些后台运行的进程了。 当中的CHECKPOINT进程看名字就知道什么意思了。LOG WRITER进程等价于Oracle的LGWR进程:它负责将数据库的变化写到事务日志中。LAZY WRITER进程等价于Oracle的DBWn进程:它的任务是将数据页的更改从缓存池中写入到数据文件中。有一点和Oracle不同的时候,在这里只有一个lazy writer进程负责写数据文件。其它还有一些后台进程是和SQLOS关联的:scheduler monitor,deadlock monitor和resource monitor等等。
top事务一致性(Transactional Consistency)和基于时间点的恢复(Point-in-time Recovery)
Microsoft SQL Server和Oracle一样内置都有针对于事务的保护机制。事务一致性的基本思想就是对于数据的更改不会马上反映到磁盘的文件当中,实际上这两者更新的都是被称为数据缓冲区(buffer cache)的内存区,同时还在一个称为日志缓存(log buffer)的内存中连续的记录对于数据所做的更改,这些内存区域的内容被不断的写入到磁盘文件当中。用于将数据缓存区和日志缓存区中的内容写入到磁盘文件当中的进程是两个不同的进程,不过将日志缓存的写入磁盘要比将数据缓冲写入磁盘要频繁的多了。现在当用户成功的提交一个事务时,他所做的更改并不会马上写入到数据文件中。不过这些变更会被记录到日志缓冲中,同时在发送提交成功的信息给用户之前这些相应的日志缓存数据会被写入到磁盘文件当中。正如之前所述,SQL Server将日志文件称为事务日志(Transaction Log),Oracle则称为重做日志(Redo Log)。在SQL Server术语中,保存数据更改记录的内存块称为日志缓存(Log Buffer),Oracle则称为重做缓存(Redo Buffer)。抛开命名的差异,实际日志文件的作用却是一样的:在服务器意外宕机之后,数据库服务器会在服务重新启动之后检查文件的内容,如果在日志文件中发现已提交的事务而在数据文件中不存在时,这些已提交的事务就会被重新应用到数据文件中;如果日志文件中的记录显示事务没有完成或者是回滚了,那反映到数据文件中的变化也同样会回滚。在这个过程中的第一个部分称为重做(REDO),第二个部分称为撤销(译注:这里英文为undo,也许说回滚合适些)。SQL Server为每个数据库单独的维护了一份事务日志,一份数据库事务日志可以存在有多个事务日志文件。事务日志文件在数据库创建的同时创建,之后也可以继续追加。对Oracle来说,数据库指的是素有的物理文件和逻辑的表空间。Oracle的重做日志会记录对于所有表空间的更改。一个Oracle数据库至少需要2个日志文件才能正常操作,当然日志文件可以多余2个,但是决不能少于2个。SQL Server事务日志和Oracle重做日志之间的一个重大的区别就在于事务日志没有逻辑分组一说,而重做日志则可以被分组在2个或更多个日志分组当中。每个Oracle数据库至少需要有2个日志分组,每个分组里面必须要有一个或多个日志文件,日志组中的日志文件被称为日志组成员(member)。Oracle每次都是将日志缓存中的重做日志一次写入到一个重做日志组中的所有文件中。在一个日志组中使用多个日志文件的容错技术称为多路技术(multiplexing)。在一个日志组写满之后,Oracle就会转到下一个日志组,这样的操作称为日志切换(log switching),在这个日志组满了之后又再转到下一个日志组,以此类推。当所有的日志都写满之后(不管是存在2个还是多个日志组),Oracle就会将第一个组中的日志清理掉,然后开启一轮新的写入循环。SQL Server数据库的事务日志一样是顺序写入的,只是如果数据库不是运行在简单恢复模式或者是事务日志做了备份的话,日志是不会被自动清除掉的。如果一个数据库的逻辑事务日志空间满了之后,它对应的数据文件还无法增长的话,数据将无法继续处理用户操作。不过如果事务日志做过备份的话,那么SQL Server就会让新事务重用那些已备份日志所占用的空间,从这点上来说,SQL Server的逻辑事务日志是以一种“回环(wrap-around)”的方式使用的。另外要强调的一点是SQL Server的事务日志文件的大小可以配置成自动扩展,而Oracle的重做日志文件则是有一个预定义大小的,如果不是手工更改这个大小的话,日志文件是不会自动增长的。就数据可用性而言,两种平台都提供了基于时间点恢复(point-in-time recovery)的选项,当然必要的话也可以禁止掉(这个在测试或开发系统中是可行的)。要是SQL Server数据库的基于时间点恢复的功能的话就必须是在完全恢复模式(full recovery mode)下。不管出于何种恢复模式,每次数据的修改都会被数据库记录在它对应的事务日志里面,这些日志会一直保留到事务日志备份备份的时候。数据库的恢复模式还能调整成简单恢复模式(simple recovery mode),这种情况下的产生的事务日志会在每次检查点(checkpoint)发生时截断。检查点操作会将所有数据缓冲中已修改的数据写入到数据文件中,日志缓存中的日志信息写入到日志文件中。如果数据库运行在简单恢复模式下,检查点完成之后所有的检查点之前完成的事务所产生的事务日志都会被删除掉,因此SQL Server已经确定这些旧的已提交的事务已经确定被写入到数据文件中去了。现在假设数据库检测到一个错误(物理的或逻辑的),这时都可以使用最后一个全备先还原数据库然后使用备份的事务日志恢复到还原的数据库上面,这种特性可以让数据库回到之前的任意一个时间点(译注:当然是指完全备份之后的任意一个时间点),只是这个特性只有在数据库使用完全恢复模式的时候才可用。Oracle中也有类似的概念。Oracle可以运行在归档模式(ARCHIVELOG)或是非归档模式(NOARCHIVELOG)下。在非归档模式下,当日志组链上的最后一个组写满之后就会覆盖第一个日志组,这时因为Oracle的重做日志组是按照循环使用的方式运作的。当然这也就意味着数据库是不能回到那些被删除了的事务记录所对应的时间点的。所以从功能上说,这就相当于SQL Server的简单恢复模式。当Oracle数据库运行在归档模式下时,它同时也会在后台启动一个或者多个归档进程(archiver),归档进程的作用就是在一个日志组满了之后将日志组的内容备份到放在磁盘上的文件中,这些保存的日志文件被称为归档日志(archived log),日志组在归档之后就可以放心的被覆盖了。自己想想就会发现Oracle重做日志组归档的功能其实和SQL Server事务日志备份是一样的,也是说Oracle的归档模式和SQL Server的完全恢复模式是一样的。Oracle和SQL Server一样,在还原全备之后可以使用归档日志进行还原。不同的时候SQL Server的事务日志备份需要手工的配置而Oracle只要配置了归档模式之后归档进行就会自动的进行日志归档备份操作。最后,从恢复时间(recovery time)上面也能看到两个平台的相似之处。在之前也提到过,在数据引擎启动时会经过一个重做和撤销的阶段,这个阶段所花费的时候称为恢复间隔(recovery interval)。很明显的数据库管理员是希望这个时间越短越好的,在SQL Server中DBA可以通过下面的命令来配置这个时间间隔:1 sp_configure 'show advanced option', 1  2 reconfigure  3    4 sp_configure 'recovery interval',   5 reconfigure 这个命令修改的是系统配置参数。设置好恢复间隔之后,SQL Server会自动调整检查点进程执行检查点的时间来满足这个设置的时间要求。设置这个恢复间隔的单位是分钟。Oracle中类似的设置就是平均恢复时间(Mean Time To Recovery, MTTR),可以通过修改初始化参数FAST_START_MTTR_TARGET来修改它,设置这个参数可以用来调整检查点执行的频率。这个值决定了Oracle再执行数据库崩溃恢复时所花费的时间,设置命令如下:1 ALTER SYSTEM SET FAST_START_MTTR_TARGET= SCOPE=spfile;
top系统元数据
不过是Oracle还是SQL Server,在数据库软件安装和数据库创建的时候,都会自动创建一大堆表以及其他诸如视图、函数、存储过程之类的对象。这些系统级的表包含的是实例和实例所用到的物理和逻辑属性的元数据,Oracle把这些表统称为数据字典(data dictionary),在SQL Server中则是称为系统表(system tables)。在SQL Server 2005及之后的版本,大部分的系统对象都保存在resource数据库中,少部分保存在master数据库中。Oracle中,数据字典表是保存在SYSTEM和SYSAUX表空间中。从SQL Server 2005开始是无法再直接访问系统表了,目录视图(catalogue views)取代系统表作为新的访问系统元数据的统一的接口。在Oracle中数据字典表名都是加密过的,藉此来减少表被直接访问或修改,同样的,Oracle也创建了一系列的视图用于给DBA和开发人员访问元数据,Oracle称这些视图为数据字典视图(data dictionary views)。目录视图的定义存储在SQL Server的resource数据库中,这些系统视图归属于一个特别的名为sys的用户架构之下(user schema)并能从任意数据库中访问到。例如,要查看一个SQL Server实例中存在的所有的数据库,DBA就可以在任意数据库下使用下面语句查询:1 SELECT * FROM  sys.databases 要查出任意一个数据库中的所有对象,则可以使用sys.objects目录视图:1 SELECT * FROM  sys.objects Oracle中,数据字典从属于Oracle用户SYS。不过不同于SQL Server的时候每个数据字典视图都存在有三种不同的形式,分别提供三个不同级别的信息。数据字典视图也就存在三个不同的类型,从视图名的前缀就能看出视图能带来什么样的信息:以USER_开头的视图允许用户查看他自己创建的对象的信息。
以ALL_开头的视图允许用户查看他自己创建的对象以及那些非他自己创建的却有权限访问的对象的信息。
以DBA_开头的视图是给DBA用的,这类的视图可以查询到数据库中存在的所有对象的信息,普通的用户是没有权限访问这些视图的。
下面的例子展示的两个查询返回的结果就是不一样的:1 SELECT TABLE_NAME, TABLESPACE_NAME FROM USER_TABLES;  2 SELECT TABLE_NAME, TABLESPACE_NAME FROM DBA_TABLES; 第一个只显示执行查询的用户自己创建的表而第二个则会显示数据库中存在的所有的表。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/shiweijian1986/archive/2010/04/27/5533579.aspx