天天看点

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