Oracle中sqlplus登入報錯SP2-0667和SP2-0750探究
前言:
朋友搭建11g兩節點的rac的時候,節點1能夠正常用sqlplus / as sysdba登入資料庫,但是節點2使用該命令報錯,如下:
解決過程:
說明:由於是遠端解決,解決過程並沒有記錄,不過該問題很容易復現。
後序會有另外一個復現該錯誤的方法,和此處遇到的案例不同。
報錯是關於ORACLE_HOME環境變數的問題,檢查.bash_profile也沒有發現問題,非常奇怪。
後邊紅色底色的報錯卻是提供了思路,進去指定目錄ls檢視,果然沒有檔案,後邊解決方法就很簡單:
朋友rac環境的話就是在節點1下該目錄的檔案scp到節點2即解決了問題。
有一個問題是搭建rac的過程為何節點2會缺失檔案,這裡也沒法弄清楚。
該案例的報錯有誤導作用,因為該出並非是由於環境變數而引起的問題。
下邊探究下環境變數引起該問題的情況。
資料庫環境:
構造之後的故障環境:
從上邊可以看出,環境變數ORACLE_HOME是有值的,但是使用sqlplus / as sysdba卻報了錯誤,這裡的錯誤非常奇怪。
以下從一般的解決思路入手:
馬上可以發現,這裡的ORACLE_HOME少了個export關鍵詞,這也是構造故障的做法。
這裡引出兩個疑問:
1.在構造故障的時候,修改完.bash_profile檔案之後,source .bash_profile之後使用sqlplus / as sysdba是不會報錯的,需要重新開啟一個會話。
為什麼?這裡先留作第一個問題。
2.就算是去掉export,echo $ORACLE_HOME還是會有值,為什麼還是報了錯誤。
網友們也可以自己構造環境去思考。
以下是我嘗試解決故障的過程,會有一些不太有用處的過程:
1.用strace跟蹤sqlplus後臺程式執行情況,藍底部分對比可以發現,第一處藍底部分的路徑值並不是從ORACLE_HOME獲取的,而是sqlplus命令的所在地址。
2.通過對比正常時候的strace sqlplus輸出文字發現,前邊部分的呼叫文字幾乎相同,除了一些函式的引數值不同。因此strace並不能找出異常時候的資訊,strace並不能更詳細的追蹤出不同之處,比較遺憾。
只能從另外一個角度重新思考了,由於ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1引起報錯是因為export有無的原因,於是:
可以發現ORACLE_HOME並沒有在環境變數env中,僅僅只是ORACLE_HOME有值,並且值是“/u01/app/oracle/product/11.2.0/db_1”,難道這個就是原因?
首先,ORACLE從ORACLE_HOME獲取值,而ORACLE_HOME也確實有值,報錯說明這裡的值沒起來作用,於是嘗試通過呼叫指令碼獲取ORACLE_HOME的值,再去觀察結果。
結果很明顯,呼叫並不能獲得ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1的結果。
那麼上邊的兩個問題也很明顯了,第一個問題是因為ORACLE_HOME已經在環境變數裡邊了,就算是更改之後再次source也還是一樣,因此需要重新開啟會話,第二個問題就很明顯了。
從該案例看的話,ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1,ORACLE_HOME只是區域性變數,區域性變數只對當前shell生效。
而export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1使得ORACLE_HOME變成系統環境變數,系統環境變數對當前shell以及子shell、子子shell等下一級有效。
網上的資料:
使用者登入到Linux系統後,系統將啟動一個使用者shell。在這個shell中,可以使用shell命令或宣告變數,也可以建立並執行 shell指令碼程式。執行shell指令碼程式時,系統將建立一個子shell。
此時,系統中將有兩個shell,一個是登入時系統啟動的shell,另一 個是系統為執行指令碼程式建立的shell。當一個指令碼程式執行完畢,它的指令碼shell將終止,可以返回到執行該指令碼之前的shell。
從這種意義上來 說,使用者可以有許多 shell,每個shell都是由某個shell(稱為父shell)派生的。
在子 shell中定義的變數只在該子shell內有效。如果在一個shell指令碼程式中定義了一個變數,當該指令碼程式執行時,這個定義的變數只是該指令碼程式內 的一個區域性變數,其他的shell不能引用它,要使某個變數的值可以在其他shell中被改變,可以使用export命令對已定義的變數進行輸出。
export命令將使系統在建立每一個新的shell時定義這個變數的一個拷貝。這個過程稱之為變數輸出。
對於export和shell的關係,有結論如下:
1、執行指令碼時是在一個子shell環境執行的,指令碼執行完後該子shell自動退出;
2、一個shell中的系統環境變數才會被複制到子 shell中(用export定義的變數);
3、一個shell中的系統環境變數只對該shell或者它的子shell有效,該shell結束時變數消失 (並不能返回到父shell中);
3、不用export定義的變數只對該shell有效,對子shell也是無效的。
朋友搭建11g兩節點的rac的時候,節點1能夠正常用sqlplus / as sysdba登入資料庫,但是節點2使用該命令報錯,如下:
-
[oracle@oracle ~]$ sqlplus / as sysdba
-
Error 6 initializing SQL*Plus
-
SP2-0667: Message file sp1<lang>.msb not found
- SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
解決過程:
說明:由於是遠端解決,解決過程並沒有記錄,不過該問題很容易復現。
後序會有另外一個復現該錯誤的方法,和此處遇到的案例不同。
-
[oracle@oracle ~]$ sqlplus / as sysdba
-
Error 6 initializing SQL*Plus
-
SP2-0667: Message file sp1<lang>.msb not found
-
SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
-
[oracle@oracle ~]$ echo $ORACLE_HOME
-
/u01/app/oracle/product/11.2.0/db_1
-
[oracle@oracle ~]$ cat .bash_profile
-
# .bash_profile
-
-
# Get the aliases and functions
-
if [ -f ~/.bashrc ]; then
-
. ~/.bashrc
-
fi
-
-
# User specific environment and startup programs
-
-
PATH=$PATH:$HOME/bin
-
-
export PATH
-
export ORACLE_SID=proc
-
export ORACLE_BASE=/u01/app/oracle
-
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1
-
export PATH=$PATH:$ORACLE_HOME/bin
-
[oracle@oracle ~]$ which sqlplus
-
/u01/app/oracle/product/11.2.0/db_1/bin/sqlplus
-
[oracle@oracle ~]$ oerr sp2 667
-
oerr: Cannot access the message file /u01/app/oracle/product/11.2.0/db_1/sqlplus/mesg/sp2us.msg
-
[oracle@oracle ~]$ cd $ORACLE_HOME/sqlplus/mesg
- [oracle@oracle mesg]$ ls
後邊紅色底色的報錯卻是提供了思路,進去指定目錄ls檢視,果然沒有檔案,後邊解決方法就很簡單:
-
[oracle@oracle mesg]$ cp ~/bak/* ./
-
[oracle@oracle mesg]$ ll
-
total 216
-
-rw-r--r--. 1 oracle oinstall 4096 Dec 30 01:13 cpyus.msb
-
-rw-r--r--. 1 oracle oinstall 4369 Dec 30 01:13 cpyus.msg
-
-rw-r--r--. 1 oracle oinstall 12288 Dec 30 01:13 sp1us.msb
-
-rw-r--r--. 1 oracle oinstall 20123 Dec 30 01:13 sp1us.msg
-
-rw-r--r--. 1 oracle oinstall 34816 Dec 30 01:13 sp2us.msb
-
-rw-r--r--. 1 oracle oinstall 137350 Dec 30 01:13 sp2us.msg
-
[oracle@oracle mesg]$ sqlplus / as sysdba
-
-
SQL*Plus: Release 11.2.0.4.0 Production on Fri Dec 30 01:13:38 2016
-
-
Copyright (c) 1982, 2013, Oracle. All rights reserved.
-
-
-
Connected to:
-
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
-
With the Partitioning, OLAP, Data Mining and Real Application Testing options
-
-
SYS@proc> !oerr sp2 667
-
00667, 0, "Message file %s<lang>.msb not found\n"
-
// *Cause: The SP1, SP2, or CPY message file could not be
-
// found. SQL*Plus cannot run.
-
// *Action: Check the Oracle platform specific documentation to make
-
// sure SQL*Plus is installed correctly. This may occur
-
// because the ORACLE_HOME environment variable or registry
-
// equivalent is not set to the location of the Oracle
-
// software. Make sure this value is set correctly. Check
-
// that the SQL*Plus binary message files exist in the
-
// SQL*Plus message directory, for example
-
// $ORACLE_HOME/sqplus/mesg. Check the value of NLS_LANG
-
// environment variable or registry equivalent is correct.
-
- SYS@proc>
有一個問題是搭建rac的過程為何節點2會缺失檔案,這裡也沒法弄清楚。
該案例的報錯有誤導作用,因為該出並非是由於環境變數而引起的問題。
下邊探究下環境變數引起該問題的情況。
資料庫環境:
-
SYS@proc> select * from v$version where rownum=1;
-
-
BANNER
-
--------------------------------------------------------------------------------
- Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
構造之後的故障環境:
- [oracle@oracle ~]$ echo $ORACLE_HOME
- /u01/app/oracle/product/11.2.0/db_1
-
[oracle@oracle ~]$ sqlplus / as sysdba
-
Error 6 initializing SQL*Plus
-
SP2-0667: Message file sp1<lang>.msb not found
-
SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
-
[oracle@oracle ~]$ ls $ORACLE_HOME/sqlplus/mesg
-
cpyus.msb cpyus.msg sp1us.msb sp1us.msg sp2us.msb sp2us.msg
- [oracle@oracle ~]$
以下從一般的解決思路入手:
-
[oracle@oracle ~]$ cat .bash_profile
-
# .bash_profile
-
-
# Get the aliases and functions
-
if [ -f ~/.bashrc ]; then
-
. ~/.bashrc
-
fi
-
-
# User specific environment and startup programs
-
-
PATH=$PATH:$HOME/bin
-
-
export PATH
-
export ORACLE_SID=proc
-
export ORACLE_BASE=/u01/app/oracle
-
ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1
- export PATH=$PATH:$ORACLE_HOME/bin
這裡引出兩個疑問:
1.在構造故障的時候,修改完.bash_profile檔案之後,source .bash_profile之後使用sqlplus / as sysdba是不會報錯的,需要重新開啟一個會話。
為什麼?這裡先留作第一個問題。
2.就算是去掉export,echo $ORACLE_HOME還是會有值,為什麼還是報了錯誤。
網友們也可以自己構造環境去思考。
以下是我嘗試解決故障的過程,會有一些不太有用處的過程:
-
[oracle@oracle ~]$ strace sqlplus
-
execve("/u01/app/oracle/product/11.2.0/db_1/bin/sqlplus", ["sqlplus"], [/* 35 vars */]) = 0
-
brk(0) = 0x1533000
-
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f88dab000
-
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/tls/x86_64/libsqlplus.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
stat("/u01/app/oracle/product/11.2.0/db_1/lib/tls/x86_64", 0x7fff8cb17860) = -1 ENOENT (No such file or directory)
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/tls/libsqlplus.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
stat("/u01/app/oracle/product/11.2.0/db_1/lib/tls", 0x7fff8cb17860) = -1 ENOENT (No such file or directory)
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/x86_64/libsqlplus.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
stat("/u01/app/oracle/product/11.2.0/db_1/lib/x86_64", 0x7fff8cb17860) = -1 ENOENT (No such file or directory)
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/libsqlplus.so", O_RDONLY) = 3
-
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\370\1\0\0\0\0\0"..., 832) = 832
-
fstat(3, {st_mode=S_IFREG|0644, st_size=1469542, ...}) = 0
-
mmap(NULL, 1985056, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f5f88bc6000
-
mprotect(0x7f5f88c9c000, 1048576, PROT_NONE) = 0
-
mmap(0x7f5f88d9c000, 57344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xd6000) = 0x7f5f88d9c000
-
mmap(0x7f5f88daa000, 2592, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f5f88daa000
-
close(3) = 0
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/libclntsh.so.11.1", O_RDONLY) = 3
-
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\326G\0\0\0\0\0"..., 832) = 832
- ...省略部分內容...
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/libsqlplusic.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/libociicus.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/libociei.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
write(2, "Error 6 initializing SQL*Plus\n", 30Error 6 initializing SQL*Plus
-
) = 30
-
write(2, "SP2-0667: Message file sp1<lang>"..., 47SP2-0667: Message file sp1<lang>.msb not found
-
) = 47
-
write(2, "SP2-0750: You may need to set OR"..., 76SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
-
) = 76
- exit_group(1) = ?
-
[oracle@oracle bin]$ strace ./sqlplus
-
execve("./sqlplus", ["./sqlplus"], [/* 36 vars */]) = 0
-
brk(0) = 0x1a0d000
-
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4f0a3c0000
-
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
- ...省略部分內容...
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/libsqlplusic.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/libociicus.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
open("/u01/app/oracle/product/11.2.0/db_1/lib/libociei.so", O_RDONLY) = -1 ENOENT (No such file or directory)
-
write(2, "Error 6 initializing SQL*Plus\n", 30Error 6 initializing SQL*Plus
-
) = 30
-
write(2, "SP2-0667: Message file sp1<lang>"..., 47SP2-0667: Message file sp1<lang>.msb not found
-
) = 47
-
write(2, "SP2-0750: You may need to set OR"..., 76SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
-
) = 76
- exit_group(1) = ?
2.通過對比正常時候的strace sqlplus輸出文字發現,前邊部分的呼叫文字幾乎相同,除了一些函式的引數值不同。因此strace並不能找出異常時候的資訊,strace並不能更詳細的追蹤出不同之處,比較遺憾。
只能從另外一個角度重新思考了,由於ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1引起報錯是因為export有無的原因,於是:
- [oracle@oracle ~]$ env | grep ORACLE_HOME
- [oracle@oracle ~]$ export | grep ORACLE_HOME
-
[oracle@oracle ~]$ export | grep ORACLE_BASE
-
declare -x ORACLE_BASE="/u01/app/oracle"
-
[oracle@oracle ~]$ env | grep ORACLE_BASE
- ORACLE_BASE=/u01/app/oracle
-
[oracle@oracle ~]$ echo $ORACLE_HOME
/u01/app/oracle/product/11.2.0/db_1
首先,ORACLE從ORACLE_HOME獲取值,而ORACLE_HOME也確實有值,報錯說明這裡的值沒起來作用,於是嘗試通過呼叫指令碼獲取ORACLE_HOME的值,再去觀察結果。
-
[oracle@oracle piscescanon]$ ll
-
total 4
-
-rwxr--r--. 1 oracle oinstall 18 Dec 30 00:32 test.sh
-
[oracle@oracle piscescanon]$ cat test.sh
-
echo $ORACLE_HOME
- [oracle@oracle piscescanon]$ ./test.sh
-
那麼上邊的兩個問題也很明顯了,第一個問題是因為ORACLE_HOME已經在環境變數裡邊了,就算是更改之後再次source也還是一樣,因此需要重新開啟會話,第二個問題就很明顯了。
從該案例看的話,ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1,ORACLE_HOME只是區域性變數,區域性變數只對當前shell生效。
而export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1使得ORACLE_HOME變成系統環境變數,系統環境變數對當前shell以及子shell、子子shell等下一級有效。
-
[oracle@oracle piscescanon]$ export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
-
[oracle@oracle piscescanon]$ ./test.sh
- /u01/app/oracle/product/11.2.0/db_1
網上的資料:
使用者登入到Linux系統後,系統將啟動一個使用者shell。在這個shell中,可以使用shell命令或宣告變數,也可以建立並執行 shell指令碼程式。執行shell指令碼程式時,系統將建立一個子shell。
此時,系統中將有兩個shell,一個是登入時系統啟動的shell,另一 個是系統為執行指令碼程式建立的shell。當一個指令碼程式執行完畢,它的指令碼shell將終止,可以返回到執行該指令碼之前的shell。
從這種意義上來 說,使用者可以有許多 shell,每個shell都是由某個shell(稱為父shell)派生的。
在子 shell中定義的變數只在該子shell內有效。如果在一個shell指令碼程式中定義了一個變數,當該指令碼程式執行時,這個定義的變數只是該指令碼程式內 的一個區域性變數,其他的shell不能引用它,要使某個變數的值可以在其他shell中被改變,可以使用export命令對已定義的變數進行輸出。
export命令將使系統在建立每一個新的shell時定義這個變數的一個拷貝。這個過程稱之為變數輸出。
對於export和shell的關係,有結論如下:
1、執行指令碼時是在一個子shell環境執行的,指令碼執行完後該子shell自動退出;
2、一個shell中的系統環境變數才會被複制到子 shell中(用export定義的變數);
3、一個shell中的系統環境變數只對該shell或者它的子shell有效,該shell結束時變數消失 (並不能返回到父shell中);
3、不用export定義的變數只對該shell有效,對子shell也是無效的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30174570/viewspace-2140746/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 11g RAC在grid使用者下登陸sqlplus報錯"Error 6 SP2-0667 SP2-0750"OracleSQLError
- oracle for windows cmd登入sqlplus之SP2-0750OracleWindowsSQL
- sqlplus / as sysdba無法登入的奇怪報錯SQL
- sqlplus本地登入報錯ORA-12545SQL
- Oracle所有者不是dba 引起sqlplus / as sysdba 登入報錯ORA-01031OracleSQL
- sqlplus 可以登入 plsql 不能登入SQL
- sqlplus / as sysdba 登入報許可權不足 for windowsSQLWindows
- sqlplus密碼中帶 @的登入方法。SQL密碼
- sqlplus登入資料庫報錯ORA-12547: TNS:lost contactSQL資料庫
- sqlplus sys/oracle@orcl as sysdba無法登入SQLOracle
- sqlplus as sysdb登入報ora-01017SQL
- mysql 8.0 使用 navicat 登入報錯MySql
- sqlplus login -- SP2-0750: You may need to set ORACLE_HOME to your Oracle software directorySQLOracle
- 登入 Oracle 資料庫報錯,ORA-00257: archiver errorOracle資料庫HiveError
- windows oracle11g資料庫使用sqlplus登入的時候出現ora-01017報錯WindowsOracle資料庫SQL
- mysql在Linux下登入正常,但是用Navicat登入報錯MySqlLinux
- Oracle中su切換進去sqlplus登入失敗的問題處理OracleSQL
- sqlplus 啟動報錯SQL
- 關於Oracle和MySQL中的無密碼登入OracleMySql密碼
- Oracle遠端登入報錯:ora-01031:insufficient privilegesOracle
- sqlplus能登入資料庫,但plsql登入不上SQL資料庫
- sqlplus 命令登入 Oracle資料庫的多種方法DXNASQLOracle資料庫
- CentOS5.6中裝好Oracle11g之後,啟動sqlplus報錯CentOSOracleSQL
- sqlplus -prelim / as sysdba強制登入SQL
- ORA-39002和ORA-39166報錯處理和探究
- ORACLE_HOME設定錯誤導致本地sqlplus無法登陸OracleSQL
- oracle windows sqlplus ora-01017 登入被拒絕OracleWindowsSQL
- aix系統資料庫sqlplus登陸報錯處理一例AI資料庫SQL
- AIX 未開啟AIO引起SQLPLUS登陸報錯exec(): 0509-036AISQL
- sqlplus常用的幾種登入方式SQL
- SYS使用者登入Oracle報錯ORA-01031: insufficient privilegesOracle
- Oracle9i sys登入後通過public同義詞move table報錯Oracle
- solaris oracle vault 登入錯誤 the account is locked [28000].Oracle
- sqlplus顯示登入使用者名稱和例項名SQL
- laravel 8.0 Auth 登入 Auth::attempt () 為什麼報錯?Laravel
- ssh登入報錯-bash fork retry Resource temporarily unavailableAI
- ORACLE密碼檔案和登入方式Oracle密碼
- selinux導致sqlplus登入失敗LinuxSQL