暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

JDBC连接为什么v$session.process=1234,真相原来是这个!

DigOps 2020-05-30
1061

作为一个运维DBA,运维手段除了具备扎实的数据库原理的基本功以外,还要彻底去了解经常使用的视图,包括视图的功能、视图字段的含义。


最近在排查锁问题时,无意中多看了一眼v$session.process,多看一眼是因为查询时一时着急谓词没写全,多打印出一些信息,经过排序仔细一看,发现MODULE=JDBC Thin Client时,process字段清一色为1234,TERMINAL为unknow!以前一直没当回事,这次产生了好奇,就花些时间琢磨了一番。


先来看看v$session.process的定义

Operating system client process ID,如果按照字面翻译,很可能就误入歧途了。它真正的含义是,“在客户端服务器上的进程ID”,理解了这个,基本上就能搞定后面很多事情了。

栗子

通过PL/SQL Developer连接Oracle数据库,在数据库中查询出工具信息如下:

      PORT MACHINE                        OSUSER   MODULE              PROGRAM         PROCESS                         PID SPID
---------- ------------------------------ -------- ------------------- --------------- ------------------------ ---------- -------
      5160 WORKGROUP\DELL-T110II          AI       PL/SQL Developer    plsqldev.exe    14600:16516                     603 26557
      5300 WORKGROUP\DELL-T110II          AI       PL/SQL Developer    plsqldev.exe    14600:16516                     605 31146
      5306 WORKGROUP\DELL-T110II          AI       PL/SQL Developer    plsqldev.exe    14600:16516                     608 31326

process列,是14600:16516,这和上面说的进程ID,也不是一回事呀?我最开始也纳闷,官方文档上也没有,就通过网上搜索,信息不好找,很少。经过一番查看,原来格式是这样的意思:process id:thread id


只听别人说,看别人写还不够严谨,所以我打算自己验证一下,在我的windows机器上,用工具查看这两项内容

正好验证了,进程ID(PID)和线程ID(TID)


JDBC 连接数据库

为什么查出来v$session.process都是1234呢?


由于我需要一起验证v$locked_object的process真正含义,所以就用如下查询(存在锁的情况才会有打印输出!

select distinct sid,
                osuser,
                s.terminal,
                module,
                pid,
                spid,
                s.process  as process_s,
                lo.process as process_lo
  from v$session s, v$process p, v$locked_object lo
 where s.paddr = p.addr
   and s.sid = lo.session_id;


输出内容:

       SID OSUSER       TERMINAL      MODULE                          PID SPID             PROCESS_S            PROCESS_LO
---------- ------------ ------------- ------------------------ ---------- ---------------- -------------------- --------------
      2108 hellox       unknown       JDBC Thin Client                 70 25822196         1234                 1234
      4387 hellox       unknown       JDBC Thin Client                238 23724558         1234                 1234
      4286 hellox       unknown       JDBC Thin Client                237 21430982         1234                 1234
       579 hellox       unknown       JDBC Thin Client                246 22021062         1234                 1234

这里同时验证了一点,v$locked_object.process=v$session.process。


下面就是寻找为什么jdbc thin在v$session.process中查出来是1234了?


搜索Oracle MOS上找到一篇文章《How to Set V$SESSION Properties Using the JDBC Thin Driver (Doc ID 147413.1)》,里面包含了如下一段说明,大意是,JDBC Thin驱动程序无法正确检索出自己会话的v$session某些属性值,v$session.terminal字段会返回 "unknow",由于无法使用JDBC Thin驱动程序获取到process id,引起v$session.process会返回“1234”。

Note: The JDBC Thin driver cannot correctly retrieve the values of some V$SESSION properties on its own. Specifically, the driver exhibits the following behavior:

    When querying the TERMINAL field of the V$SESSION table using the JDBC Thin driver, the value returned is "unknown".
    When querying the PROCESS field of the V$SESSION table using the JDBC Thin driver, the value returned is "1234". The driver returns the process ID as "1234" by default, since obtaining a process ID is not possible using the JDBC Thin driver.


这里应该明确了,jdbc连接请求后,会话属性的terminal及process默认是null,也就是什么也没有,所以才会无法取到。process=1234,应该也是jdbc驱动中默认设置的一个值,国外有人说JDBC开发者认为”1234“是一个吉利数字,可以用来取代”unknow“ 。


反编译JDBC后验证猜想

代码段:v$session.terminal

    str1 = null;
    if (paramProperties != null)
    {
      str1 = paramProperties.getProperty("v$session.terminal");
      if (str1 == null)
        str1 = paramProperties.getProperty("oracle.jdbc.v$session.terminal");
    }
    if (str1 == null)
      str1 = getSystemProperty("oracle.jdbc.v$session.terminal"null);
    if (str1 == null) {
      str1 = "unknown";
    }



代码段:v$session.process

this.thinVsessionProgram = str1;

    str1 = null;
    if (paramProperties != null)
    {
      str1 = paramProperties.getProperty("v$session.process");
      if (str1 == null)
        str1 = paramProperties.getProperty("oracle.jdbc.v$session.process");
    }
    if (str1 == null)
      str1 = getSystemProperty("oracle.jdbc.v$session.process"null);
    if (str1 == null) {
      str1 = "1234";
    }




文章转载自DigOps,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论