Oracle 11g不同情形下的登录分析

对于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请求,并把结果返回给客户端。

Oracle 11g不同情形下的登录分析_第1张图片


任何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侦听与密码存放

作为C/S架构程序,账号登录过程分成前后两个部分,一是网络连接,二是账号验证。

3.1 两种服务器端侦听程序

前面说过Oracle net支持多种底层通信协议,其中包括操作系统本地的进程间通信协议。 无论底层是何种协议,服务器端程序必须进行某种形式的侦听,以等待来自客户的连接请求。

(1)网络侦听程序tnslsnr

当底层协议是网络协议时,Oracle tnslsnr提供侦听服务。这是一个单独的进程,与其他进程独立。下面是Oracle专用服务器工作方式下的侦听器工作示意图。

Oracle 11g不同情形下的登录分析_第2张图片

如上图所示,客户端进程首先与侦听器连接(红色连线),并验证账户与权限,如果所有验证通过,侦听进程负责产生出一个新的服务器进程,并让客户端进程和新产生的服务器进程直接连接(蓝色连线),称之为一个会话,同时自身断开与客户端的连接,并与新建立的会话不再有任何关系。可见侦听进程起到了一个牵线的作用。之后,即使侦听器停止了工作,已经建立的会话也丝毫不受影响。

(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环境变量。

Oracle 11g不同情形下的登录分析_第3张图片

连接字符串:

此时,的连接字符串必须为 connect / as sysdba。


使用场景:

值得说明的是,这种情况下,登录成功的唯一前提就是需要指定$ORACLE_SID环境变量。不需要侦听器,也不需要数据库加载,甚至不需要实例启动。如上图所示,实例没有启动。此时,会默认使用oracle的sys账户登录。

这种情形的使用情况是,DBA启动数据库。

4.2 本地侦听+外部文件密码

使用前提:

(1)客户端与服务器端运行在同一机器上;

(2)使用任何账户登录OS;

(3)设置了$ORACLE_SID环境变量。

Oracle 11g不同情形下的登录分析_第4张图片

连接字符串:

此时,的连接字符串必须为 connect 特权账户名/密码 as sysdba。


使用场景:

与4.1类似,只是此时的OS账户只要有权限运行sqlplus即可,无需是Oracle的安装用户。


4.3 本地侦听+数据字典密码

适用前提:
(1)客户端与服务器端运行在同一机器上;
(2)数据库已经加载打开。
(3)设置了$ORACLE_SID环境变量。

Oracle 11g不同情形下的登录分析_第5张图片

连接字符串:
connect username/password。

使用场景:
此时适用于本地登录的普通用户。注意,由于密码存放在数据字典里,所以数据库必须处于打开状态。

4.4 网络侦听+外部文件密码

适用前提:
(1)tnslsnr必须已经正常工作;
(2)数据实例启动;无需加载数据库。


连接字符串:
connect 特权用户名/password@serverIP/servicename as sysdba

使用场景:
dba远程登录进行数据库维护。此时数据库无需加载。需要注意:连接字符串中有服务名,所以侦听程序必须知道这个服务名的信息,然而默认情况下只有数据库加载后才动态向侦听器注册服务信息。而现在的情况是,只有数据库实例启动了,没有加载数据库。此时,要想让侦听器得知服务信息,必须静态注册服务。方法是修改服务器端的listener.ora配置文件,如下所示:

Oracle 11g不同情形下的登录分析_第6张图片

4.5 网络侦听+数据字典密码

适用前提:
(1)tnslsnr必须已经正常工作;
(2)数据实例启动,数据库已经加载,并且打开;


连接字符串:
connect 普通用户名/password@serverIP/servicename

使用场景:
这是普通oracle应用最常用的情形了,大多数的web程序,应用程序一般都是使用普通账户远程接入oracle服务器来读写数据。

5 密码中特殊字符的处理

前面说过客户端是根据连接字符串来确定采用哪种方式向服务器登录的,连接字符串有特定的语法格式和特殊字符,如/,@,"。对于oracle账户名来说,一般要尽量避免名字中出现这些特殊字符,防止冲突。而对于账户的密码来说,很多人都喜欢使用特殊的字符,一旦密码中包含了/,@,",则势必导致与登录字符串的语法冲突。下面看几个例子。
(1)密码 p@ssw0rd
此时如果连接字符串为 connect username/p@ssw0rd, 那么@会被当做关键字,ssw0rd被当成是侦听地址,从而报错。解决方法是使用双引号把密码部分包围起来。 connect username/"p@ssw0rd"。

(2)密码 1/2
方法与上面相同, connect username/"1/2"。

(3)密码 1"2
密码里带有双引号,我还真没见过,也不知道怎么创建这种密码,还请高人指教。

oracle解析连接字符串时,如果用户名没有使用引号包围,则自动转换为大写字符;而对密码部分的解析则原样不变。
(4)注意平台shell的元字符转义
sqlplus支持在操作系统的CUI界面直接给出用户名和密码参数进行登录。如 
sqlplus username/password@server/service
当密码本身中含有bash元字符或者用引号包围密码时,都需要进行转义。以bash为例,如上面的密码 p@ssw0rd 的情况,此时需要写成:
sqlplus username/\"p@ssw0rd\"
因为"本身在bash中是元字符,要想把"本身作为参数的一部分传递给sqlplus,必须对其进行转义。

最后推荐一本OracleDBA的书籍,该书把很多的Oracle术语与原理讲述的非常清楚,只是翻译的略显粗糙,建议下载英文版比较阅读。英文版下载链接:http://download.csdn.net/detail/smstong/7534001。

你可能感兴趣的:(Oracle 11g不同情形下的登录分析)