天天看點

oracle

最近看到好多人說到tns或者資料庫不能登入等問題,就索性總結了下面的東東。

  

  首先來說oracle的網絡結構,往複雜處說能加上加密、ldap等等。。這裡不做讨論,重點放在基本的網絡結構也就是我們最常用的這種情況

  <b>三個配置檔案</b>

  listener.ora、sqlnet.ora、tnsnames.ora ,都是放在$oracle_homenetworkadmin目錄下。

  <b>重點:三個檔案的作用和使用</b>

  #-----------------------

  sqlnet.ora-----作用類似于linux或者其他unix的nsswitch.conf檔案,通過這個檔案來決定怎麼樣找一個連接配接中出現的連接配接字元串,

  例如我們用戶端輸入

  sqlplus sys/oracle@orcl

  假如我的sqlnet.ora是下面這個樣子

  sqlnet.authentication_services= (nts)

  names.directory_path= (tnsnames,hostname)

  那麼,用戶端就會首先在tnsnames.ora檔案中找orcl的記錄.如果沒有相應的記錄則嘗試把orcl當作一個主機名,通過網絡的途徑去解析它的ip位址然後去連接配接這個ip上global_dbname=orcl這個執行個體,當然我這裡orcl并不是一個主機名

  如果我是這個樣子

  names.directory_path= (tnsnames)

  那麼用戶端就隻會從tnsnames.ora查找orcl的記錄

  括号中還有其他選項,如ldap等并不常用。

  #------------------------

  tnsnames.ora------這個檔案類似于unix 的hosts檔案,提供的tnsname到主機名或者ip的對應,隻有當sqlnet.ora中類似

  names.directory_path= (tnsnames) 這樣,也就是用戶端解析連接配接字元串的順序中有tnsnames是,才會嘗試使用這個檔案。

  例子中有兩個,orcl 對應的本機,sales對應的另外一個ip位址,裡邊還定義了使用主用伺服器還是共享伺服器模式進行連接配接,一句一句說

  #你所要連接配接的時候輸入得tnsname

  orcl =

  (description =

  (address_list =

  #下面是這個tnsname對應的主機,端口,協定

  (address = (protocol = tcp)(host = 127.0.0.1)(port = 1521))

  )

  (connect_data =

  #使用專用伺服器模式去連接配接需要跟伺服器的模式比對,如果沒有就根據伺服器的模式

  #自動調節

  (server = dedicated)

  #對應service_name,sqlplus&gt;show parameter service_name;

  #進行檢視

  (service_name = orcl)

  #下面這個類似

  sales =

  (address = (protocol = tcp)(host = 192.168.188.219)(port = 1521))

  (service_name = sales)

  #----------------------

  <b>用戶端完了我們來看伺服器端</b>

  listener.ora------listener監聽器程序的配置檔案

  關于listener程序就不多說了,接受遠端對資料庫的接入申請并轉交給oracle的伺服器程序。是以如果不是使用的遠端的連接配接,listener程序就不是必需的,同樣的如果關閉listener程序并不會影響已經存在的資料庫連接配接。

  listener.ora檔案的例子

  #listener.ora network configuration file: #e:oracleproduct10.1.0db_2networkadminlistener.ora

  # generated by oracle configuration tools.

  #下面定義listener程序為哪個執行個體提供服務

  #這裡是orcl,并且它對應的oracle_home和global_dbname

  #其中global_dbname不是必需的除非使用hostname做資料庫連接配接

  sid_list_listener =

  (sid_list =

  (sid_desc =

  (global_dbname = boway)

  (oracle_home = e:oracleproduct10.1.0db_2)

  (sid_name = orcl)

  #監聽器的名字,一台資料庫可以有不止一個監聽器

  #再向下面是監聽器監聽的協定,ip,端口等,這裡使用的tcp1521端口,并且使#用的是主機名

  listener =

  (address = (protocol = tcp)(host = boway)(port = 1521))

  上面的例子是一個最簡單的例子,但也是最普遍的。一個listener程序為一個instance(sid)提供服務。

  監聽器的操作指令

  $oracle_home/bin/lsnrctl start,其他諸如stop,status等。具體敲完一個lsnrctl後看幫助。

  上面說到的三個檔案都可以通過圖形的配置工具來完成配置

  $oracle_home/netca  向導形式的

  $oracle_home/netmgr

  本人比較習慣netmgr,

  profile 配置的是sqlnet.ora也就是名稱解析的方式

  service name 配置的是tnsnames.ora檔案

  listeners配置的是listener.ora檔案,即監聽器程序

  具體的配置可以嘗試一下然後來看一下配置檔案。

  這樣一來總體結構就有了,是當你輸入sqlplus sys/oracle@orcl的時候

  1. 查詢sqlnet.ora看看名稱的解析方式,發現是tnsname

  2. 則查詢tnsnames.ora檔案,從裡邊找orcl的記錄,并且找到主機名,端口和service_name

  3. 如果listener程序沒有問題的話,建立與listener程序的連接配接。

  4. 根據不同的伺服器模式如專用伺服器模式或者共享伺服器模式,listener采取接下去的動作。預設是專用伺服器模式,沒有問題的話用戶端就連接配接上了資料庫的server process。

  5. 這時候網絡連接配接已經建立,listener程序的曆史使命也就完成了。

  #---------------

  <b>幾種連接配接用到的指令形式</b>

  1.sqlplus / as sysdba 這是典型的作業系統認證,不需要listener程序

  2.sqlplus sys/oracle 這種連接配接方式隻能連接配接本機資料庫,同樣不需要listener程序

  3.sqlplus sys/oracle@orcl 這種方式需要listener程序處于可用狀态。最普遍的通過網絡連接配接。

  以上連接配接方式使用sys使用者或者其他通過密碼檔案驗證的使用者都不需要資料庫處于可用狀态,作業系統認證也不需要資料庫可用,普通使用者因為是資料庫認證,是以資料庫必需處于open狀态。

  然後就是

  #-------------

  <b>平時排錯可能會用到的</b>

  1.lsnrctl status檢視伺服器端listener程序的狀态

  lsnrctl&gt; help

  the following operations are available

  an asterisk (*) denotes a modifier or extended command:

  start        stop        status

  services      version       reload

  save_config     trace        change_password

  quit        exit        set*

  show*

  lsnrctl&gt; status

  :em11:

  2.tnsping 檢視用戶端sqlnet.ora和tnsname.ora檔案的配置正确與否,及對應的伺服器的listener程序的狀态。

  c:&gt;tnsping orcl

  tns ping utility for 32-bit windows: version 10.1.0.2.0 - production on 16-8月 -

  2005 09:36:08

  copyright (c) 1997, 2003, oracle. all rights reserved.

  used parameter files:

  e:oracleproduct10.1.0db_2networkadminsqlnet.ora

  used tnsnames adapter to resolve the alias

  attempting to contact (description = (address_list = (address = (protocol = tcp)

  (host = 127.0.0.1)(port = 1521))) (connect_data = (server = dedicated) (service_

  name = orcl)))

  ok (20 msec)

  3.sql&gt;show sga 檢視instance是否已經啟

  sql&gt; select open_mode from v$database; 檢視資料庫是打開還是mount狀态。

  open_mode

  ----------

  read write

  #-----------------

  <b>使用hostname通路資料庫而不是tnsname的例子</b>

  使用tnsname通路資料庫是預設的方式,但是也帶來點問題,那就是用戶端都是需要配置tnsnames.ora檔案的。如果你的資料庫伺服器位址發生改變,就需要重新編輯用戶端這個檔案。通過hostname通路資料庫就沒有了這個麻煩。

  需要修改

  伺服器端listener.ora

  #監聽器的配置檔案listener.ora

  #使用host naming則不再需要tnsname.ora檔案做本地解析

  # listener.ora network configuration file: d:oracleproduct10.1.0db_1networkadminlistener.ora

  #  (sid_name = plsextproc)

  (oracle_home = d:oracleproduct10.1.0db_1)

  #  (program = extproc)

  (description_list =

  (address = (protocol = ipc)(key = extproc))<b> </b>

<b>vnc server配置</b>

<b>使用root使用者啟動系統的vncserver服務;</b>

#service vncserver start

<b>然後切換到登陸使用者下面,我這裡假設要使用oracle系統帳戶進行遠端登陸</b>

#su - oracle

<b>使用oracle使用者輸入以下指令:</b>

$vncserver

如果是第一次運作,則系統會出現提示資訊,提示你輸入密碼,這是通過終端進行登陸時需要輸入的;

另外,還有一個數字資訊,這個也是需要在終端登陸時輸入的,即冒号後面跟着的一個數字,如:1  ,:2等等,需要記住;

<b>在windows用戶端使用vncviewer,輸入如下:xxx.xxx.xxx.xxx:1 或者xxx.xxx.xxx.xxx:2等,後面的數字需要和伺服器端的對應才行;xxx是你伺服器的ip位址了;</b>

<b></b> 

<b>[linux redhat ] 軟體要求</b>

其他所需程式包的版本(或更高版本): 

<b>       libaio-devel</b>

<b></b>

<b>       elfutils-libelf-devel</b>

<b>       unixodbc-devel</b>

<b>        gcc-2.96-124 </b>

        binutils-2.11

        openmotif-2.1.30-11

        glibc-2.2.4-31

<b>2、設定系統參數;</b>

 oracle 資料庫需要以下所示的核心參數設定。

 一般情況下可以設定最大共享記憶體為實體記憶體的一半,如果實體記憶體是 2g,則可以設定最大共享記憶體為 1073741824,如上;如實體記憶體是 1g,則可以設定最大共享記憶體為 512 * 1024 * 1024 = 536870912;以此類推。在redhat上最大共享記憶體不建議超過4*1024*1024*1024-1=4294967295切換到root使用者:

<b>vi /etc/sysctl.conf 加入:</b>

kernel.shmall = 2097152

kernel.shmmax = 536870912

kernel.shmmni = 4096

kernel.sem = 250 32000 100 128

fs.file-max = 65536

net.ipv4.ip_local_port_range = 1024 65000

net.core.rmem_default = 4194304

net.core.wmem_default = 262144

net.core.rmem_max = 4194304

net.core.wmem_max = 262144

儲存後,可以用/sbin/sysctl -p 讓參數立該生效

<b>3、vi /etc/security/limits.conf</b>

oracle soft nproc 2047

oracle hard nproc 16384

oracle soft nofile 1024

oracle hard nofile 65536

<b>4、添加如下的行到/etc/pam.d/login 檔案:</b>

session required /lib/security/pam_limits.so

session required pam_limits.so

<b>5、vi /etc/profile 在尾部加入:</b>

if [ \$user = "oracle" ]; then

if [ \$shell = "/bin/ksh" ]; then

   ulimit -p 16384

   ulimit -n 65536

else

   ulimit -u 16384 -n 65536

fi

umask 022

<b>6、vi /etc/csh.login  在尾部加入:</b>

if ( \$user == "oracle" ) then

  limit maxproc 16384

  limit descriptors 65536

  umask 022

endif

<b>7、建立組及使用者</b>

groupadd oinstall

groupadd dba

useradd -g oinstall -g dba oracle

passwd oracle

<b>8、建立目錄及給目錄付權限</b>

mkdir -p /opt/oracle/product/11.1

chown -r oracle.oinstall /opt/oracle

<b>9、設定使用者oracle環境變量</b>

要使用 oracle 産品,應該或必須設定幾個環境變量。

如果您在同一伺服器上安裝了多個 oracle 産品或資料庫,則 oracle_home、oracle_sid 和 path 變量可能會更改。

oracle_base 變量不應更改,并可以在需要時在您的登入配置檔案中設定它。oracle 提供了一個稱作 oraenv 的實用程式來設定其他變量。

切到oracle使用者

vi ~/.bashrc (或vi .bash_profile)

export oracle_base=/opt/oracle

export oracle_home=/opt/oracle/product/11.1

export oracle_sid=orcl

export path=$oracle_home/bin:$oracle_home/apache/apache/bin:$path

export ld_library_path=$oracle_home/lib:/lib:/usr/lib

export ld_library_path=$ld_library_path:/usr/local/lib

<b>儲存退出</b>

--執行以下指令讓配置馬上生效或以oracle使用者登入使設定生效

$ source $home/.bash_profile

<b>10、進行按裝</b>

su root

xhost +  (或 export display=ip:0.0)

su oracle

運作 ./runinstaller

<b>然後按照提示即可完成安裝;</b>

登陸并啟動資料庫的操作。

su - oracle

[oracle@oracle oracle]$ lsnrctl start

[oracle@oracle oracle]$ sqlplus /nolog

sql*plus: release 9.2.0.0 - production on sat mar 12 22:58:53 2005

copyright (c) 1982, 2002, oracle corporation. all rights reserved.

sql&gt; connect / as sysdba

connected.

sql&gt; startup; 啟動資料庫

oracle instance started.

total system global area 236000356 bytes

fixed size 451684 bytes

variable size 201326592 bytes

database buffers 33554432 bytes

redo buffers 667648 bytes

database mounted.

database opened.sql&gt; shutdown immediate ;關閉資料庫 (or "dbshut" command)

database closed.

database dismounted.

oracle instance shut down.4, dbstart腳本修改

資料庫建立完成後,修改vi /etc/oratab,把orcl:/opt/oracle/11.1:n那一行最後的n改成y,

修改vi /opt/oracle/1x.x.1/bin/dbstart中oracle_home_listner=/opt/oracle/1x.x.1

然後執行dbstart啟動資料庫資料庫可能無法啟動,報告can’t find init file …的錯誤,需要複制一個初始化檔案:

cp /opt/oracle/admin/orcl/pfile/init.ora.* /opt/oracle/1x.x.1/dbs/initge01.ora

重新執行dbstart就可以了。可以執行dbshut 停止oraclevi /etc/rc.local 加入下面一行 起動oracle on system boot

su - oracle -c "lsnrctl start"

su - oracle -c "dbstart" 5. 為了root友善管理,可以寫一個啟動腳本

vi /etc/init.d/ora10g

#!/bin/bash

#

# chkconfig: 2345 91 19

# description: starts the oracle listener and instance status() {

    pid=`ps -ef | grep ora_pmon | grep -v grep | awk '{print $8}'`

    if [ "x$pid" = "x" ]

    then

        echo "oracle10g is not running."

        exit 1

    else

        echo "oracle10g is running."

        exit 0

    fi

}case "$1" in

    start)

        #startup the listener and instance

        echo -n "oracle begin to startup: "

        su - oracle -c "lsnrctl start"

        su - oracle -c dbstart

        echo "oracle10g started"

        ;;

    stop)

        # stop listener, apache and database

        echo -n "oracle begin to shutdown:"

        su - oracle -c "lsnrctl stop"

        su - oracle -c dbshut

        echo "oracle10g shutdowned"

    reload|restart)

        $0 stop

        $0 start

    'status')

        status

     *)

        echo "usage: ora10g [start|stop|reload|restart]"

esac

exit 0 存為ora10g後,然後

chmod a+x /etc/init.d/ora10g

即可在以後以root身份運作/etc/rc.d/init.d/ora10g start |stop 來管oracle的啟動和停止了。

如果要将這個腳本加入到系統中使其可開機運作,那麼要運作以下指令:

chkconfig --level 35 ora10g on

6, 關于資料庫删除重新安裝的問題:

1 . 去除 /usr/local/bin 目錄 下的 coraenv dbhome oraenv

2 . 去除 /etc/oratab , /etc/oracle

3 . 去掉安裝 目錄 /opt/oracle 目錄下的 product admin oradata oralnventor 目錄 。

# userdel -r oracle

# groupdel dba oinstall

rm -rf /tmp/ora*

rm -rf /opt/oracle/*

rm -rf /opt/orclfmap

rm -f /etc/ora*

rm -f /usr/local/bin/oraenv

rm -f /usr/local/bin/coraenv

rm -f /usr/local/bin/dbhome

7.修改oracle10g資料庫字元集

sql&gt; connect sys/oracle as sysdba

sql&gt; startup mount

sql&gt; alter session set sql_trace=true;session altered.sql&gt; alter system enable restricted session;system altered.sql&gt; alter system set job_queue_processes=0;system altered.sql&gt; alter system set aq_tm_processes=0;system altered.sql&gt; alter database open;database altered.sql&gt; set linesize 120;

sql&gt; alter database character set zhs16gbk;

alter database character set zhs16gbk

*

error at line 1:

ora-12712: new character set must be a superset of old character setsql&gt; alter database character set internal_use zhs16gbk; # 使用internal_use可以跳過超集的檢查,alter database character set internal_use database altered.sql&gt; shutdown immediate;

oracle instance shut down.

sql&gt; startup

sql&gt; select name,value$ from props$ where name like '%nls%';nls_characterset

zhs16gbk8. oracle database異機備份腳本

mkdir /home/oracle/dbbackup(1)vi /home/oracle/dbbackup/bachupdb.sh

#as oracle user, chmod 744 /home/oracle/dbbackup/dbbackuprecover.sh

#crontab -e 35 1 * * * /home/oracle/dbbackup/dbbackuprecover.sh &gt;/dev/null 2&gt;&amp;1

#@tip: modify local database's home directory

#@tip &lt;ip&gt; is remote database ip addressexport oracle_home=/opt/oracle/10.2.0.1

export path=$oracle_home/bin:$path:

export nls_lang=american_america.zhs16gbk

export lang=american_america.zhs16gbk

export oracle_sid=ge01dmpfile=gedb_`date +%f`.dmp

logfile=gedb_`date +%f`.log

restoredblog=restoredb_`date +%f`.log

work_dir=~/dbbackupcd $work_dir

exp userid=gedb/gegedb@&lt;ip&gt;/ge01 file=$dmpfile log=$logfile  owner=gedb

if [ 0 -eq "$?" ]

     then

         sqlplus / as sysdba @user.sql 

         imp userid=gedb/gegedb file=$dmpfile log=./$restoredblog fromuser=gedb  touser=gedb

         find  ./*.dmp -type f -mtime +7 -exec rm {} ;

         find  ./*.log -type f -mtime +30 -exec rm {} ;

         exit 0

      else

         echo "backup error,quit!" &gt; $logfile

         exit 1

#@tip ip位址修改為要備份的oracle的主機位址

exp userid=gedb/[email protected]/ge01 file=$dmpfile log=$logfile  owner=gedb direct=y  (2)更改腳本權限:

     chown oracle.oinstall backupdb.sh

     chmod 744 backupdb.sh   

 (3)以oracle user role

    crontab -e

    35 2 * * * /home/oracle/dbbackup/backupdb.sh 9. restore oracle backup

(1) 先建立gedb使用者和授權:

  su - oracle

  sqlplus / as sysdba @createuser.sql 

(2)imp userid=gedb/gegedb file=110.dmp fromuser=gedb touser=gedb

  如果要第二次imp操作要先删除使用者gedb,再建立使用者gedb,這樣imp才不會出錯.

  drop user gedb cascade;

  create user gedb  identified by gegedb;

  grant unlimited tablespace to gedb;

  grant connect to gedb;

  grant resource to gedb;

  grant dba to gedb;

10. oracle優化 sql&gt; alter system set "_kgl_large_heap_warning_threshold"=8388608 scope=spfile ; (only for 10.2.0.1.0 )

sql&gt; shutdown immediate

11.bug fix(1)10g em亂碼之快速解決

[oracle@danaly ~]$ cd $oracle_home/jdk/jre/lib

[oracle@danaly lib]$ ls font*zh_cn*

font.properties.zh_cn.redhat font.properties.zh_cn.redhat2.1

font.properties.zh_cn.sun font.properties.zh_cn_utf8.sun [oracle@danaly lib]$ cd $oracle_home/jre/1.4.2/lib/

font.properties.zh_cn.sun font.properties.zh_cn_utf8.sun 我們隻要用合适的中文字元集檔案替換預設檔案即可,我選擇使用font.properties.zh_cn.redhat來替換預設字型定義檔案: [oracle@danaly lib]$ cp font.properties.zh_cn.redhat font.properties 替換之後需要清理一下cache,重新開機em即可. cache路徑通常位于: $oracle_home/oc4j/j2ee/oc4j_applications/applications/em/em/cabo/p_w_picpaths/cache/zhs 清除所有gif檔案即可.然後重新啟動em(2)10201上一個嚴重的bug

環境 10201,aix53

但據oracle解釋,在任何作業系統版本都有此問題。現象:監聽器啟動後,隔一段時間(長短不定),就會出現無法

連接配接: 若是用10201版本的sqlplus,則會出現 no listener。

9207 版本的sqlplus,則會出現:沒反應,hang住。原因:10201 版本上的一個bug:4518443。其會自動建立一個子

監聽器,當出現此情況時,監聽器将會挂起。

/opt/oracle/product/10g/network/log/listener.log有如下語句:

warning: subscription for node down event still pending檢查是否真因為此bug造成此現象:

$ ps -ef | grep tnslsnr

ora10g 8909 1 0 sep 15 ? 902:44 /u05/10ghome/dbhome/bin/tnslsnr sales -inherit

ora10g 22685 8909 0 14:19:23 ? 0:00 /u05/10ghome/dbhome/bin/tnslsnr sales –inherit

正常情況隻有一個監聽器,而此bug則會出現兩個監聽器。解決方法:

打更新檔4518443

或者在listener.ora 檔案裡加入:

subscribe_for_node_down_event_&lt;listener_name&gt;=off

其中,&lt;listener_name&gt; 是資料庫的監聽器的名稱。如:

預設情況下,監聽器名為:listener 。則語句就是:

subscribe_for_node_down_event_listener=off

同時:

cd $oracle_home/opmn/conf

mv ons.config ons.config.orig

重新開機監聽程式:

lsnrctl stop

lncrctl start