代码改变世界

Oracle的聚簇也Hold不住了

  心中无码  阅读(2030)  评论(7编辑  收藏  举报

       这两天在研究Oracle的Cluster,这里的Cluster不是聚簇索引的意思。Cluster是Oracle特有的一种数据存储方式,即把相关的数据存储在同一个数据块上,如果一组表有一些共同的列,则将这样的一些表存储在相同的数据块上,这样对于主外键这种连接操作,会起到减少I/O的作用。

      Oracle支持两种方式的Cluster,即Index Cluster和Hash Cluster。其实现的原理就是抛弃原始的B树的扫描阶段,尽可能快的定位到具体的数据页。这在Hash Cluster上展现的更为明显。在TPC-C测试中,Oralce的很多表都是建立在Hash Cluster上的,可见这种Cluster对性能的影响了。当然Oracle本身的一些系统表也是建立在Cluster上的。

       按理说这种Cluster应该很稳定了,可是经过我简单的测试,竟然发现了两个导致客户端断开连接的bug,这也太坑爹了吧,哥只想对甲骨文的测试人员说:少年,奋起吧!

       下面分别就两个bug进行阐述(关于簇的使用说明可以参考《Oracle9i10g编程艺术》)。

  • bug1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
DROP CLUSTER CLUSTER_TEST1 INCLUDING TABLES;
 
CREATE CLUSTER CLUSTER_TEST1(C1 INT , C2 INT SORT)
HASHKEYS 11
SIZE  1024
HASH IS MOD(C1,2) + C2;
 
CREATE TABLE CLUSTER_T1(C1 INT, C2 INT SORT) cluster CLUSTER_TEST1 (C1, C2);
 
INSERT INTO CLUSTER_T1 VALUES(1,3);
INSERT INTO CLUSTER_T1 VALUES(1,2);
INSERT INTO CLUSTER_T1 VALUES(1,1);
INSERT INTO CLUSTER_T1 VALUES(2,3);
INSERT INTO CLUSTER_T1 VALUES(2,2);
INSERT INTO CLUSTER_T1 VALUES(2,1);
 
 
COMMIT;
 
select c1,c2 from cluster_t1 where c1 =1 order by c2;
 
 
SQL> select c1,c2 from cluster_t1 where c1 =1 order by c2;
select c1,c2 from cluster_t1 where c1 =1 order by c2
*
第 1 行出现错误:
ORA-03113: 通信通道的文件结束
进程 ID: 6076
会话 ID: 138 序列号: 51

 

      可以看到,哥的通信通道文件结束了。这和排序散列聚簇有关系,可以看见我的Hash函数中包含了排序列,同时我的查询语句的执行计划会使用一种针对排序散列聚簇才有的物理操作符。这大概是执行计划和Hash函数的矛盾导致的一个bug。

  • bug2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
DROP CLUSTER CLUSTER_TEST1 INCLUDING TABLES;
 
create cluster CLUSTER_TEST1 (   c1 number
, c2 number
, c3 number  SORT
, c4 number SORT
    )
hashkeys 176
hash is ( (c1 - 1) * 10 + c2 - 1 + c4)
size 1490 ;
  
  create table CLUSTER_T1 (
    o_id number 
, o_w_id number
, o_d_id number
, o_c_id number
)
cluster ordrcluster_queue (
    o_w_id
, o_d_id
, o_id);            
  
   
SQL> INSERT INTO CLUSTER_T1 VALUES(1,1,1,1);
INSERT INTO CLUSTER_T1 VALUES(1,1,1,1)
            *
第 1 行出现错误:
ORA-03113: 通信通道的文件结束
进程 ID: 3708
会话 ID: 135 序列号: 623

 

        这个导致了连接断开,当然还是SORT的原因,在建立CLUSTER_TEST1这个簇的时候,指定的列为4列,但是我在簇上建表CLUSTER_T1的时候,只指定了3列,竟然坑爹地可以创建成功,我嘞个去,第四列同时在Hash函数中,这就导致我插入数据时,Hash函数就范2了,这尼玛都没指定对应的第四个列,让Hash函数肿么计算Hash values啊…

     都是Sort Hash Cluster惹的祸啊,拜托测试部的大佬们工作的时候别再看小电影了,Oracle在哥心目中的地位又是微微一颤啊…

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示