[20260824]数字字典对象hash的计算.txt
[20260824]数字字典对象hash的计算.txt
--//前几天探究row cache时,好奇对应的hash值如何计算,经过多次尝试,大致知道算法。
1.环境:
SYS@book> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
2.提问:
--//在kimi上提问,给出计算调用kqrhsh函数,仔细查看反汇编真正计算的是kgghash函数。而且还问oracle可能使用的算法.
--//给出的结论,猜测3种算法,最大可能是Jenkins Lookup3,不熟悉也不懂,不过这个不重要。
--//摘要如下:
--//从 Oracle 内部函数的命名和历史实现来看,kgghash 很可能是Jenkins Lookup3.
--//典型情况是级联调用模式(用前次结果作 seed)是 lookup3 的典型用法.
--//猜测 A:Jenkins Lookup3 的 Oracle 变体
--//Oracle 内部大量使用 Bob Jenkins 的哈希算法。kgghash 的签名(data, len, seed)与 lookup3 完全一致.
--//如果我的理解没错的话,使用ora_hash函数应该也可以计算出结果.
$ cat dc_hash.bt
BEGIN
{
printf("Tracing Oracle kgghash... Target PID: %d\n", $1);
printf("Hit Ctrl-C to stop.\n\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("\nkrqhsh Begin\n");
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("krqhsh End\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
@kgg++;
@is_kgg[pid] = 1;
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x hash_text_ascii = ", strftime("%H:%M:%S", nsecs), @kgg, pid,str(arg0,arg1+1),arg1,arg2);
// print(buf(str(arg0,arg1+1),arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
// printf("xxxx = %s %s %s\n",str(arg0,arg1),str(arg0,arg1+1),buf(arg0,arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(arg0,arg1), arg1,arg2);
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
if (@is_kgg[pid] == 1) {
printf("[%s] kgghash #%02d pid=%d return hash_value=%016lx %ld %016lx %d\n", strftime("%H:%M:%S", nsecs), @kgg,pid, retval, retval, retval%32768,retval%32768);
delete(@is_kgg[pid]);
}
}
END
{
printf("\nTotal kgghash: %d\n", @kgg);
delete(@kgg);
}
3.使用bpftrace跟踪:
SYS@book> @ spid
==============================
SID : 30
SERIAL# : 900
PROCESS : 3156
SERVER : DEDICATED
SPID : 3157
PID : 8
P_SERIAL# : 6
KILL_COMMAND : alter system kill session '30,900' immediate;
PL/SQL procedure successfully completed.
--//先在cdb下执行 select sid from v$mystat where rownum=1;多次,切换界面执行# bpftrace ./dc_hash.bt 3157。
SYS@book> select sid from v$mystat where rownum=1;
SID
----------
30
# bpftrace dc_hash.bt 3157
Attached 6 probes
Tracing Oracle kgghash... Target PID: 3157
Hit Ctrl-C to stop.
[15:45:21] kgghash #01 pid=3157 hash_text=CDB$ROOT length=8 seed=0
[15:45:21] kgghash #01 pid=3157 return hash_value=000000001eee6512 518939922 0000000000006512 25874
krqhsh Begin
[15:45:21] kgghash #02 pid=3157 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[15:45:21] kgghash #02 pid=3157 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
[15:45:21] kgghash #03 pid=3157 hash_text=CDB$ROOT length=8 seed=f28adaf8
[15:45:21] kgghash #03 pid=3157 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
krqhsh Begin
[15:45:21] kgghash #04 pid=3157 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[15:45:21] kgghash #04 pid=3157 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
[15:45:21] kgghash #05 pid=3157 hash_text=CDB$ROOT length=8 seed=f28adaf8
[15:45:21] kgghash #05 pid=3157 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
krqhsh Begin
[15:45:21] kgghash #06 pid=3157 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[15:45:21] kgghash #06 pid=3157 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
[15:45:21] kgghash #07 pid=3157 hash_text=CDB$ROOT length=8 seed=368bf4a4
[15:45:21] kgghash #07 pid=3157 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
krqhsh Begin
[15:45:21] kgghash #08 pid=3157 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[15:45:21] kgghash #08 pid=3157 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
[15:45:21] kgghash #09 pid=3157 hash_text=CDB$ROOT length=8 seed=368bf4a4
[15:45:21] kgghash #09 pid=3157 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
[15:45:21] kgghash #10 pid=3157 hash_text=\x0b\x00\x01\x00\x00\x00\x00\x00 length=8 seed=0
[15:45:21] kgghash #10 pid=3157 return hash_value=00000000ceb5d99e 3468024222 000000000000599e 22942
--//简单解析:
--//hash_text=\xc3\xc0\xff\xff, intel cpu 大小头问题,大小头对调对应整形
--//0xffffc0c3 = 4294951107
--//0xffffc3fa = 4294951930
SYS@book> @ xtab X$KSUSGIF|^V$MYSTAT
INST_ID NAME OBJECT_ID TYPE TABLE_NUM CON_ID
---------- ------------------------------ ---------- ------------------------------ ---------- ----------
1 X$KSUSGIF 4294951930 TABLE 52 0
1 V$MYSTAT 4294951107 VIEW 65537 0
4.先简单验证:
[15:45:21] kgghash #01 pid=3157 hash_text=CDB$ROOT length=8 seed=0
[15:45:21] kgghash #01 pid=3157 return hash_value=000000001eee6512 518939922 0000000000006512 25874
--//0xffffffff = 4294967295
$ cat ora_hash1.txt
select
ora_hash('&&1',4294967295,&2) n20
,to_char(ora_hash('&1',4294967295,&2),'FM0xxxxxxxxxxxxxxx') c20
from dual;
--//缺省ora_hash函数最大max_bucket=2^3201=4294967295,seed=0,采用如下计算结果一样。
SYS@book> select to_char(ora_hash('CDB$ROOT'),'FM0xxxxxxxxxxxxxxx') c20 from dual;
C20
--------------------
000000001eee6512
SYS@book> @ ora_hash1.txt CDB$ROOT 0
N20 C20
--------------------- --------------------
518939922 000000001eee6512
--//说明推断可能正确,如果这步不正确的话,估计我当时就放弃猜测。
--//再验证如下:
krqhsh Begin
[15:45:21] kgghash #02 pid=3157 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[15:45:21] kgghash #02 pid=3157 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
[15:45:21] kgghash #03 pid=3157 hash_text=CDB$ROOT length=8 seed=f28adaf8
[15:45:21] kgghash #03 pid=3157 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
--//这里的hash_text 对应的ascii码\xc3\xc0\xff\xff,注:bpftrace的buf函数如果字符可以显示,直接输出对应字符。
--//为了测试方便另外写一个脚本:
$ cat ora_hash2.txt
select
ora_hash(UTL_RAW.cast_to_varchar2(hextoraw('&1')),4294967295,&2) n20
,to_char(ora_hash(UTL_RAW.cast_to_varchar2(hextoraw('&1')),4294967295,&2),'FM0xxxxxxxxxxxxxxx') c20
from dual;
[15:45:21] kgghash #02 pid=3157 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[15:45:21] kgghash #02 pid=3157 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
SYS@book> @ ora_hash2.txt c3c0ffff 0
N20 C20
--------------------- --------------------
4069186296 00000000f28adaf8
--//hash_value=00000000f28adaf8完全对上。
--//然后级联调用模式,可以理解为迭代(不知道是否正确),seed=4069186296继续运算。
[15:45:21] kgghash #03 pid=3157 hash_text=CDB$ROOT length=8 seed=f28adaf8
[15:45:21] kgghash #03 pid=3157 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
SYS@book> @ ora_hash1.txt CDB$ROOT 4069186296
N20 C20
--------------------- --------------------
1185782394 0000000046ad9a7a
--//hash_value=0000000046ad9a7a完全对上,证明我的猜测正确。
SYS@book> select mod(1185782394,power(2,15)) from dual ;
MOD(1185782394,POWER(2,15))
---------------------------
6778
--//6778= 0x1a7a
--//再来验证如下情况:
krqhsh Begin
[15:45:21] kgghash #08 pid=3157 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[15:45:21] kgghash #08 pid=3157 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
[15:45:21] kgghash #09 pid=3157 hash_text=CDB$ROOT length=8 seed=368bf4a4
[15:45:21] kgghash #09 pid=3157 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
SYS@book> @ ora_hash2.txt fac3ffff 0
N20 C20
--------------------- --------------------
915141796 00000000368bf4a4
SYS@book> @ ora_hash1.txt CDB$ROOT 915141796
N20 C20
--------------------- --------------------
1087871609 0000000040d79a79
SYS@book> select mod(1087871609,power(2,15)) from dual ;
MOD(1087871609,POWER(2,15))
---------------------------
6777
--//6777 = 0x1a79,两者不知道是否巧合正好hash相差1.
--//继续验证:
[15:45:21] kgghash #10 pid=3157 hash_text=\x0b\x00\x01\x00\x00\x00\x00\x00 length=8 seed=0
[15:45:21] kgghash #10 pid=3157 return hash_value=00000000ceb5d99e 3468024222 000000000000599e 22942
SYS@book> @ ora_hash2.txt 0b00010000000000 0
N20 C20
--------------------- --------------------
3468024222 00000000ceb5d99e
--//完全对上。
4.小结:
--//数据字典对象的hash计算基本通过类似ora_hash函数,参与运算的数据包括对象属性,比如前面测试的情况object_id,cdb_name之类
--//属性,然后不断级联迭代得到hash结果。不同类型对象参与计算属性可能不同,没有必要追求这些细节。
--//前几天探究row cache时,好奇对应的hash值如何计算,经过多次尝试,大致知道算法。
1.环境:
SYS@book> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
2.提问:
--//在kimi上提问,给出计算调用kqrhsh函数,仔细查看反汇编真正计算的是kgghash函数。而且还问oracle可能使用的算法.
--//给出的结论,猜测3种算法,最大可能是Jenkins Lookup3,不熟悉也不懂,不过这个不重要。
--//摘要如下:
--//从 Oracle 内部函数的命名和历史实现来看,kgghash 很可能是Jenkins Lookup3.
--//典型情况是级联调用模式(用前次结果作 seed)是 lookup3 的典型用法.
--//猜测 A:Jenkins Lookup3 的 Oracle 变体
--//Oracle 内部大量使用 Bob Jenkins 的哈希算法。kgghash 的签名(data, len, seed)与 lookup3 完全一致.
--//如果我的理解没错的话,使用ora_hash函数应该也可以计算出结果.
$ cat dc_hash.bt
BEGIN
{
printf("Tracing Oracle kgghash... Target PID: %d\n", $1);
printf("Hit Ctrl-C to stop.\n\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("\nkrqhsh Begin\n");
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("krqhsh End\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
@kgg++;
@is_kgg[pid] = 1;
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x hash_text_ascii = ", strftime("%H:%M:%S", nsecs), @kgg, pid,str(arg0,arg1+1),arg1,arg2);
// print(buf(str(arg0,arg1+1),arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
// printf("xxxx = %s %s %s\n",str(arg0,arg1),str(arg0,arg1+1),buf(arg0,arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(arg0,arg1), arg1,arg2);
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
if (@is_kgg[pid] == 1) {
printf("[%s] kgghash #%02d pid=%d return hash_value=%016lx %ld %016lx %d\n", strftime("%H:%M:%S", nsecs), @kgg,pid, retval, retval, retval%32768,retval%32768);
delete(@is_kgg[pid]);
}
}
END
{
printf("\nTotal kgghash: %d\n", @kgg);
delete(@kgg);
}
3.使用bpftrace跟踪:
SYS@book> @ spid
==============================
SID : 30
SERIAL# : 900
PROCESS : 3156
SERVER : DEDICATED
SPID : 3157
PID : 8
P_SERIAL# : 6
KILL_COMMAND : alter system kill session '30,900' immediate;
PL/SQL procedure successfully completed.
--//先在cdb下执行 select sid from v$mystat where rownum=1;多次,切换界面执行# bpftrace ./dc_hash.bt 3157。
SYS@book> select sid from v$mystat where rownum=1;
SID
----------
30
# bpftrace dc_hash.bt 3157
Attached 6 probes
Tracing Oracle kgghash... Target PID: 3157
Hit Ctrl-C to stop.
[15:45:21] kgghash #01 pid=3157 hash_text=CDB$ROOT length=8 seed=0
[15:45:21] kgghash #01 pid=3157 return hash_value=000000001eee6512 518939922 0000000000006512 25874
krqhsh Begin
[15:45:21] kgghash #02 pid=3157 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[15:45:21] kgghash #02 pid=3157 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
[15:45:21] kgghash #03 pid=3157 hash_text=CDB$ROOT length=8 seed=f28adaf8
[15:45:21] kgghash #03 pid=3157 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
krqhsh Begin
[15:45:21] kgghash #04 pid=3157 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[15:45:21] kgghash #04 pid=3157 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
[15:45:21] kgghash #05 pid=3157 hash_text=CDB$ROOT length=8 seed=f28adaf8
[15:45:21] kgghash #05 pid=3157 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
krqhsh Begin
[15:45:21] kgghash #06 pid=3157 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[15:45:21] kgghash #06 pid=3157 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
[15:45:21] kgghash #07 pid=3157 hash_text=CDB$ROOT length=8 seed=368bf4a4
[15:45:21] kgghash #07 pid=3157 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
krqhsh Begin
[15:45:21] kgghash #08 pid=3157 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[15:45:21] kgghash #08 pid=3157 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
[15:45:21] kgghash #09 pid=3157 hash_text=CDB$ROOT length=8 seed=368bf4a4
[15:45:21] kgghash #09 pid=3157 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
[15:45:21] kgghash #10 pid=3157 hash_text=\x0b\x00\x01\x00\x00\x00\x00\x00 length=8 seed=0
[15:45:21] kgghash #10 pid=3157 return hash_value=00000000ceb5d99e 3468024222 000000000000599e 22942
--//简单解析:
--//hash_text=\xc3\xc0\xff\xff, intel cpu 大小头问题,大小头对调对应整形
--//0xffffc0c3 = 4294951107
--//0xffffc3fa = 4294951930
SYS@book> @ xtab X$KSUSGIF|^V$MYSTAT
INST_ID NAME OBJECT_ID TYPE TABLE_NUM CON_ID
---------- ------------------------------ ---------- ------------------------------ ---------- ----------
1 X$KSUSGIF 4294951930 TABLE 52 0
1 V$MYSTAT 4294951107 VIEW 65537 0
4.先简单验证:
[15:45:21] kgghash #01 pid=3157 hash_text=CDB$ROOT length=8 seed=0
[15:45:21] kgghash #01 pid=3157 return hash_value=000000001eee6512 518939922 0000000000006512 25874
--//0xffffffff = 4294967295
$ cat ora_hash1.txt
select
ora_hash('&&1',4294967295,&2) n20
,to_char(ora_hash('&1',4294967295,&2),'FM0xxxxxxxxxxxxxxx') c20
from dual;
--//缺省ora_hash函数最大max_bucket=2^3201=4294967295,seed=0,采用如下计算结果一样。
SYS@book> select to_char(ora_hash('CDB$ROOT'),'FM0xxxxxxxxxxxxxxx') c20 from dual;
C20
--------------------
000000001eee6512
SYS@book> @ ora_hash1.txt CDB$ROOT 0
N20 C20
--------------------- --------------------
518939922 000000001eee6512
--//说明推断可能正确,如果这步不正确的话,估计我当时就放弃猜测。
--//再验证如下:
krqhsh Begin
[15:45:21] kgghash #02 pid=3157 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[15:45:21] kgghash #02 pid=3157 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
[15:45:21] kgghash #03 pid=3157 hash_text=CDB$ROOT length=8 seed=f28adaf8
[15:45:21] kgghash #03 pid=3157 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
--//这里的hash_text 对应的ascii码\xc3\xc0\xff\xff,注:bpftrace的buf函数如果字符可以显示,直接输出对应字符。
--//为了测试方便另外写一个脚本:
$ cat ora_hash2.txt
select
ora_hash(UTL_RAW.cast_to_varchar2(hextoraw('&1')),4294967295,&2) n20
,to_char(ora_hash(UTL_RAW.cast_to_varchar2(hextoraw('&1')),4294967295,&2),'FM0xxxxxxxxxxxxxxx') c20
from dual;
[15:45:21] kgghash #02 pid=3157 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[15:45:21] kgghash #02 pid=3157 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
SYS@book> @ ora_hash2.txt c3c0ffff 0
N20 C20
--------------------- --------------------
4069186296 00000000f28adaf8
--//hash_value=00000000f28adaf8完全对上。
--//然后级联调用模式,可以理解为迭代(不知道是否正确),seed=4069186296继续运算。
[15:45:21] kgghash #03 pid=3157 hash_text=CDB$ROOT length=8 seed=f28adaf8
[15:45:21] kgghash #03 pid=3157 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
SYS@book> @ ora_hash1.txt CDB$ROOT 4069186296
N20 C20
--------------------- --------------------
1185782394 0000000046ad9a7a
--//hash_value=0000000046ad9a7a完全对上,证明我的猜测正确。
SYS@book> select mod(1185782394,power(2,15)) from dual ;
MOD(1185782394,POWER(2,15))
---------------------------
6778
--//6778= 0x1a7a
--//再来验证如下情况:
krqhsh Begin
[15:45:21] kgghash #08 pid=3157 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[15:45:21] kgghash #08 pid=3157 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
[15:45:21] kgghash #09 pid=3157 hash_text=CDB$ROOT length=8 seed=368bf4a4
[15:45:21] kgghash #09 pid=3157 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
SYS@book> @ ora_hash2.txt fac3ffff 0
N20 C20
--------------------- --------------------
915141796 00000000368bf4a4
SYS@book> @ ora_hash1.txt CDB$ROOT 915141796
N20 C20
--------------------- --------------------
1087871609 0000000040d79a79
SYS@book> select mod(1087871609,power(2,15)) from dual ;
MOD(1087871609,POWER(2,15))
---------------------------
6777
--//6777 = 0x1a79,两者不知道是否巧合正好hash相差1.
--//继续验证:
[15:45:21] kgghash #10 pid=3157 hash_text=\x0b\x00\x01\x00\x00\x00\x00\x00 length=8 seed=0
[15:45:21] kgghash #10 pid=3157 return hash_value=00000000ceb5d99e 3468024222 000000000000599e 22942
SYS@book> @ ora_hash2.txt 0b00010000000000 0
N20 C20
--------------------- --------------------
3468024222 00000000ceb5d99e
--//完全对上。
4.小结:
--//数据字典对象的hash计算基本通过类似ora_hash函数,参与运算的数据包括对象属性,比如前面测试的情况object_id,cdb_name之类
--//属性,然后不断级联迭代得到hash结果。不同类型对象参与计算属性可能不同,没有必要追求这些细节。
浙公网安备 33010602011771号