前言
本篇文章将针对Oracle的登录方式进行整理,同时对数据库、实例、服务这几个常用的概念进行辨析,文章里面会拓展到一些Oracle的一些版本特性,也是其他文章所很少提及的,通过阅读这篇文章相信可以给初识Oracle的读者一定的指引。
一、SQL Plus的登录方式
不考虑jdbc驱动连接数据库的情况下,我们一般连接oracle更多的都是选择使用安装oracle时自带的sqlplus来完成登录以及数据库sql语句的执行工作。而sqlplus连接数据库的方式大致可以分为以下三种
方式一:启动sqlplus进程并连接oracle
sqlplus {<username>[/<password>][@<connect_identifier>]}
处于{}
内的参数为非必填参数,我们可以在控制台输入sqlplus
命令后,根据提示再输入用户名和密码来连接数据库,也就是说输入用户名密码等操作和启动sqlplus
客户端是分开执行的。(由于不是在一个命令中完成数据库的连接动作,所以这种情况下我们输入的用户名和密码都是无法通过history
命令查看的!)
但是这种做法有个弊端,默认情况下sqlplus
不会询问我们想要连接的实例,只会帮助我们尝试登录当前本地服务器的oracle
实例,但更多的时候我们是希望访问其他服务器上面的oracle。好在sqlplus
的语法十分给力,它支持我们根据实际需要来完成不同的操作,比如以下命令:
# 直接指定用户名(默认登录本地数据库实例)
sqlplus username
# 直接指定用户名和密码(默认登录本地数据库实例)
sqlplus username/password
# 直接指定用户名,密码和连接的实例
sqlplus username/password@<connect_identifier>
需要注意的是,直接在命令行中输入密码是十分不安全的行为,所以虽然sqlplus支持我们通过一个命令就实现客户端启动以及连接oracle,但建议还是不要直接通过这种方式登录,避免暴露数据库的密码。
关于<connect_identifier>
我们在上文中提到通过指定<connect_identifier>
来完成实例的指定,那具体如何,这里我们不妨看一下官方的介绍
<connect_identifier> can be in the form of Net Service Name or Easy Connect.
@[<net_service_name> | [[//]Host[:Port]/<service_name>] |
[[[protocol:]//]host1{,host12}[:port1]{,host2:port2}[/service_name]
[:server][/instance_name][?[parameter_name=value]
{¶meter_name=value}]]]
<net_service_name> is a simple name for a service that resolves to a connect descriptor.
Example: Connect to database using Net Service Name and the database net service name is ORCL.
sqlplus myusername/mypassword@ORCL
Host specifies the host name or IP address of the database server computer.
Port specifies the listening port on the database server.
<service_name> specifies the service name of the database you want to access.
Example: Connect to database using Easy Connect and the Service name is ORCL.
sqlplus myusername/mypassword@Host/ORCL
简单来说,这里的<connect_identifier>
其实就是数据库的“网络服务名”或者“连接别名”
这里的格式根据实际情况有很多种写法,按笔者的经验来看的话,最常见的写法是ip:port/service_name
以及net_service_name
。比如下面这两个例子,如果希望连接的是非本地服务器的oracle
,那么只能用前者这种写法来连接。
# 适用于连接非本地数据库,且tnsnames.ora文件中配置的服务名为orcl
sqlplus SCOTT/SCOTT@//10.108.108.108:1521/orcl
注意:这里的//可以省略
# 适用于连接本地数据库,且tnsnames.ora文件中配置的网络服务名为ORCL
sqlplus SCOTT/SCOTT@ORCL
方式二:以无日志的方式登录,暂不连接数据库(最推荐!)
方式二其实和方式一没有差别太多,主要区别在于它真正意义上把启动sqlplus
应用和连接oracle
的步骤分离了,分离带来的好处就是不需要担心操作过程中密码登敏感信息会在操作记录中泄露。
而且比方式一更好的地方是,方式二可以既实现敏感数据的隐藏,又可以实现指定连接的凭证信息(也就是<connect_identifier>
)
sqlplus /nolog
conn SCOTT/SCOTT@10.108.108.108:1521/orcl
方式三:以当前用户的凭证直接进行登录(最简单)
在sqlplus中,单个斜杠(/
)用作快捷方式,代表当前用户的操作系统用户名。当使用/
作为用户名时,sqlplus
会尝试使用操作系统的凭据来认证用户,而as sysdba
这部分指定了要以 sysdba
角色连接到数据库。
这种方式下,不需要再额外手动输入用户名和密码进行登录了,但是同样有以下的限制
- ① 只能连本地的数据库实例
- ② 要求当前登录的用户具备dba的权限
二、一些知识点拓展
(一)登录并执行sql脚本
我们在写一些定时任务的时候,可能会需要使用到sqlplus
来完成数据库的表操作,出于简化操作考虑,我们有时候会希望把把登录动作和执行sql文件的动作放在一起执行,这一点sqlplus
也是支持的。我们可以通过下面的语法来实现:
sqlplus username/password@<connect_identifier> @sql_file_name
比如:sqlplus scott/scott@ORCL @update_name.sql
(二)关于数据库(名)、实例(名)、服务名的名词解释和辨析
数据库(名)
在oracle中,数据库可以理解为是存储数据的媒介,像数据文件,控制文件以及REDO文件 都是属于数据库中的一部分。一台服务器上面可以装多个数据库,为了更好的进行不同数据库的区分,oracle使用了数据库名来解决这个问题,不同的数据库拥有各自的数据库名。
数据库名的查询
方式1:SELECT NAME FROM V$DATABASE;
方式2:show parameter db(需要先连接sqlplus)
方式3:select global_name from global_name;
实例(名)
实例指的操作系统中一系列的进程以及为这些进程所分配的内存块,简单来说就是数据库服务端应用。实例创建出来后此时是并不能真正对外提供服务的,还需要去和数据库进行关联,把数据库加载到实例中,此时实例才能对外提供完整的服务,否则数据库实例也只是一个空架子而已。
数据库实例可以在脱离数据文件的情况下直接启动 (start unmount
),但一般情况下这种操作并没有太大意义,也就是说数据库实例和数据库是缺一不可的!同时,数据库实例只能挂载一个数据库,二者的关系是一对一或者多对一(oracle8i
推出RAC模式后,支持多个实例同时连接一个数据库)。
PS:直到在oracle12c
推出多租户特性之后,数据库实例和数据库之间才有了1对多的关系
实例名的查询
方法1:select instance_name from v$instance;
方法2:show parameter instance
实例和数据库的多对一:RAC模式
什么情况下,多个数据库实例会同时对应一个数据库呢?这就要提到Oracle的RAC模式了(Real Application Clusters)。实例和数据库如果是1对1的关系的话,我们很容易联想到如果实例突然挂了,那么必然会导致我们的应用不可用,也就是说存在单点问题,RAC模式的存在就是为了解决这个问题的
RAC模式本质上就是通过多实例的方式来实现集群的效果,达到服务的高可用。和常见的主备架构不同,RAC模式下所有节点均可对外提供服务,也就是说,两个节点的集群节点间是一种并行运行的关系,当一台机器出现问题,请求会自动转发到另一台机器,没有任何一台机器作为备用机一直不被使用,这样就充分利用了服务器资源。同时,传统的双机热备构架在出现问题时,常常需要数分钟的切换时间,而RAC在出现问题时,针对存在的会话只需要数十秒的时间就可以完成失败切换过程,对新会话的创建不会产生影响,在切换时间上也有比较大的优势。
当然了,RAC模式厉害之处不只是高可用,还有高性能。Oracle 的主要创新是一项称为高速缓存合并的技术。高速缓存合并使得集群中的节点可以通过高速集群互联高效地同步其内存高速缓存,从而最大限度地低降低磁盘 I/O。
服务名
服务名其实并不是在Oracle刚刚推出就有的一个概念,在Oracle 8i
之前一个数据库只能有一个实例,Oracle8i
之后一个数据库可以对应多个实例,例如RAC。为了充分利用所有实例。多个实例虽然提升了数据库的性能,但也给客户端的连接带来了不便,对客户端来说其实并不关注当前连接的是哪个实例,它只是想访问数据库而已。
为了令客户端连接配置简单,ORACLE提出了SERVICE_NAME
的概念。服务名其实就是为了方便客户端连接数据库,允许我们给多个实例同时定义一个“外号”,方便客户端连接。
不过服务名的存在从Oracle12c推出多租户特性之后,也慢慢退出使用了,在oracle19c之后,官方已经标识弃用ServiceName了,并且可能在后续的版本中不再支持。我们可以从官方的文档中看到对这个概念的介绍
Oracle官方解释地址:https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/SERVICE_NAMES.html
PS:虽然官方说不支持这个参数了,不过笔者认为目前连接oracle数据库暂时还是离不开SID
或者Service Name
,所以该用还得用。
服务名的查询
- 方式1:show parameter service_name
- 方式2:可以在tnsname.ora文件里面看配置
对于oracle12c之后的版本,由于存在可拔插数据库(也就是PDB),用方式1、2查到的结果可能是CDB的ServiceName,所以我们要换种方式来查询服务名
- 方式3:通过动态视图进行查询
SELECT CDB FROM "V$DATABASE";
(看数据库是否属于CDB数据库,如果结果为NO,就直接用方式1,2就行)
SELECT NAME,PDB FROM V$SERVICES;
或者SELECT NAME FROM V$PDBS;
(三)关于登录PDB数据库的简化操作
在oracle12c之后,由于多租户特性的存在,我们在连接数据库时往往进入到的数据库是CDB,而不是实际存储数据的PDB,直接登录的话往往会报错(因为我们的用户是创建在PDB数据库上面的)。出于简化登录操作考虑,我们可以用以下方式来进行优化
方式1:通过配置ORACLE_PDB_SID环境变量
假如说PDB库的服务名为pdb1,那么只需要在/etc/profile文件中配置一下ORACLE_PDB_SID=pdb1后,source /etc/profile即可。
PS:笔者亲试,这种做法只适合sysplus / as sysdba;这种登录方式,其他登录方式照常还是默认切换到CDB库的。
方式2:通过tnsname.ora
进行配置(有用)
在本地的tnsname.ora
文件中,给需要连接的PDB配置Service Name
PDB1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 具体IP)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = pdb1)
)
)
后续通过sqlplus username/password@PDB1
的方式就可以实现快速连接了,不再需要输入IP:PORT/ServiceName
的认证信息。
PS:这种方式适用于大部分场景,也十分简便,比较推荐使用。
方式3:显示指定service name
其实这种方式就相当于是登录的时候显示的先指定好,我要用哪个服务,至于存储数据库的服务名我们可以在前面介绍的方式中进行获取。
sqlplus username/password@ip:port/service_name
ps:大部分情况下,service_name和pdb_name是一致的
参考文章
oracle 数据库、实例、服务名、SID https://www.cnblogs.com/ahudyan-forever/p/6016784.html
oracle 实例名和服务名以及数据库名区别 https://www.cnblogs.com/lcword/p/7421622.html