读书频道 > 网站 > 网页设计 > DBA的思想天空:感悟Oracle数据库本质
1.3.1 什么是数据库实例
12-11-16    奋斗的小年轻
收藏    我要投稿   
本书重在介绍Oracle 数据库的性能调优方法及相应的工作思路,但并不拘泥于技术细节。作者结合多年的丰富经验,借助大量真实案例剖析了相关技术原理,阐述了理论知识在实践中的应用方法,并总结出思路是道,操作...立即去当当网订购

在实际的开发应用中,关于Oracle数据库,经常听见有人说建立一个数据库、建立一个实例(Instance)、启动一个实例之类的话。其实问他们什么是数据库、什么是实例,很可能他们会说“数据库就是实例,实例就是数据库啊,没有什么区别”。我只能说虽然他们使用了很长时间的Oracle数据库,也算积累了一定的经验,不过基础的概念还是不太清楚。

我们都知道,数据库就是存储数据的一种媒介,数据都是按照某种格式存储在某些特定的文件中的。我们比较早接触过的数据库,比如说DBASE、FOXBASE之类的,实际上更多地表现为一种记录管理系统,在文件中按照既定的格式存储了一些数据记录。早期开发DBASE应用的程序员可能还记得,最初的DBASE数据库都是单机环境的,因此在开发时不用考虑互斥和锁的问题,只需要按照业务要求处理记录就行了。后来有了NOVELL网,FOXBASE得到了广泛的应用。老白最早学习NOVELL网的时候也很困惑,对于FOXBASE能够在NOVELL网上运行感到十分神秘,后来明白了实际上NOVELL网为FOXBASE数据库提供了一个共享文件系统,FOXBASE正是通过NOVELL的共享文件系统在多个网络终端之间同步,这样一来在NOVELL网上的FOXBASE应用就十分容易理解了。在FOXBASE里,我们通过LOCK TABLE命令来锁定某张表,然后再对其进行访问和修改,这样就可以避免多用户环境下的冲突问题了。

刚才似乎扯得有点远了,反过头来,我们再来认识Oracle 数据库。Oracle 数据库是一种支持高并发的RDBMS系统,因此Oracle也需要解决在大量并发用户下的一致性访问问题。Oracle数据库对外提供的访问方式并不是应用程序直接打开数据文件来操作数据库,而是通过一种TWO-TASK的模式提供服务。在这种架构下,应用无法直接访问数据库,而必须通过一种被称为实例(Instance)的逻辑结构去访问数据库。

于是我们需要了解一个十分重要的新概念——实例。那么什么是实例呢?官方的说法,实例指的就是操作系统中一系列的进程以及为这些进程所分配的内存块。如果用更容易理解的方式来解释,那就是说Oracle数据库的实例是我们访问Oracle数据库的通道。

下面我们先来了解一些数据库实例的基础概念。在一个数据库实例中,包含了Oracle的共享内存和一系列的后台进程,一个实例在同时只能打开一个数据库,而一个数据库可以同时被多个实例打开,当然了,这种情况就是我们常说的RAC。Oracle数据库的实例必须依赖于某个特定的ORACLE_HOME,启动实例需要的所有的程序和相关的文件(除了数据库外)都包含在$ORACLE_HOME中。除此之外,每个实例都有自己独立的SID。在同一个ORACLE_HOME下,允许启动多个实例,但是这些实例必须拥有不同的SID。另外,一个非RAC的数据库是不允许被多个实例打开的,因为实例mount独立数据库的时候,是以排他的方式进行的。一个RAC的数据库,只允许同一个RAC集群中的多个实例打开,非相同集群的节点是无法打开同一个数据库的。

通过上面的介绍,我们了解了实例、数据库、ORACLE_HOME、SID这些概念之间的关系,下面我们进一步来了解实例。在Oracle中,我们可以启动一个Oracle的实例,这个时候虽然有了进程还有SGA等一系列的内存块,但是并没有把数据库文件读取进来。实例启动后,为访问Oracle数据库的应用提供了一个基础的环境。这个基础环境包含了一组共享内存,后者又包含了Oracle数据库的一系列内部数据结构,也包括了Oracle数据库的SQL和数据字典缓冲(共享池中的库缓存和字典缓存),还有数据块缓冲(DB Cache)。在一个启动了Oracle实例的UNIX系统上,使用ipcs命令可以看到共享内存的情况:
[oracle@ ~]$ ipcs
------ Shared Memory Segments --------
key          shmid      owner      perms      bytes         nattch status
0x9a8837b4   163840     oracle     640        1050673152    20
------ Semaphore Arrays --------
key          semid      owner      perms      nsems    
0x03c13d24   753664     oracle     640        154

我们可以看到,Oracle 用户分配了一组共享内存和信号灯,这和我们在UNIX下编写具有共享内存的应用程序并无不同。实例启动时首先会装载参数文件,根据参数文件中定义的内存相关参数创建共享内存和信号灯,然后将参数文件装载到共享内存中被称为ksppi的内存区域,同时将当前实例的参数装载到一个独立的区域——ksppsv。根据参数文件,启动进程完成SGA中内存结构的初始化工作,然后启动相关的后台进程。这个过程完成后,数据库实例启动的第一步nomount就完成了。

实例启动到nomount后,所有的共享内存和后台进程就都已经装载完毕。于是,系统根据参数文件中控制文件的位置,打开控制文件,并对控制文件进行校验,如果这个步骤没有发现问题,就完成了mount步骤。

数据库实例mount完成后,通过对控制文件、UNDO和REDO等进行比对分析后,发现数据库状态是一致的,数据库实例就可以打开数据库了。数据库打开后,数据库实例就可以提供对外服务了。

数据库实例启动过程在很多书中都有十分详细的介绍,因此本节就不再赘述。数据库实例启动后,应用程序就可以通过数据库实例来访问数据库了。

应用要访问Oracle数据库,可以通过三种方式:第一种方式是应用进程直接访问数据库实例的共享内存,第二种方式是通过beq协议在本机上访问,第三种方式是通过网络协议访问。第一种方式使用的场合很少,我们不做讨论。下面着重讨论通过第二种和第三种方式访问数据库。

首先,后两种访问数据库的方式都是基于two-task结构的,都需要在数据库服务器上建立一个服务进程(server进程,或者前台进程)来为客户端应用服务(在这里我们只讨论独立服务器模式,共享服务器模式十分类似,我们将在后面进行专题描述)。two-task架构下访问数据库,首先需要在服务器端创建一个进程,这个进程启动时先要映射共享内存,然后才能够通过共享内存中的内部数据结构完成会话的初始化工作。

在本机上不经过SQL*Net连接数据库,前台进程和用户进程之间通过IPC机制进行通信,通信协议就是著名的Bequeath协议,简称BEQ协议。而如果通过SQL*Net连接数据库,那么就需要使用网络协议。现在TCP/IP协议已经成为使用最为广泛的协议,因此我们主要面对的是TCP/IP协议,而10多年前,著名的SPX协议、DECnet协议、Token Ring协议等都曾经是DBA进程配置的协议。使用SQL*Net协议的前台进程和用户进程之间的通信采用Socket通信。实际上,在服务器上,我们也可以使用SQL*Net连接数据库,只不过我们很少会去这样做,因为BEQ协议在效率上高于Socket通信。

除了使用的协议不同,在本机上通过BEQ协议连接数据库实例和通过SQL*Net连接数据库实例还有什么不同吗?很多DBA可能会感觉有所不同,因为在本机上直接连接数据库协议,前台进程是shell进程产生的子进程;而通过SQL*Net连接数据库实例,server进程是LISTENER(tnslsnr)产生的子进程,如果监听器进程的属性不同,那么产生的子进程会和shell直接产生的子进程有所不同。这一点不同在早期的Oracle版本中确实存在,而自从$ORACLE_HOME/bin/oracle这个映像文件被设定为s属性后,这个问题就不存在了。Oracle映像通过s属性可以将子进程的属性转为Oracle用户。

不过使用BEQ协议和网络协议在服务进程方面还是有所不同的,BEQ协议通过IPC通信,因此不需要使用Socket,而通过网络协议(SQL*Net)连接,客户进程最初连接的是tnslsnr进程,tnslsnr进程接受了连接请求后,为其创建一个子进程,然后通知客户端进程重新连接到子进程上继续工作。在这个时候,就存在一个Socket重定向的问题。监听器产生子进程时会为新的连接分配一个未被使用的端口号,这个子进程启动后就在该端口上侦听,同时监听器会通知客户端进程,要求其重定向到新的端口号。此时客户端进程会关闭老的Socket,并打开一个新的Socket,完成登录操作。

可能有些DBA对上面的讨论感到有些迷茫了,怎么讨论实例的问题,一下子又转到了监听器的工作机制上了,这些知识对于DBA又有什么作用呢?我们刚才一直在强调实例是客户端访问数据库的通道,因此讨论客户端如何通过监听器连接数据库就十分有意义了。

首先第一点,现在很多客户对系统安全性要求很高,因此服务器上大量的网络端口是被封掉的,只有必须使用的才会被开放。那么对于Oracle数据库来说,我们只需要开放监听器所需要的端口就可以了吗?事实上不是这样的,除了开放类似1521的监听端口外,我们还需要开放一些高端口,这些端口将被用于Socket重定向。

可能很多用户在客户端连接数据库的过程中经常会碰到TNS-12535之类的错误,开始的时候总是从网络超时的角度去分析,不过这样分析往往很难找到真正的故障原因。这类问题在一个存在防火墙的环境中,往往是由于在防火墙环境下的Socket重定向引起的,特别是在有NAT功能的防火墙上,这类问题很容易出现。客户端连接的是一个NAT翻译后的IP地址,而重定向的时候,监听器要求客户端连接到真实的IP地址上,这样就会出现连接超时导致的失败。这种情况一般的解决方案是使用connect manager(CMAN),老白也曾经碰到过几个这样的客户,最后都是通过CMAN来彻底解决问题的。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1.3 功能
下一篇:1.5 小结
相关文章
图文推荐
JavaScript网页动画设
1.9 响应式
1.8 登陆页式
1.7 主题式
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站