oracle从客户端到sql语句追踪<转>

  当我们从客户端发起一个Oracle连接的时候,要如何查看这个客户端用户此时正在执行什么事务(transaction)呢?首先,我们要搞清楚下面这几个动态性能视图的关系(如图1),以及客户端到服务器端的连接方式(如图2)。

oracle从客户端到sql语句追踪 - 了烦山人 - 了烦山人

  (图1:几个动态性能视图的关系)

V$session            列出当前登录到oracle数据库的用户总数

V$transaction      列出当前正在进行的事物

V$sql                    列出当前正在执行的sql语句

V$process      列出当前事物到底属于哪个(客户端)用户

oracle从客户端到sql语句追踪 - 了烦山人 - 了烦山人

  (图2:从Oracle客户端发起的SQL语句到服务器端的过程)

 

oracle客户端与oracle服务器端通过建立tcp连接,是进程与进程间通信(ip/prot),进程通过pid唯一来标志。

下面以一个示例来演示从客户端发起一个连接,并对这个连接的一个跟踪过程。

1. 在window上开启一个客户端连接,然后在任务管理器下面,就可以找到相关的进程及其PID。

oracle从客户端到sql语句追踪 - 了烦山人 - 了烦山人
oracle从客户端到sql语句追踪 - 了烦山人 - 了烦山人

2. 在客户端,通过netstat 命令,找到进程id为6808的连接的客户端端口,如下图,这个连接的客户端端口为51935.

oracle从客户端到sql语句追踪 - 了烦山人 - 了烦山人

3.      然后转到服务器上,用netstat 命令查找客户端为51935的连接,同时可以找到服务器上是哪个进程在提供服务,实际上到这里v$process 中的spid已经有了。

 

oracle从客户端到sql语句追踪 - 了烦山人 - 了烦山人

4.      通过netstat查找出来的SPID ,通过v$process找出ADDR

5.      通过第4步中得到的ADDR关联v$session视图的PADDR,可以找到相关的SESSION

6.      通过V$SESSION中的SADDR可以在v$transaction中找到当前执行的TRANSACTION、

7.      通过V$SESSION中的SQL_ADDRESS  可以在v$sql中找到SQL_TEXT(如下图,我们找到了之前开启session的sql)

(注:如果sql已经执行过了,则需要用prev_sql_addr 列来关联,sql_address关联的是正在执行的sql)

oracle从客户端到sql语句追踪 - 了烦山人 - 了烦山人

当然,这个过程也可以反过来:

根据当前活动的transaction 查询出 ses_addr , 然后找出对应v$session的saddr 

根据saddr查找出对应的paddr , 根据paddr找到对应v$process 的addr .

根据addr找到对应的spid ,即当前的服务端机器进程号 (如:4259)。

根据netstat -anp | grep  4259命令可以查看到当前连接的客户端的端口号,即客户端工具sqlplus的端口号。

 

几个sql:

select  addr , sid, username , s.status , process , program  from v$session s , v$transaction t   where  s.saddr = t.addr ;

-- 查询当前正在活动的进程号:线程号,程序名称

select addr, pid spid , program from v$process ;

select saddr,  sid, paddr , username, status  from  v$session ;

select  sql_text , address  , hash_value from v$sql q , v$session s where s.sid=14 and s.PREV_SQL_ADDR=q.ADDRESS ;

 

原文地址:

http://xiangqinghu1988.blog.163.com/blog/static/5882299120134208254311/

posted @ 2016-03-08 18:17  g29tony  阅读(548)  评论(0)    收藏  举报