您的位置:首页 > 数据库 > Oracle

【Oracle】记一次数据库连接没有关闭导致数据库宕机的排查过程

2017-07-31 11:33 441 查看
笔者在之前的项目中,发现服务部署上去之后,过了很大概几天,数据库宕机了,当时以为可能只是一次偶然异常,并没有在意,于是重启数据库就行了。但是之后,发现过了一段时间数据库又宕机了。于是重视起来,决定排查以下异常信息,因为系统已经上线使用,因此只能在夜间排查问题,苦逼地夜间调代码,让我想起删除生产库跑路的段子,hhhhh。

言归正传,查看服务端会输出以下的异常信息:

ora-12518: 监听程序无法分发客户机连接

ora-12520:TNS: 监听程序无法为请求的服务器类型找到可用的处理程序

从上面来看是连接数超限了,于是决定重新检查一下数据库的连接数,查看有哪些用户,哪些机器连接了数据库,一个一个的排查。查出是哪台机器造成的之后,再查是那个用户连接的,以什么用户名登录的,然后继续跟踪到sql层面,是哪一句sql造成的,这样就可以根据sql来定位到代码中的数据库连接那部分。之后就可以排查出问题了。这里主要是涉及到两个视图v$session和v$sql这两个视图。

这里介绍一下两个概念:

process和session

session与process的关系

oracle的连接数(sessions)与其参数文件中的进程数(process)相关,它们的关系如下:sessions=(1.1*process+5),若果资源允许,而当前process

数过小,那么可以适当增大processs 数( session 数依赖于process数,一般不去直接修改session数)。

Shared Server中的Process 一个对应着Oracle 中的一个或者一个以上的Session。Dedicated

Server中,一个session对应一个process,但是一个process未必对应一个session。

至于这里的shared和dedicated参数的设置是在安装数据库的时候我们设置的oracle的数据库模式,设置完之后,我们可以在tnsnames.ora里面查看到数据库是shared还是dedicated。

如何修改session与process

v$session 每一个连接到数据库实例中的session都拥有一条记录。包括用户session及后台进程如DBWR,LGWR,arcchiver等等。

V$process 本视图包含当前系统oracle运行的所有进程信息。常被用于将oracle或服务进程的操作系统进程ID与数据库session之间建立联系。

show parameter sessions 查看当前session配置

show parameter processes 查看当前process配置

alter system set processes=1000 scope=spfile .更改配置,更改完后需要重启数据库(因为这个后面这个是在spfile里设置的,因此这个设置会写入到spfile,数据库默认启动时会加载spfile中的设置)。

对于spfile和pfile,我想对这篇文章感兴趣:

ORACLE的SPFILE与PFILE

两个重要的动态视图的使用

(1)v$session

会话视图:

里面包含的主要信息有machine(计算机名),logon_time(登录时间),prev_sql_id(上次执行的sql_id,可以和v$sql里面的sql_id关联),program(打开会话的程序,可能有几种,JDBC Thin Client、PL/SQL Developer)

(2)v$sql

主要包含:module(对应于上面的program)、sql_text(sql语句)、last_active_time

SQL_TEXT:SQL文本的前1000个字符

SHARABLE_MEM:占用的共享内存大小(单位:byte)

PERSISTENT_MEM:生命期内的固定内存大小(单位:byte)

RUNTIME_MEM:执行期内的固定内存大小

SORTS:完成的排序数

LOADED_VERSIONS:显示上下文堆是否载入,1是0否

OPEN_VERSIONS:显示子游标是否被锁,1是0否

USERS_OPENING:执行语句的用户数

FETCHES:SQL语句的fetch数。

EXECUTIONS:自它被载入缓存库后的执行次数

USERS_EXECUTING:执行语句的用户数

LOADS:对象被载入过的次数

FIRST_LOAD_TIME:初次载入时间

INVALIDATIONS:无效的次数

PARSE_CALLS:解析调用次数

DISK_READS:读磁盘次数

BUFFER_GETS:读缓存区次数

ROWS_PROCESSED:解析SQL语句返回的总列数

COMMAND_TYPE:命令类型代号

OPTIMIZER_MODE:SQL语句的优化器模型

OPTIMIZER_COST:优化器给出的本次查询成本

PARSING_USER_ID:第一个解析的用户ID

PARSING_SCHEMA_ID:第一个解析的计划ID

KEPT_VERSIONS:指出是否当前子游标被使用DBMS_SHARED_POOL包标记为常驻内存

ADDRESS:当前游标父句柄地址

TYPE_CHK_HEAP:当前堆类型检查说明

HASH_VALUE:缓存库中父语句的Hash值

PLAN_HASH_VALUE:数值表示的执行计划。

CHILD_NUMBER:子游标数量

MODULE:在第一次解析这条语句是通过调用DBMS_APPLICATION_INFO.SET_MODULE设置的模块名称。

ACTION:在第一次解析这条语句是通过调用DBMS_APPLICATION_INFO.SET_ACTION设置的动作名称。

SERIALIZABLE_ABORTS:事务未能序列化次数

OUTLINE_CATEGORY:如果outline在解释cursor期间被应用,那么本列将显示出outline各类,否则本列为空

CPU_TIME:解析/执行/取得等CPU使用时间(单位,毫秒)

ELAPSED_TIME:解析/执行/取得等消耗时间(单位,毫秒)

OUTLINE_SID:outline session标识

CHILD_ADDRESS:子游标地址

SQLTYPE:指出当前语句使用的SQL语言版本

REMOTE:指出是否游标是一个远程映象(Y/N)

OBJECT_STATUS:对象状态(VALID or INVALID)

IS_OBSOLETE:当子游标的数量太多的时候,指出游标是否被废弃(Y/N)

通过上面的两个视图可以排查出哪个用户,哪句sql执行完毕之后,没有关闭数据库连接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐