南大通用GBase 8a集群删除数据后释放磁盘空间shrink space

背景

GBase 8a 集群在delete一些行后,是不释放其占用的磁盘空间的,只是在这些行打上了一个【已删除】的标记。 其空间也不会被后续新加入的数据重复使用。

原因是8a是列存,每65536行做成一个DataCell单元,并对其做了压缩后,集中保存。如果每删除一行就释放空间,那么所有的数据都要重新计算一遍,来避免空间浪费,其成本是很大的。而如果复用,不仅不能确保新数据压缩后,一定不会超过原来占用的磁盘大小,而且由于delete数据不连续,也会造成大量的随机读写,影响性能。

参考

GBase 8a数据文件大小参数_gbase_segment_size

解决方案

seg数据文件级释放空间

alter table TTT shrink space

释放掉连续删除的数据文件的空间。请注意,8a集群按列存储,如果某个列的数据超过了2G(压缩后), 则新建一个文件,并增加一个数字的后缀。 如果要删除,必须这个文件里的所有行,都处于【被删除】状态。 否则即使这2G文件里,即使只有1行非删除,将不能删除文件来释放空间。

批量删除文件可以快速的释放空间,对于每日有大量数据入库和删除的,可以逐渐接近空间占用平衡。

建议配合如下参数使用 GBase 8a数据文件大小参数_gbase_segment_size

优点

耗时短,只有那些整个seg文件内的数据全部是删除状态,才会删除文件来释放空间

缺点

释放空间不彻底

行级释放空间

alter table TTT shrink space full 

警告

早期的版本,有可能出现数据错误, 所以对于没有gcluster_shrink_to_rebalance参数的版本,请联系支持人员该版本是否支持

目前(2021-12-30)已知8.6.2.33.R44、8.6.2.43.R31、9.5.2.33、9.5.3.19及之后的版本已经解决。

建议用带gcluster_shrink_to_rebalance的版本,设置gcluster_shrink_to_rebalance=1, 然后用带FULL的方法。

这个full参数,是让数据库完全重建这个表,回收所有的空间。副作用是耗时很长,基本可以理解为新建一个表,然后把数据insert select过去。

如下是使用gcluster_shrink_to_rebalance=1时,从gcluster的express.log看到的重分布日志。注意其中的BALANCE字样。

gbase> show variables like '%gcluster_shrink_to_rebalance%';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| gcluster_shrink_to_rebalance | OFF   |
+------------------------------+-------+
1 row in set (Elapsed: 00:00:00.00)

gbase> set gcluster_shrink_to_rebalance=1;
Query OK, 0 rows affected (Elapsed: 00:00:00.00)

。。。

2022-06-21 09:27:20.867 [DDL][WARN ][S:237][Q:376]<ExecuteUseNormalMode|3936>:  running in recovery mode for scn: 7172
2022-06-21 09:27:20.949 [BALANCE][INFO ][S:25][Q:347]<RecordPrint|3255>:
+------------------+---------------+-----------------+-------------+------------+---------+----------------+--------------------------+
|                                                        testdb.t1 from 6 to 6                                                         |
+------------------+---------------+-----------------+-------------+------------+---------+----------------+--------------------------+
| REB_CREATE_TABLE | REB_DATA_MOVE | REB_EXEC_POLICY | REB_GC_LOCK | REB_RENAME | REB_SIS | REB_SIS_COMMIT | REB_UPDATE_FAILOVER_INFO |
+------------------+---------------+-----------------+-------------+------------+---------+----------------+--------------------------+
| 1                | 0             | 1               | 0           | 0          | 0       | 0              | 0                        |
+------------------+---------------+-----------------+-------------+------------+---------+----------------+--------------------------+

You have new mail in /var/spool/mail/root
[root@gbase_rh7_001 gcluster]#

优点

彻底释放删除数据占用的空间

缺点

耗时长,特别是针对行特别多,列特别多的表。

DC级释放空间

警告

早期的版本,有可能出现数据错误, 所以对于没有gcluster_shrink_to_rebalance参数的版本,请联系支持人员该版本是否支持

目前(2021-12-30)已知8.6.2.33.R44、8.6.2.43.R31、9.5.2.33、9.5.3.19及之后的版本已经解决。

alter table t shrink space full block_reuse_ratio=30

FULL BLOCK_REUSE_RATIO:块级(DC)回收,DC 中有效数据占比大于等于设置值时该 DC 保留重用,有效数据占比低于该设置值时 DC 空间进行整合,回收无效数据空间,DC 整合后重新落盘写 seg 文件,无法保证原始顺序。

比如90, 则代表如果一个DC内,有大于等于90%的数据还在用,也就是只有不到10%的删除数据,则【保留】。

优点

可自定义比例,相对不带full的可以释放更多的空间。

缺点

比不带full的耗时更长,但比只带full的耗时短。

使用天表或者天分区

然后按照整天或者整个分区的drop掉就可以了。 前提是你的数据有比较强的时间关联性。

方案对比

性能对比

天表>shrink space > shrink space full block_reuse_ratio > shrink space full

空间释放率

天表 > shrink space full > shrink space full block_reuse_ratio > shrink space

总结

由于shrink spce full的耗时确实很长,等同于表重建,所以对于大表,行多和列多,特别是保存周期非常长的,重建的代价可能无法承担,所以还是建议优先分表或者分区。 具体可接受访问,可以自行重建一下看影响是否接受。

  • 对于大表,且有明确边界的数据,比如时间相关、区域相关的数据,按该字段删除的,建议考虑天表或天分区,快速释放空间。
  • 对于频繁更新的小表,比如任务调度表,建议定期,比如每周(需要根据性能下降情况以及磁盘使用情况评估),执行一次shrink space full
  • 如不可接受重建代价,建议通过shrink space来释放空间。同时磁盘空间要【充足】,超过50-60%就要根据历史情况评估磁盘预期,必要时扩容。
  • 如评估shrink space full可接受,也建议每周或每月一次。