对于Oracle初学者,甚至有些经验的Oracle DBA来说,Oracle的账户登录问题往往非常棘手,即便成功登录oracle也是知其然而不知其所以然。作者经过系统学习和反复实践,本着打破砂锅问到底的态度,总算对Oracle的登录原理与操作细节有了较全面的认识。本文记录下这些体会与经验,希望能帮助Oracle初学者自信地顺利登录oracle。
1 学习本文的先决条件
Oracle相关的知识很多,但一些基本的术语是所有dba都应该熟悉的。为更好的理解本文内容,读者需要理解如下术语: Instance和Database,IP/TCP,sqlplus,Oracle 账号与操作系统账号, Oracle DBA。
2 Oracle登录概述
2.1 Oracle的C/S架构与通信协议
Oracle软件的整体架构是基于C/S的,按照功能分为客户端和服务器端。客户端负责接受用户的输入和接收并显示来自服务器端的结果,常见客户端有Sql Developer, SqlPlus;服务器端则负责解析来自客户端的SQL请求,并把结果返回给客户端。
任何C/S架构的软件,通信部分都是至关重要的,重中之重就是通信协议的设计了。Oracle也不例外,采用的通信协议被称为oracle net。它是一个应用层协议,目前oracle net可以运行在很多底层协议上,如TCP, 安全TCP,命名管道,SDP等。另外,针对不同的底层操作系统平台,oracle net也支持操作系统的本地进程间通信协议。
无论底层是什么平台,无论客户端软件是什么、运行在哪里,客户端和服务器通信只能采用唯一的Oracle net协议,别无它方。
2.2 oracle账户与验证方式
通过账户进行权限控制是很多软件采取的方法,例如每个OS都有自己的账户。Oracle也不例外,要想进入Oracle进行操作,必须以某种身份进入,这就是Oracle的账户。Oracle账户按照权限大致分为特权账户和普通账户。特权账户拥有极大的权限,而而普通用户的权限受到很大限制。典型的特权账户就是SYS,SYSTEM。
那么oracle是如何对账户进行验证的呢?答案是有很多种方式,最容易理解的就是本地密码验证了,另外还有使用OS账户验证、利用LDAP验证、以及Kerberos等外部验证。本文只涉及最基本的密码验证方式。
3 Oracle侦听与密码存放
3.1 两种服务器端侦听程序
前面说过Oracle net支持多种底层通信协议,其中包括操作系统本地的进程间通信协议。 无论底层是何种协议,服务器端程序必须进行某种形式的侦听,以等待来自客户的连接请求。
(1)网络侦听程序tnslsnr
当底层协议是网络协议时,Oracle tnslsnr提供侦听服务。这是一个单独的进程,与其他进程独立。下面是Oracle专用服务器工作方式下的侦听器工作示意图。
如上图所示,客户端进程首先与侦听器连接(红色连线),并验证账户与权限,如果所有验证通过,侦听进程负责产生出一个新的服务器进程,并让客户端进程和新产生的服务器进程直接连接(蓝色连线),称之为一个会话,同时自身断开与客户端的连接,并与新建立的会话不再有任何关系。可见侦听进程起到了一个牵线的作用。之后,即使侦听器停止了工作,已经建立的会话也丝毫不受影响。
(2)本地侦听程序
本地侦听程序与网络侦听器完全不同,它不需要网络协议栈,具体实现严重依赖于底层OS。在Oracle中,本地侦听与tnslsnr完全独立。在Linux平台的本地侦听不需要执行任何程序。也就是说本地登录不依赖于tnslsnr。这对于dba是很实用的,当侦听器发生故障不能正常工作时,我们仍然可以通过本地连接来登入oracle进行操作。
3.2 两种密码存放方式
本文只关心本地密码方式的验证。
(1)密码存放在数据字典中
此时要想验证密码,数据库必须处于打开状态,大多数普通用户的密码都是按照这种方式存放的。密码存放于数据字典中会带来一个问题,那就是数据库打开之前,数据字典不可用,从而账户密码也无法得知,导致用户无法登录。这对于DBA来说是个致命的问题,试想某一天数据库出现问题无法加载,此时DBA必须登入系统进行修复,如果DBA账户的密码存放在数据字典中,要想登录必须先打开数据库,这岂不是陷入死循环了。所以oracle规定凡是具有DBA特殊权限的账户的密码信息会自动复制一份存放到外部文件中。
(2)密码存放在外部文件中
这个密码文件通常的存放位置是@ORACLE_HOME/dbs/orapw$SID。需要注意的是,只有具有DBA权限的账户密码才会存放到外部文件中,而且是在授予特殊权限时系统自动添加的,不能手工修改外部密码文件。
4 Oracle登录的几种情形分析
4.1 本地侦听+无需密码
使用前提:
(1)客户端与服务器端运行在同一机器上;
(2)使用安装oracle的OS账户登入OS;
(3)设置了$ORACLE_SID环境变量。
连接字符串:
此时,的连接字符串必须为 connect / as sysdba。
使用场景:
值得说明的是,这种情况下,登录成功的唯一前提就是需要指定$ORACLE_SID环境变量。不需要侦听器,也不需要数据库加载,甚至不需要实例启动。如上图所示,实例没有启动。此时,会默认使用oracle的sys账户登录。
这种情形的使用情况是,DBA启动数据库。
4.2 本地侦听+外部文件密码
使用前提:
(1)客户端与服务器端运行在同一机器上;
(2)使用任何账户登录OS;
(3)设置了$ORACLE_SID环境变量。
连接字符串:
此时,的连接字符串必须为 connect 特权账户名/密码 as sysdba。
使用场景:
与4.1类似,只是此时的OS账户只要有权限运行sqlplus即可,无需是Oracle的安装用户。