Oracle安装,特别是Linux/Unix环境下安装对于每一个初学者而言,都是一个挑战。操作步骤多、各种配置项目复杂和细节点多,只要有一个步骤出现错误,就可能给后续安装或者运行带来问题。有时候一些问题还是比较有迷惑性,解决起来需要一些经验和知识。
本篇主要介绍一个由于SID安装过程中大小写不一致引起的问题,以及解决策略。
1、环境介绍
笔者接到同事反馈,说一个已经安装好的数据库,远程使用sys用户登录失败,报错用户名密码错误。但是使用其他用户登录就没有问题。
由于是一个新安装的数据库,先去检查一下各种环境变量和数据情况。当前后台进程的确是正常运行,环境变量上也算正常。
[oracle@TEST-NE-TESTDB ~]$ ps -ef | grep pmon
oracle 13259 1 0 Jul13 ? 00:00:07 ora_pmon_TESTDB
oracle 16439 16414 0 08:31 pts/1 00:00:00 grep pmon
[oracle@TEST-NE-TESTDB ~]$ env | grep ORA
ORACLE_SID=TESTDB
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1
在笔者之前的文章里,对于连接故障推荐过一个流程,是按照“从近到远”的顺序逐步递进。简单的说:先看服务器内部连接、之后从监听器、网络到特定连接客户端。
在服务器上,匿名sys登录是没有问题的,普通用户(以scott为例)也没有问题。
SQL> conn / as sysdba
Connected.
SQL> conn scott/tiger
Connected.
SQL> select open_mode from v$database;
OPEN_MODE
--------------------
READ WRITE
SQL> show parameter service
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string testdb
监听器状态也是正常的。
[oracle@TEST-NE-TESTDB ~]$ lsnrctl status
LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 14-JUL-2017 08:35:54
Copyright (c) 1991, 2013, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))
STATUS of the LISTENER
------------------------
(篇幅原因,有省略……)
Services Summary...
Service "TESTDB" has 1 instance(s).
Instance "TESTDB", status READY, has 1 handler(s) for this service...
Service "testdbXDB" has 1 instance(s).
Instance "TESTDB", status READY, has 1 handler(s) for this service...
The command completed successfully
[oracle@TEST-NE-TESTDB ~]$
但是,远程使用pl/sql developer或者sqlplus连接的时候,sys账号是不成功的,scott账号成功。
2、问题分析
这个问题的故障点应该不在客户端到服务器的网络层面,因为毕竟有用户可能实现登录。而且一个怀疑点就是报错信息:sys连接时候报错信息不是连接不上,而是用户名密码错误。
那么推回到服务器端,如果在服务器端使用监听器进行连接,那么效果如何?
[oracle@TEST-NE-TESTDB admin]$ sqlplus /nolog
SQL*Plus: Release 11.2.0.4.0 Production on Fri Jul 14 08:45:06 2017
Copyright (c) 1982, 2013, Oracle. All rights reserved.
SQL> conn sys/oracle@testdb as sysdba
ERROR:
ORA-01017: invalid username/password; logon denied
SQL> conn scott/tiger@testdb
Connected.
SQL>
错误提示是相同,说明在经过监听器的情况下,引起了验证错误。那么,是否经过监听器,对Oracle而言有什么差别呢?经过监听器,无论是否是服务器本地客户端,Oracle都会视为“远程连接”,进行远程连接处理。
那么,sys和scott用户的差别在什么地方?就是密码文件Password File。普通用户验证信息是在数据库内部,而具有sysdba权限的是在一个单独的密码文件中。所以猜想是密码文件出了问题。
但是,在$ORACLE_HOME/dbs目录下,存在疑似的参数文件和密码文件。
[oracle@TEST-NE-TESTDB admin]$ cd $ORACLE_HOME/dbs
[oracle@TEST-NE-TESTDB dbs]$ ls -l
total 32
-rw-rw----. 1 oracle oinstall 1544 Jul 13 20:25 hc_testdb.dat
-rw-rw----. 1 oracle oinstall 1544 Jul 13 20:27 hc_TESTDB.dat
-rw-rw----. 1 oracle oinstall 1544 Jul 13 18:28 hc_TESTNETESTDB.dat
-rw-r--r--. 1 oracle oinstall 2851 May 15 2009 init.ora
-rw-r-----. 1 oracle oinstall 2112 Jul 13 20:15 initTESTDB.ora
-rw-r-----. 1 oracle oinstall 24 Jul 13 20:27 lkTESTDB
-rw-r-----. 1 oracle oinstall 1536 Jul 13 18:32 orapwtestdb
-rw-r-----. 1 oracle oinstall 3584 Jul 13 19:16 spfiletestdb.ora
但是,看起来很怪,特别是参数文件。当前参数文件发现,根本就没有使用SPfile,而是直接使用Pfile启动的。
SQL> conn / as sysdba
Connected.
SQL> show parameter spfile
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
spfile string
到此,笔者能猜出原因在于大小写。在同事安装数据库过程中,环境变量和安装文件上输入的sid信息大小写不一致。环境变量中输入的是大写TESTDB,而Oracle实例生成的是小写testdb对应实例文件。
3、解决问题
了解了问题原因,解决起来就有方向了。这个问题要从参数文件和密码文件两个层面进行解决。首先要重建参数文件。
SQL> create spfile from pfile;
File created.
SQL> quit
对应目录上,新生成了大写的spfileTESTDB.ora文件。
[oracle@TEST-NE-TESTDB dbs]$ ls -l
total 36
-rw-rw----. 1 oracle oinstall 1544 Jul 13 20:25 hc_testdb.dat
(篇幅原因,有省略……)
-rw-r-----. 1 oracle oinstall 1536 Jul 13 18:32 orapwtestdb
-rw-r-----. 1 oracle oinstall 3584 Jul 13 19:16 spfiletestdb.ora
-rw-r-----. 1 oracle oinstall 2560 Jul 14 08:48 spfileTESTDB.ora
密码文件重构。
[oracle@TEST-NE-TESTDB dbs]$ orapwd file=orapwTESTDB password=oracle entries=5 force=Y
[oracle@TEST-NE-TESTDB dbs]$ ls -l | grep orapw
-rw-r-----. 1 oracle oinstall 1536 Jul 13 18:32 orapwtestdb
-rw-r-----. 1 oracle oinstall 2048 Jul 14 08:56 orapwTESTDB
重新启动数据库。
SQL> conn / as sysdba
Connected.
SQL> startup force
ORACLE instance started.
Total System Global Area 4993982464 bytes
Fixed Size 2261808 bytes
Variable Size 1073745104 bytes
Database Buffers 3909091328 bytes
Redo Buffers 8884224 bytes
Database mounted.
Database opened.
重新测试故障消失。
SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS TRUE TRUE FALSE
SQL> conn sys/oracle@testdb as sysdba
Connected.
SQL> show user;
USER is "SYS"
4、结论
注意:本案例其实还有另外的一种处理思路,就是顺着实例小写的特点,修改环境变量ORACLE_SID,这样重新启动数据库的时候,原有的那些环境文件就能发挥作用。