Oracle sid_name 和service_name的区别

目录

问题: 

排查一:

排查二:

jdbc连接oracle的方式 


问题: 

kettle连接Oracle时候报错:

错误连接数据库 [MFG Prod] : org.pentaho.di.core.exception.KettleDatabaseException: 
Error occurred while trying to connect to the database

Error connecting to database: (using class oracle.jdbc.driver.OracleDriver)
Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
 


org.pentaho.di.core.exception.KettleDatabaseException: 
Error occurred while trying to connect to the database

Error connecting to database: (using class oracle.jdbc.driver.OracleDriver)
Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor

排查一:

连接另外一个Oracle数据库都是正常的,经过查询两个Oracle的版本不一致,可能是oracle jar包版本的问题

于是像这位前辈学习了一下:

Oracle数据库的驱动包ojdbc*.jar之间的差别 - elleniou - 博客园

尽量使用和数据库版本一致的驱动,有bug时,换高版本的JDBC驱动试试 。

换成对应的jar包还是报错,排除jar不兼容问题。

排查二:

最后查到的原因如下

查找资料得知:

jdbc连接数据库的时候,需要使用数据库的sid_name,而不是数据库的services_name
而使用plsql连接数据库的时候,只需要数据库的services_name即可,所以修改连接字符串中的services_name (即连接参数中的database name)为sid_name。

现在很多工具提供了两种连接方式,例如dbeaver

 

 因为这个工具是java写的,底层还是jdbc,应该也是会转化为下面的方式去连接。

通过查找JDBC帮助得知JDBC连接ORACLE的方法由三种:

格式一:jdbc:oracle:thin:@//<host>:<port>/<service_name>
格式二:jdbc:oracle:thin:@<host>:<port>:<SID>
格式三:jdbc:oracle:thin:@<TNSName>

jdbc连接oracle的方式 

# jdbc连接oracle实例 
driverClassName: oracle.jdbc.driver.OracleDriver
 url: jdbc:oracle:thin:@10.2.1.22:1521:testdb1
 username: abc
 password: 123
# jdbc连接oracle service_name      
 driverClassName: oracle.jdbc.driver.OracleDriver
 url: jdbc:oracle:thin:@10.2.1.5:1521/PRODDB
 username: adm
 password: admin

在操作系统中要取得与数据库之间的交互,必须使用数据库实例名。例如,要和某一个数据库server连接,就必须知道其数据库实例名,只知道数据库名是没有用的,与数据库名不同,在数据安装或创建数据库之后,实例名可以被修改。

那么sid_name 和service_name 到底有什么区别?

1.数据库实例名(SID)
什么是数据库实例名?
数据库实例名是用于和操作系统进行联系的标识,就是说数据库和操作系统之间的交互用的是数据库实例名。实例名也被写入参数文件中,该参数为instance_name,在win平台中,实例名同时也被写入注册表。
数据库名和实例名可以相同也可以不同。
在一般情况下,数据库名和实例名是一对一的关系,但如果在oracle并行服务器架构(即oracle实时应用集群)中,数据库名和实例名是一对多的关系。(MFG的PROD是如此,最著名的是如RAC技术)

一个serice name 对应多个 sid name. 

2.数据库服务名(SERVICE_NAME)
什么是数据库服务名?
从oracle9i版本开始,引入了一个新的参数,即数据库服务名。参数名是SERVICE_NAME。
如果数据库有域名,则数据库服务名就是全局数据库名;否则,数据库服务名与数据库名相同。
 

tnsname.ora  如下

配置tnsname.ora时,可以用SID,也可以用SERVICE_NAME.  注意这两个值不一定相同,具体要看数据库服务器中的配置。

connect_data对应的是SID还是SERVICE_NAME? 如果是SID则对应该数据库的实例名称(instant_name),如果是SERVICE_NAME的话则填写数据库服务名,即全局数据库名

PS:查看数据库的sid_name语句:

select INSTANCE_NAME from v$instance;

总之jdbc连接数据库的时候是sid_name;

      psql连接数据库的时候是service_name;

我们平常使用工具连接的都属于psql连接,kettle是通过java jdbc接口连接DB的,故应该为sid_name,事实上,多数的数据库两者一致,导致我们忽视了此问题。

参考文章:ORACLE中SID和SERVICE_NAME的区别 - lclc - 博客园