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

(图1:几个动态性能视图的关系)
V$session 列出当前登录到oracle数据库的用户总数
V$transaction 列出当前正在进行的事物
V$sql 列出当前正在执行的sql语句
V$process 列出当前事物到底属于哪个(客户端)用户

(图2:从Oracle客户端发起的SQL语句到服务器端的过程)
oracle客户端与oracle服务器端通过建立tcp连接,是进程与进程间通信(ip/prot),进程通过pid唯一来标志。
下面以一个示例来演示从客户端发起一个连接,并对这个连接的一个跟踪过程。
1. 在window上开启一个客户端连接,然后在任务管理器下面,就可以找到相关的进程及其PID。


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

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

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)

当然,这个过程也可以反过来:
根据当前活动的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/

浙公网安备 33010602011771号