csq39 发表于 2017-9-8 08:42:37

ORACLE中SID和SERVICE_NAME的区别

本帖最后由 csq39 于 2017-9-8 08:46 编辑

<p><br/></p><p><br/></p><p>先来讲一个小故事,2015年6月份,有个客户迁移了数据库,由单实例数据库变成了RAC。JAVA应用程序出现了无法连接数据库的情况,但是PL/SQL能连接上数据库。由于项目比较庞大,虽然在半夜切换的,但是也不能接受长时间的业务停顿。当时,我对ORACLE技术也只是略知皮毛。在咨询过公司研发后,他们给我的建议是:参考PL/SQL的连接参数,将spring中jdbc连接的url由</p><pre class="brush:java;toolbar:false">jdbc:&nbsp;oracle:thin:&nbsp;@10.2.0.2:1521:&nbsp;orcl</pre><p>改为</p><pre class="brush:java;toolbar:false">jdbc:&nbsp;oracle:thin:&nbsp;@(DESCRIPTION&nbsp;=(ADDRESS_LIST&nbsp;=(ADDRESS&nbsp;=(PROTOCOL&nbsp;=&nbsp;TCP)(HOST&nbsp;=&nbsp;10.2.0.2)(PORT&nbsp;=&nbsp;1521)))(CONNECT_DATA&nbsp;=(SERVICE_NAME&nbsp;=&nbsp;orcl)))</pre><p>,结果问题解决了,当时我挺佩服公司研发的。现在看来,这个并不是最佳的解决方案,下面通过讲解SID和SERVICE_NAME的区别,我将给出更佳的解决方案。<br/></p><p><br/></p><p>在讲解SID和SERVICE_NAME之前,先说一下实例。实例是操作系统中访问数据库所需要的一系列的进程和内存的集合。即使没有任何数据文件,实例也可以启动。但是要想访问数据库,必须把数据库文件加载进实例中。实例和数据库的区别可以简单概括为:实例是临时的,它只在相关的进程和内存集合存在时存在,而数据库是永久的,只要文件存在它就存在。一个实例只能对应一个数据库,但是一个数据库可以由多个实例对应(如RAC)。RAC就是多个实例同时打开一个数据库文件的系统,在结构上是多台机器,每台机器运行一个实例,每个实例都打开同一个数据库 (这个是用磁盘共享技术实现的),这些实例之间需要同步高速缓存,这样保证多个实例是完全一致的,不会相互冲突乃至覆盖。</p><p><br/></p><p>SID即INSTANCE_NAME是用来唯一标示实例的。SERVICE_NAME是oracle8i新引进的,8i之前,一个数据库只能由一个实例对应,但是随着高性能的需求,并行技术的使用,一个数据库可以由多个实例对应了,比较典型的应用如RAC。为了充分利用所有实例,并且令客户端连接配置简单,ORACLE提出了SERVICE_NAME的概念。该参数直接对应数据库,而不是某个实例。</p><p>了解了SID和SERVICE_NAME之后,我突然觉得前面故事中使用的解决方案并不是最佳的解决方案,因为SERVICE_NAME的出现就是为了应对并发技术,简化客户端连接配置。通过SERVICE_NAME应该能找到更好的解决方案。通过查找JDBC帮助得知JDBC连接ORACLE的方法由三种:</p><p><br/></p><p>格式一:</p><pre class="brush:java;toolbar:false">jdbc:&nbsp;oracle:thin:&nbsp;@//&lt;host&gt;:&lt;port&gt;/&lt;service_name&gt;</pre><p>格式二:</p><pre class="brush:java;toolbar:false">jdbc:&nbsp;oracle:thin:&nbsp;@&lt;host&gt;:&lt;port&gt;:&lt;SID&gt;</pre><p>格式三:</p><pre class="brush:java;toolbar:false">jdbc:&nbsp;oracle:thin:&nbsp;@&lt;TNSName&gt;</pre><p>不难看出,故事中使用RAC之前,JDBC是使用格式二连接的,使用RAC后实例增多了,SID已经不唯一,格式二已经无法完全利用所有资源。研发参考PL/SQL的连接方法刚好碰巧使用了格式三。因为java应用服务器跟数据库服务器是分离的,应用服务器上没有oracle的服务端以及客户端。虽然解决方案中没有使用TNSName,但是使用了TNSName的连接描述,效果是一样的。</p><p><br/></p><p>既然JDBC有三种连接方案,我们不妨再看一下第一种方案。再加上前面的讲解内容,我想大家已经都知道故事中的问题该怎么修改了,只要改成</p><pre class="brush:java;toolbar:false">jdbc:&nbsp;oracle:thin:&nbsp;@//10.2.0.2:1521/orcl</pre><p>就可以了,而且这种格式也支持单实例数据库。这也是ORACLE在8i之后增加SERVICE_NAME的初衷。<br/></p><p>通过这个故事,我们可以看到,只有充分了解了ORACLE的知识,才能更好的使用ORACLE技术。</p><p><br/></p>
页: [1]
查看完整版本: ORACLE中SID和SERVICE_NAME的区别