398 Star 1.4K Fork 1.5K

GVPopenGauss / openGauss-server

 / 详情

列存表使用列属性compress_mode=DELTA,表异常

待办的
咨询
创建于  
2022-10-25 23:07

【标题描述】:
【测试类型:SQL功能/存储功能/接口功能/工具功能/性能/并发/压力长稳/故障注入/安全/资料/编码规范】【测试版本:2.0.0】 问题描述
普通列存表创建数据2100MB. 带compress_mode=DELTA时插入相同数据异常,插入时停不下来,中途停止插入发现已35GB

【操作系统和硬件信息】(查询命令: cat /etc/system-release;uname -a):
输入图片说明
【测试环境】(单机/1主x备x级联备):单机

【被测功能】:建表时,列的压缩选项compress_mode=DELTA

【测试类型】:列存表-列压缩

【数据库版本】(查询命令: gaussdb –V):
输入图片说明
【预置条件】:

【操作步骤】(请填写详细的操作步骤):
drop table if exists t1,t2,t3;
--普通列存表对照
create table t1(c_int int)WITH (ORIENTATION=COLUMN);
insert into t1 values(generate_series(1,10000000));

--带compress_mode选项
create table t2(c_int float Delta)WITH (ORIENTATION=COLUMN);
insert into t2 values(generate_series(1,10000000));

【预期输出】:
结果参考t1大小,或者实现列压缩,表大小更小

【实际输出】:
中途发现t2时间过久,终止插入,查询发现表为空,t2大小35GB,对照普通未压缩的列存表2100MB

【原因分析】:

  1. 这个问题的根因
  2. 问题推断过程
  3. 还有哪些原因可能造成类似现象
  4. 该问题是否有临时规避措施
  5. 问题解决方案
  6. 预计修复问题时间

【日志信息】(请附上日志文件、截图、coredump信息):

【测试代码】:

评论 (7)

zdai96 创建了缺陷

Hey @zdai96, Welcome to openGauss Community.
All of the projects in openGauss Community are maintained by @opengauss-bot.
That means the developers can comment below every pull request or issue to trigger Bot Commands.
Please follow instructions at Here to find the details.

Hi @zdai96, please use the command /sig xxx to add a SIG label to this issue.
For example: /sig sqlengine or /sig storageengine or /sig om or /sig ai and so on.
You can find more SIG labels from Here.
If you have no idea about that, please contact with @xiangxinyong , @zhangxubo .

yansong_lee 负责人设置为吴岳川
yansong_lee 优先级设置为主要
yansong_lee 优先级主要 修改为次要
yansong_lee 负责人吴岳川 修改为未设置
yansong_lee 添加协作者pengjiong
yansong_lee 负责人设置为pengjiong
yansong_lee 取消协作者pengjiong

跟压缩没有什么关系,issue中对比的是 int 和 float 类型,两个表不一样。
应该是 float 类型在列存场景下占用空间大,请列存责任田的同事确认下是否合理:
测试用建表语句:

create table t1(c_int float)WITH (ORIENTATION=COLUMN);
create table t4(c_int int) WITH (ORIENTATION=COLUMN);

分别插入 100W 数据:

insert into t1 values(generate_series(1,10000000));
insert into t4 values(generate_series(1,10000000));

占用空间如下,同样的数据量,int类型 210MB, float类型 8023MB:
输入图片说明
输入图片说明
输入图片说明

opengauss-bot 负责人pengjiong 修改为陈栋

非问题。
理由如下:操作的SQL非批量插入,而是点插。列存表存储结构决定了不适合使用点插,每次insert会使用一个新的CU,因此对存储空间占用巨大。列存表适用场景见https://opengauss.org/zh/docs/3.0.0/docs/BriefTutorial/%E5%88%97%E5%AD%98%E5%82%A8.html
正确的insert语句为

insert into t1 select generate_series(1,10000000);

这里再解释一下为什么点插语句int和float类型存储空间占用区别巨大。
列存表分为CU和CUDESC,前者是最小的列存单元,存储列存的数据;后者存储CU对应的一些信息,是行存表。每一个CU都对应CUDESC中的一行记录,这一行数据中除了CU的基本信息,还有min/max的字段,用于加速查询。
点插情况下int是一种特殊的类型,其max/min值与数据值相同,在本例中可以直接插入CUDESC内,通过min/max就可以把值取出来了,因此不会生成CU。而代码中限制了float没有min、max值,即使点插情况下也会生成CU(这里又有delta表概念,本例中未开启,因此不考虑),所以存储空间占用较大。
借用@pengjiong的例子,其中插入了100w条数据,float和int相比占用的CUDESC相同,但是float比int多生成了100w个CU,每个CU大小为8K,因此存储空间多了7813MB。

@陈栋 感谢解答!
这边在学习使用列存表的时候也看到了compress_mode的列属性,但选项的介绍比较少,是否可以补充一下使用介绍
输入图片说明

补充下批插测试结果

openGauss=# create table t_float(c float)WITH (ORIENTATION=COLUMN);
CREATE TABLE
openGauss=# create table t_int(c int)WITH (ORIENTATION=COLUMN);
CREATE TABLE
openGauss=# insert into t_float select generate_series(1,1000000);
INSERT 0 1000000
openGauss=# insert into t_int select generate_series(1,1000000);
INSERT 0 1000000
openGauss=# \d+
                                         List of relations
 Schema |  Name   | Type  |  Owner   |  Size   |               Storage                | Description
--------+---------+-------+----------+---------+--------------------------------------+-------------
 public | t_float | table | chendong | 6968 kB | {orientation=column,compression=low} |
 public | t_int   | table | chendong | 2032 kB | {orientation=column,compression=low} |
(2 rows)
zdai96 修改了描述
zdai96 任务类型缺陷 修改为咨询
陈栋 负责人陈栋 修改为未设置

登录 后才可以发表评论

状态
负责人
项目
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
预计工期 (小时)
参与者(4)
5622128 opengauss bot 1581905080
C++
1
https://gitee.com/opengauss/openGauss-server.git
git@gitee.com:opengauss/openGauss-server.git
opengauss
openGauss-server
openGauss-server

搜索帮助