SYS_CONTEXT('USERENV', 'HOST') Return NULL & Oracle Fixed Tables

有时候通过sys_context('userenv', 'host')  来获取当前session的client host的名字,结果却得到一个空值,很是奇怪!每次都是重启下电脑就OK了,我怀疑是windows操作系统的问题,但是又没法得到很有利的证明,因为不知道这个sys_context('usrenv', 'host') 是怎么实现的,内部代码是啥自然不清楚 :( 


不管怎样,猜测sys_context('userenv', 'host') 应该跟v$session中的MACHINE应该是一样的。那么应该可以通过v$session的定义追溯到这个信息是怎么来的。
 

下图简单描述了v$视图是如何build up的...


那么对于v$session而言,从v$fixed_view_definition中很容易得到它的定义....

SELECT s.inst_id,
s.addr,
s.indx,
s.ksuseser,
s.ksuudses,
s.ksusepro,
s.ksuudlui,
s.ksuudlna,
s.ksuudoct,
s.ksusesow,
DECODE (s.ksusetrn, HEXTORAW (
'00'), NULL, s.ksusetrn),
DECODE (s.ksqpswat, HEXTORAW (
'00'), NULL, s.ksqpswat),
DECODE (
BITAND (s.ksuseidl,
11),
1, 'ACTIVE',
0, DECODE (BITAND (s.ksuseflg, 4096), 0, 'INACTIVE', 'CACHED'),
2, 'SNIPED',
3, 'SNIPED',
'KILLED'),
DECODE (s.ksspatyp,
1, 'DEDICATED',
2, 'SHARED',
3, 'PSEUDO',
'NONE'),
s.ksuudsid,
s.ksuudsna,
s.ksuseunm,
s.ksusepid,
s.ksusemnm,
s.ksusetid,
s.ksusepnm,
DECODE (BITAND (s.ksuseflg,
19),
17, 'BACKGROUND',
1, 'USER',
2, 'RECURSIVE',
'?'),
s.ksusesql,
s.ksusesqh,
s.ksusesqi,
DECODE (s.ksusesch,
65535, TO_NUMBER (NULL), s.ksusesch),
s.ksusepsq,
s.ksusepha,
s.ksusepsi,
DECODE (s.ksusepch,
65535, TO_NUMBER (NULL), s.ksusepch),
DECODE (s.ksusepeo,
0, TO_NUMBER (NULL), s.ksusepeo),
DECODE (s.ksusepeo,
0, TO_NUMBER (NULL), s.ksusepes),
DECODE (s.ksusepco,
0, TO_NUMBER (NULL), s.ksusepco),
DECODE (s.ksusepco,
0, TO_NUMBER (NULL), s.ksusepcs),
s.ksuseapp,
s.ksuseaph,
s.ksuseact,
s.ksuseach,
s.ksusecli,
s.ksusefix,
s.ksuseobj,
s.ksusefil,
s.ksuseblk,
s.ksuseslt,
s.ksuseltm,
s.ksusectm,
DECODE (BITAND (s.ksusepxopt,
12), 0, 'NO', 'YES'),
DECODE (s.ksuseft,
2, 'SESSION',
4, 'SELECT',
8, 'TRANSACTIONAL',
'NONE'),
DECODE (s.ksusefm,
1, 'BASIC',
2, 'PRECONNECT',
4, 'PREPARSE',
'NONE'),
DECODE (s.ksusefs,
1, 'YES', 'NO'),
s.ksusegrp,
DECODE (BITAND (s.ksusepxopt,
4),
4, 'ENABLED',
DECODE (BITAND (s.ksusepxopt,
8), 8, 'FORCED', 'DISABLED')),
DECODE (BITAND (s.ksusepxopt,
2),
2, 'FORCED',
DECODE (BITAND (s.ksusepxopt,
1), 1, 'DISABLED', 'ENABLED')),
DECODE (BITAND (s.ksusepxopt,
32),
32, 'FORCED',
DECODE (BITAND (s.ksusepxopt,
16), 16, 'DISABLED', 'ENABLED')),
s.ksusecqd,
s.ksuseclid,
DECODE (s.ksuseblocker,
4294967295, 'UNKNOWN',
4294967294, 'UNKNOWN',
4294967293, 'UNKNOWN',
4294967292, 'NO HOLDER',
4294967291, 'NOT IN WAIT',
'VALID'),
DECODE (s.ksuseblocker,
4294967295, TO_NUMBER (NULL),
4294967294, TO_NUMBER (NULL),
4294967293, TO_NUMBER (NULL),
4294967292, TO_NUMBER (NULL),
4294967291, TO_NUMBER (NULL),
BITAND (s.ksuseblocker,
2147418112) / 65536),
DECODE (s.ksuseblocker,
4294967295, TO_NUMBER (NULL),
4294967294, TO_NUMBER (NULL),
4294967293, TO_NUMBER (NULL),
4294967292, TO_NUMBER (NULL),
4294967291, TO_NUMBER (NULL),
BITAND (s.ksuseblocker,
65535)),
s.ksuseseq,
s.ksuseopc,
e.kslednam,
e.ksledp1,
s.ksusep1,
s.ksusep1r,
e.ksledp2,
s.ksusep2,
s.ksusep2r,
e.ksledp3,
s.ksusep3,
s.ksusep3r,
e.ksledclassid,
e.ksledclass#,
e.ksledclass,
DECODE (
s.ksusetim,
0, 0,
-1, -1,
-2, -2,
DECODE (
ROUND (s.ksusetim / 10000),
0, -1,
ROUND (s.ksusetim / 10000))),
s.ksusewtm,
DECODE (
s.ksusetim,
0, 'WAITING',
-2, 'WAITED UNKNOWN TIME',
-1, 'WAITED SHORT TIME',
DECODE (
ROUND (s.ksusetim / 10000),
0, 'WAITED SHORT TIME',
'WAITED KNOWN TIME')),
s.ksusesvc,
DECODE (BITAND (s.ksuseflg2,
32), 32, 'ENABLED', 'DISABLED'),
DECODE (BITAND (s.ksuseflg2,
64), 64, 'TRUE', 'FALSE'),
DECODE (BITAND (s.ksuseflg2,
128), 128, 'TRUE', 'FALSE')
FROM x$ksuse s, x$ksled e
WHERE BITAND (s.ksspaflg, 1) != 0
AND BITAND (s.ksuseflg, 1) != 0
AND s.ksuseopc = e.indx

  

那么v$session中的machine是从表x$ksuse (Kernel Service User SEssion)中得来的.... 

select ksusemnm from x$ksuse

  

只可惜到这个地方就不知道怎么往下走了,毕竟x$ksuse是oracle写死在代码里面的,看不到怎么实现的:(  不过应该都是调用C语言的一些库从操作系统得到系统的相关信息。如果得不到host name,那么很可能就是操作系统出了点问题,否则也不会我重启机器就可以解决问题了。

关于X$ table,下面这些链接有比较详细的描述....

http://oracle-abc.wikidot.com/x-tables

http://www.oracle-internals.com/?p=11

原文地址:https://www.cnblogs.com/fangwenyu/p/2132436.html