Oracle Listener
一、监听器功能
1)监听客户端请求:监听器作为独立进程运行在数据库服务器上,监听特定网络端口(默认1521)服务请求。
2)为客户端请求分配oracle Server Process:监听器不直接处理客户端发送过来的SQL命令,而是作为代理,将分配一个服务进程与客户端建立通信连接,由server process处理SQL命令并返回结果。
3)注册服务:通过注册过程实现监听器与数据库实例之间了联系,注册的过程就是告知监听器数据库实例名称和服务名,目前Oracle版本中,提供动态注册和静态注册两种方式。
4)故障转移failover: Failover是RAC容错的一个重要方面功能,当数据库实例发生崩溃时,监听器可以自动将请求转移到其它可用实例上。
5)负载均衡衡:在RAC架构中,当一个客户请求到来时,Oracle会根据当前RAC集群环境中所有实例的负载情况,避开负载较高的实例,将请求转移到负载较低的实例进行处理。
二、注册过程
注册的作用就是实现数据库实例名和服务名注册到运行的监听器程序中。
Figure 2-1 Example listener.ora File
LISTENER=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS))
(ADDRESS=(PROTOCOL=ipc)(KEY=extproc))))
# -- 静态注册部分
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(GLOBAL_DBNAME=sales.us.acme.com)
(ORACLE_HOME=/oracle9i)
(SID_NAME=sales))
(SID_DESC=
(SID_NAME=plsextproc)
(ORACLE_HOME=/oracle9i)
(PROGRAM=extproc)))
2.1) 默认是动态注册的时候,只有PLSExtProc项目。SID_LIST里用来配置当前监听器静态注册的服务项目,其中,通过一个或多个SID_DESC进行配置。静态配置项目中,通过GLOBAL_NAME配置服务项目,通过SID_NAME指定数据库实例的名称,通过ORACLE_HOME配置Oracle数据库软件安装的基本目录。
2.2)动态注册由PMON后台进程周期(2分钟)发起注册。
-- 手工进行注册 alter system set LOCAL_LISTENER='(ADDRESS = (PROTOCOL = TCP)(HOST = 10.150.10.150)(PORT = 1521))'; alter system register;
三、监听器信息
通过lsnrctl监听器控制程序与监听器进行交互和控制操作获取相对应信息。


注:
-- 这在10g及以后版本不是必要的安全检查条件,若想要取消此安全设置,可以在listener.ora文件中设置上LOCAL_OS_AUTHENTICATION_[listener name]=OFFset password
监听器密码设置在ORACLE 9i版本中有效,在10g版本中,即使设置密码后,依然可以不用输入密码停止监听服务,因为In Oracle 10, the TNSListener is secure out of the box and there should not be a need to set a listener password as in older versions of the Oracle listener。
Oracle10g以后,设置Listener密码已经不是安全检查的必要条件了,因为默认在10g里面除了启动监听的用户之外,其它用户都无法停止Listener(还有另外一些lsnrctl的命令也同样被禁止了,比如trace, reload等),即使Listener没有设置密码。在默认情况下,启动Listener或者使用lsnrctl status命令查看监听状态,可以看到:Security ON: Password OR Local OS Authentication这表明Listener的安全机制使用了Password方式或者Local OS Authentication方式,在这种状态下,即使是设置了监听密码,对于启动监听的user来说,也仍然是不需要任何密码就可以停止监听的。
3.1)set 命令操作配置
|
参数 |
描叙 |
|
set password |
|
|
set rawmode |
设置rawmode |
|
set displaymode |
把lsnrctl工具的显示模式设置成RAW、COMPACT、NORMAL或VERBOSE |
|
set trc_file |
设置监听跟踪文件的名称 |
|
set trc_directory |
设置监听器跟踪目录的名称 |
|
set trc_level |
把跟踪级别设置为OFF、USER、ADMIN、SUPPORT模式 |
|
set log_file |
显示或设置日志文件 |
|
set log_directory |
设置日志目录位置 |
|
set log_status |
设置是否为该监听器打开日志特性 |
|
set current_listener |
设置当前监听器为指定监听器 |
|
set inbound_connect_timeout |
设置参数指定的时间,在几秒钟内为客户完成网络连接已经建立后,其连接请求的监听 |
|
set startup_waittime |
设置监听器等待响应lsnrctl 命令行工具中的一条STATUS命令的时间长度 |
|
set save_config_on_stop |
在退出lsnrctl工具时保存对listener.ora文件的修改 |
|
set dynamic_registration |
使用的DYNAMIC_REGISTRATION_listener_name的参数启用或禁用动态注册。当设置为on,听者接受动态登记;设置为关闭时,听者拒绝动态注册。静态注册不受影响 |
|
set enable_global_dynamic_endpoint |
3.2)通过TNS_ADMIN命令指定监听器配置文件路径
expport TNS_ADMIN=$ORACLE_HOME/network/admin
四、监听器日志解析
1)日志格式:TIMESTAMP * CONNECT DATA [* PROTOCOL INFO] * EVENT [* SID] * RETURN CODE, 使用*进行内容分割。

2)监听日志截断,防止日志文件过大,一般不能超过2GB,超过会导致LISTENER监听器无法处理新的连接或是给写入、查看带来的一些性能问题。
Step 1:首先停止监听服务进程(tnslsnr)记录日志。
Step 2:将监听日志文件(listener.log)复制一份,以listener.log.yyyymmdd格式命名
Step 3:将监听日志文件(listener.log)清空。(如:mv命令等)
Step 4:开启监听服务进程(tnslsnr)记录日志
#!/bin/sh
# * * * * su - username -c sh clean_lsnrlog.sh
# reload user profile
[ -f "${HOME}/.bash_profile" ] && . ${HOME}/.bash_profile
[ -f "${HOME}/.profile" ] && . ${HOME}/.profile
# HP-UX操作系统使用ksh环境执行脚本,AIX使用ksh93环境执行,其他环境使用sh
# AIX则ECHO=echo(AIX系统没有-e的参数,默认会进行转义)
export OSTYPE=$(uname -s)
case ${OSTYPE} in
"HP-UX")
export LANG=en_US
EXEC_SHELL="ksh -x"
ECHO="echo -e"
;;
"AIX")
EXEC_SHELL="sh -x"
[ -f "/usr/bin/ksh93" ] && EXEC_SHELL="/usr/bin/ksh93 -x"
ECHO="echo"
;;
*)
EXEC_SHELL="sh -x"
ECHO="echo -e"
esac
export EXEC_SHELL ECHO
# scripts directory
WDIR=${HOME}/scripts
LOGDIR=${WDIR}/log
[ -d "${HOME}/scripts" ] || mkdir -p ${WDIR}
[ -d "${WDIR}/log" ] || mkdir -p ${WDIR}/log
LSNRNAMEFILE=${LOGDIR}/listener_name.txt
# output listener username
# USERID=$(ps -ef|grep tnslsnr |grep -v grep | awk '{print $1}' |sort -u)
# output listener name to the file
ps -ef|grep tnslsnr |grep -v grep | awk '{print $(NF-1)}' > ${LSNRNAMEFILE}
# ps -ef|grep tnslsnr |perl -lane 'print $F[-2] if/bin\/tnslsnr/' |awk '{$0=tolower($0);print $0}'|sort -u
# Get datetime format is yyyymmddhh24missss()
dtime=$(
CLR_TIME=$(
OPT_TIME=$(date +%Y%m%d%H%M)
# clean options
for LSN in $(cat "${LSNRNAMEFILE}" | awk '{ $0=tolower($0);print $0 }'); do
${ECHO} "\n ---------------------------- Begin ---------------------------- \n">> ${OPT_LOGFILE}
lsnrctl status ${LSN} > ${LOGDIR}/${LSN}.stat
# 监听配置文件
LSNRORAFILE=$(grep -i 'Listener Parameter File' ${LOGDIR}/${LSN}.stat |awk ' {print $NF}')
# output listener log directory
STR=$(grep -i 'Listener Log File' ${LOGDIR}/${LSN}.stat |awk ' {print $NF}')
# 监听日志文件[listener_name.log]所在目录
LSNR_DIR=${STR%'alert'*}trace
# 监听日志文件[log*.xml]所在目录
LSNXML_DIR=${STR%/*}
# 监听日志文件绝对路径
LSNLOGFILE=${LSNR_DIR}/${LSN}.log
# 监听日志文件大小
LSN_LOGFILE_SIZE=$(du -k ${LSNLOGFILE} | awk '{print $1}')
# clean operations logs
OPT_LOGFILE=${LOGDIR}/clean_${LSN}_${OPT_TIME}.log
# if xml directory exits,then delete 30 days agos xml files
if [ -d "${LSNXML_DIR}" ]; then
# change into xml directory
cd ${LSNXML_DIR} || exit 1
touch -t ${dtime} today
# recode deleting files
find ${LSNXML_DIR} -type f ! -newer today |xargs ls -ltr |grep 'xml$' >> ${OPT_LOGFILE}
# delete xml file actions
find ${LSNXML_DIR} -type f ! -newer today |grep 'xml$' |xargs -n1000 rm -f
fi
# if listener.log file exits,then backup and clear them
# if [ `du -sk ${LSNR_DIR}/trace` eq 1048576 && -f "${LSNLOGFILE}" ]
if [[ -f "${LSNLOGFILE}" ]] && [[ "${LSN_LOGFILE_SIZE}" -gt "1048576" ]]; then
${ECHO} "\n -------The size of ${LSNLOGFILE} is: ${LSN_LOGFILE_SIZE}'K' ------- \n">> ${OPT_LOGFILE}
cd ${LSNR_DIR} || exit 1
#如果存在监听配置文件,且有设置ADMIN_RESTRICTIONS,则OFF再进行mv的操作
if [[ -f "${LSNRORAFILE}" ]]; then
# 回退安全加固参数
grep -i "ADMIN_RESTRICTIONS_${LSN}" ${LSNRORAFILE}
ADMINSTAT=$?
if [[ "${ADMINSTAT}" = "0" ]]; then
perl -i.${OPT_TIME}.1 -pe "s/ADMIN_RESTRICTIONS_${LSN}=ON/ADMIN_RESTRICTIONS_${LSN}=OFF/ig" "${LSNRORAFILE}"
${ECHO} '\n ------- reload begin ------- \n'>> ${OPT_LOGFILE}
lsnrctl << EOFRELOAD
set CURRENT_LISTENER ${LSN}
reload
status
exit
EOFRELOAD
${ECHO} '\n ------- reload END ------- \n'>> ${OPT_LOGFILE}
fi
fi
#关闭监听的日志输出
${ECHO} '\n ------- set logfile off ------- \n'>> ${OPT_LOGFILE}
lsnrctl << EOFOFF >> ${OPT_LOGFILE}
set CURRENT_LISTENER ${LSN}
set log_status off
status
exit
EOFOFF
${ECHO} '\n ------- set logfile off END ------- \n'>> ${OPT_LOGFILE}
#确认监听状态是否log_status已off,off则进行move操作
lsnrctl status ${LSN}|grep ${LSNLOGFILE}
if [[ "$?" != "0" ]] ; then
# 备份并压缩监听日志文件
[[ -f "${LSNLOGFILE}" ]] && mv ${LSNLOGFILE} ${LSNLOGFILE}.${OPT_TIME} && gzip -f ${LSNLOGFILE}.${OPT_TIME} && ${ECHO} "\n ------- command: \nmv ${LSNLOGFILE} ${LSNLOGFILE}.${OPT_TIME}\ngzip -f ${LSNLOGFILE}.${OPT_TIME} \n------- \n" >> ${OPT_LOGFILE}
fi
#开启监听日志的输出
${ECHO} '\n ------- set logfile on ------- \n'>> ${OPT_LOGFILE}
lsnrctl << EOFON >> ${OPT_LOGFILE}
set CURRENT_LISTENER ${LSN}
set log_status on
status
exit
EOFON
${ECHO} '\n ------- set logfile on END ------- \n'>> ${OPT_LOGFILE}
# 安全加固参数
# grep -i "ADMIN_RESTRICTIONS_${LSN}" ${LSNRORAFILE}
if [[ "${ADMINSTAT}" = "0" ]]; then
perl -i.${OPT_TIME}.2 -pe "s/ADMIN_RESTRICTIONS_${LSN}=OFF/ADMIN_RESTRICTIONS_${LSN}=ON/ig" "${LSNRORAFILE}"
${ECHO} '\n ------- reload begin ------- \n'>> ${OPT_LOGFILE}
lsnrctl << EOFRELOAD
set CURRENT_LISTENER ${LSN}
reload
status
exit
EOFRELOAD
${ECHO} '\n ------- reload END ------- \n'>> ${OPT_LOGFILE}
fi
# 清理历史备份文件
touch -t ${CLR_TIME} cleansfile
${ECHO} '\n ------- Deleting histoty compress file before 180 days ago. ------- \n'>> ${OPT_LOGFILE}
find ${LSNR_DIR} -type f ! -newer cleansfile |xargs ls -ltr |grep '.gz$' >> ${OPT_LOGFILE}
find ${LSNR_DIR} -type f ! -newer cleansfile |grep '.gz$' |xargs -n100 rm -f
fi
${ECHO} "\n ---------------------------- Finish ---------------------------- \n">> ${OPT_LOGFILE}
done
4.3 监听文件的各个参数的作用作个描述:
|
LISTENER |
指出一个监听器定义的起始点。它实际上是正被定义的当前监听器的名称。默认的名称是LISTENER |
|
DESCRIPTION |
描述每个监听位置 |
|
ADDRESS_LIST |
含有与监听器正在监听的那些位置有关的地址信息 |
|
PROTOCOL |
指定用于本监听位置的协议 |
|
HOST |
保存监听器所驻留在的那台计算机的名称 |
|
PORT |
含有监听器正在上面监听的地址 |
|
SID_LIST_LISTENER |
定义配置监听器所针对的ORACLE服务的列表 |
|
SID_DESC |
描述每个Oracel SID |
|
GLOBAL_DBNAME |
标识全局数据库名称。本项应该与当前Oracle服务的init.ora文件中的SERVICE_NAMES项一致 |
|
ORACLE_HOME |
给出服务器上Oracle可执行程序的位置 |
|
SID_NAME |
含有用于本Oracle实例的Oracle SID的名称 |
五、sqlplus连接数据库实例方式,其它类似
5.1) sqlplus / as sysdba
操作系统认证,不需要数据库服务器启动listener,也不需要数据库服务器处于可用状态。比如我们想要启动数据库就可以用这种方式进入
sqlplus,然后通过startup命令来启动。
5.2) sqlplus username/password
连接本机数据库,不需要数据库服务器的listener进程,但是由于需要用户名密码的认证,因此需要数据库服务器处于可用状态才行。
5.3) sqlplus usernaem/password@orcl
通过网络连接,这是需要数据库服务器的listener处于监听状态。此时建立一个连接的大致步骤如下
a. 查询sqlnet.ora,看看名称的解析方式,默认是TNSNAME
b. 查询tnsnames.ora文件,从里边找orcl的记录,并且找到数据库服务器的主机名或者IP,端口和service_name
c. 如果服务器listener进程没有问题的话,建立与listener进程的连接。
d. 根据不同的服务器模式如专用服务器模式或者共享服务器模式,listener采取接下去的动作。默认是专用服务器模式,没有问题的话客户端
就连接上了数据库的server process。
e. 这时连接已经建立,可以操作数据库了。
5.4)sqlplus username/password@//host:port/sid
用sqlplus远程连接oracle命令(例:sqlplus risenet/@//192.168.130.99:1521/risenet)
六、oracle 11G 的监听器默认开启了ADR特性,客户端连接信息记录客户端2种日志格式(xml 和 listener_name.log),占用大量的空间,通常只需一种日志即可满足日常维护需求。下面通过关闭其ADR特性的方式检查空间占用
. 在sqlnet.ora文件中增加 DIAG_ADR_ENABLED=off . 在监听器文件listener.ora中增加 DIAG_ADR_ENABLED_<Listener_name>=off For example, if the listener name is 'LISTENER_SCAN1', the parameter should be: DIAG_ADR_ENABLED_LISTENER_SCAN1=OFF . reload or start 监听器,使得配置生效 . 日志路径可通过命令获取 lsnrctl status|grep 'Listener Log File'
Oracle Listener的更多相关文章
- Oracle Listener日志位置及压缩转移
近日由于Oracle Listener异常断开导致应用无法上传数据,需要从listener日志开始分析问题原因.此文介绍如何获取日志位置.由于日志文件大小问题,同时将日志文件进行压缩存放. alert ...
- [Oracle] Listener的动态注册
在有Oracle Listener的动态注册之前,采用的是静态注册,所谓静态注册是指Oracle实例在启动时,读取listener.ora里的配置,然后注册到Listener,它主要有两个缺点: 1. ...
- Linux开放1521端口允许网络连接Oracle Listener
症状: 1. TCP/IP连接是通的.可以用ping 命令测试. 2. 服务器上Oracle Listener已经启动. lsnrctl status 查看listener状态 lsnrct ...
- [oracle] listener.ora 、sqlnet.ora 、tnsnames.ora
路径 $ORACLE_HOME/network/admin sqlnet.ora(客户及服务器端) 作用类似于linux或者其他unix的nsswitch.conf文件,通过这个文件来决定怎么样找一个 ...
- 怎样绕过oracle listener 监听的password设置
怎样绕过oracle 监听的password设置: 1.找到监听进程pid ,并将它kill 掉 ps -ef|grep tns [oracle@lixora admin]$ ps -ef|gr ...
- Oracle listener lsnrctl
lsnrctl(Listener Control)是一家SQL*Net具,用于控制数据库listener,此工具提供了控制命令listener开端.停止,查看listener状态,更改listener ...
- Oracle listener服务启动后又停止的解决方案
这是Oracle监听服务.忘了说我的版本是Oracle10g. 我装完Oracle数据库之后,然后用第三方工具plsql去连接,提示no listener,首先我反复检查tnsnames.ora配置文 ...
- oracle listener.ora文件配置
# listener.ora Network Configuration File: /oracleDB/product//db_1/network/admin/listener.ora # Gene ...
- Oracle LISTENER 主机名修改为IP地址后LISTENER无法监听到实例 oracle监听错误与hosts文件配置
为什么listener.ora文件里面HOST后面到底应该输入IP地址还是主机名.我的经验告诉我,这边最好使用主机名.很多的时候,一个机器绑定的不只一个IP地址,如HOST后面是IP地址,那么ORAC ...
随机推荐
- [C语言] 数据结构-预备知识动态内存分配
动态内存分配 静态内存分配数组 int a[5]={1,2,3,4,5} 动态内存分配数组 int len=5; int *parr=(int *)malloc(sizeof(int) * len) ...
- 撩课-Web大前端每天5道面试题-Day21
1.对async.await的理解,内部原理? ①async---声明一个异步函数: 自动将常规函数转换成promise,返回值也是一个promise对象, 只有async函数内部的异步操作执行完,才 ...
- 山东第四届省赛: Boring Counting 线段树
http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=3237 Problem H:Boring Counting Time Limit: 3 Sec ...
- Docker 更改镜像存储位置
在使用 Docker 的过程中,如果我们一切都以默认的设置进行操作的话,在使用一段时间之后你应该会发现系统的根目录空间越来越少,直到有一天发现空间都被占满了,最后发现原来是被 Docker 占用了.所 ...
- C# 运算符 ++在前与++在后实例分析。
首先记住计算技巧“++在前先+1,++在后后+1”. static void Main(string[] args) { int i = 10; Console.WriteLine(i);//此时i的 ...
- Android开发之旅1:环境搭建及HelloWorld
——工欲善其事必先利其器 引言 本系列适合0基础的人员,因为我就是从0开始的,此系列记录我步入Android开发的一些经验分享,望与君共勉!作为Android队伍中的一个新人的我,如果有什么不对的地方 ...
- vue自定义日历组件的实现
实现一个日期组件,如图: components.js代码如下: Vue.component('sc-calendar',{ template:'<div class="scCalend ...
- js处理包含中文的字符串
场景: js中String类型自带的属性length获取的是字符串的字符数目,但是前端经常会需要限制字符串的显示长度,一个中文字符又大概占两个英文小写字符的显示位置,所以中英文混合的情况下用lengt ...
- mysqli 更新&插入操作及事务
$mysqli = new mysqli('localhost', 'root', '1234', 'shop'); $query1 = " update sw_goods set good ...
- 微格式(microformat)
由于HTML中缺少相应的元素,很难突出显示人.地点或日期等类型的信息.为了解决这个问题,有一组开发人员决定开发一套标准的命名约定盒标记模式来表示这些数据.这些命名约定基于vCard和iCalendar ...