高铭杰
2017年10月
当我们发出一条命令:sqlplus bys/bys@orcl121时,连接到数据库大致经过以下步骤:
- 首先在sqlplus程序的相关目录中查找tnsnames.ora
- 在tnsnames.ora中查找
orcl121=
开头的字符串 - 根据tnsnames.ora中查找
orcl121=
字符串中的查询相应的HOST,如是IP,则直接访问;如是域名,需要解析为IP(PROTOCOL = TCP)(HOST = 192.168.1.92 )(PORT = 1521)
- 如果以上连接成功,则已经连接到数据库监听器。此时tnsnames.ora中查找
orcl121=
字符串中的:SERVICE_NAME = orcl121
,这一句则再次指定了要连接到监听器的orcl121服务上 - 如果以上连接成功,已经连接到监听器的orcl121服务,则会根据监听器中服务所对应的实例,来连接到具体的实例。
- 如果以上连接成功,则已经连接到实例。接下来就由数据库来验证用户名、密码的正确性了。
sqlplus jackgo/333@orcl121连接到数据库的步骤来对每一步进行错误演示
sqlplus jackgo/333@192.168.1.92:1521/orcl121 这样连接不走tnsname.ora sqlplus jackgo/333@orcl121 这样连接会走tnsname.ora
-
tnsnames.ora文件不存在。此时使用本地名来连接是不行的。
[oracle@localhost admin]$ tnsping orcl121 ... OK (0 msec) [oracle@localhost admin]$ cd /u01/app/oracle/product/12.1.0/dbhome_1/network/admin [oracle@localhost admin]$ mv tnsnames.ora tnsnames.ora.bak [oracle@localhost admin]$ tnsping orcl121 ... TNS-03505: Failed to resolve name
-
tnsnames.ora 中orcl121本地名对应的字段描述格式正确,数据库监听开启。但是使用TNSPING或SQLPLUS时所用的本地名不对。
[oracle@localhost admin]$ tnsping hello ... TNS-03505: Failed to resolve name
-
tnsnames.ora 中orcl121本地名对应的字段描述格式正确,数据库监听开启。但是tnsnames.ora 中HOST = 字段指定的IP不存在或无法PING通。
[oracle@localhost admin]$ tnsping orcl121 ... TNS-03505: Failed to resolve name
作用类似于linux 或者其他unix 的nsswitch.conf 文件,通过这个文件来决定怎么样找一个连接中出现的连接字符串。
例如我们客户端输入
sqlplus sys/oracle@orcl
假如我的sqlnet.ora 是下面这个样子
SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES,HOSTNAME)
那么,客户端就会首先在tnsnames.ora文件中找orcl的记录. 如果没有相应的记录则尝试把orcl 当作一个主机名,通过网络的途径去解析它的 ip 地址然后去连接这个ip 上GLOBAL_DBNAME=orcl
这个实例,当然我这里orcl 并不是一个主机名
如果我是这个样子
NAMES.DIRECTORY_PATH= (TNSNAMES)
那么客户端就只会从tnsnames.ora查找orcl的记录, 括号中还有其他选项,如LDAP 等并不常用。
客户端与服务器端通讯的协议,一般为TCP ,该内容一般不用改。
数据库侦听所在的机器的机器名或IP 地址,数据库侦听一般与数据库在同一个机器上,所以当我说数据库侦听所在的机器一般也是指数据库所在的机器。在UNIX 或WINDOWS 下,可以通过在数据库侦听所在的机器的命令提示符下使用hostname 命令得到机器名,或通过ipconfig(for WINDOWS) or ifconfig (for UNIX )命令得到IP 地址。需要注意的是,不管用机器名或IP 地址,在客户端一定要用ping 命令ping 通数据库侦听所在的机器的机器名,否则需要在 hosts 文件中加入数据库侦听所在的机器的机器名的解析。 PORT :数据库侦听正在侦听的端口,可以察看服务器端的listener.ora 文件或在数据库侦听所在的机器的命令提示符下通过lnsrctl status [listener name] 命令察看。此处Port 的值一定要与数据库侦听正在侦听的端口一样。
在服务器端,用system 用户登陆后,sqlplus> show parameter service_name 命令察看。
对应的本机,SALES 对应的另外一个IP 地址,里边还定义了使用主用服务器还是共享服务器模式进行连接
ORCL =
(DESCRIPTION =
(ADDRESS_LIST =
# 下面是这个TNSNAME 对应的主机,端口,协议
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
)
(CONNECT_DATA =
# 使用专用服务器模式去连接需要跟服务器的模式匹配,如果没有就根据服务器的模式自动调节
(SERVER = DEDICATED)
# 对应service_name ,SQLPLUS>;show parameter service_name; 进行查看
(SERVICE_NAME = orcl)
)
)
# 下面这个类似
SALES =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = dg1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = sales)
)
)
监听器进程的配置文件,接受远程对数据库的接入申请并转交给oracle 的服务器进程。所以如果不是使用的远程的连接,并且不需要使用OEM时,listener 进程就不是必需的,同样的如果关闭listener 进程并不会影响已经存在的数据库连接。
# Generated by Oracle configuration tools.
# 下面定义LISTENER 进程为哪个实例提供服务 这里是ORCL ,并且它对应的ORACLE_HOME 和GLOBAL_DBNAME 其中GLOBAL_DBNAME 不是必需的除非
# 使用HOSTNAME 做数据库连接
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl121)
(ORACLE_HOME = /u01/app/oracle)
(SID_NAME = ORCL)
)
)
# 监听器的名字,一台数据库可以有不止一个监听器
# 再向下面是监听器监听的协议,ip,端口等,这里使用的tcp1521端口,并且使#用的是主机名
LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = dg1)(PORT = 1521))
)
$ORACLE_HOME/bin/lsnrctl start