Greenplum列存压缩表事务机制

事务隔离级别

我们知道Heap表的事务隔离是通过MVCC实现,但是在列存表没有记录xmin,xmax等多版本信息,仅仅记录了块的元信息以及数据,那么它是如何实现事务隔离的?
仍然借助于Heap表,每创建一个列存表,同时创建一个heap辅助表表,通过select * from pg_appendonly可以看到辅助表的OID(segrelid),这个辅助表几面记录了什么呢?

typedef struct AOCSVPInfoEntry
{
        int64 eof;
        int64 eof_uncompressed;
} AOCSVPInfoEntry;

从这个结构体可以看出来,辅助表记录了当前事务在列存文件中可见的结尾偏移量。如果其他连接插入了数据,列存文件变大了,但是当前事务还是只能看到插入之前的结尾偏移量,多余的数据是看不到的。

如图所示,B事务新增的数据的EOF位置存在Heap表中,而Heap表满足MVCC的,所以A事务看不到B事务中Heap表的变更,继续使用A事务开始的是EOF。

6d16bfce2db5e8e9.png

总之,列存的事务原理是靠辅助Heap表实现的。

崩溃恢复

机器可能宕机、断电等,事务需要回滚,数据可能部分写,对于这些场景Greenplum列存是如何处理的呢?

cancel/kill等引起的正常事务回滚

在Greenplum列存表原理里面我们已经提到,并发导入是靠多个文件实现,也就是说每个Insert连接只会负责一个列文件,假设事务开始的时候文件EOF为EOF_start, 导入后变成EOF_end,如果事务回滚,辅助Heap表里面记录的EOF回滚到事务开始的EOF_start,回滚完成。下次事务导入将会从EOF_start继续增加数据,覆盖EOF_start--EOF_end之间的数据。

数据部分写

Greenplum列存表是不写XLOG的,那么它是如何做到崩溃之后恢复的呢?

  • 每次commit提交强制做fsync,所以只要事务提交,那么磁盘数据就是一致的,崩溃恢复不影响。
  • 新的事务导入数据,强制新增block,不能使用上一个事务的block,即便上一个事务的block还没有写满。这样就不会存在复用上一个事务block写数据时写到一半出问题丢失上个事务block的数据。因此强烈不建议使用每次insert一条方式导入数据,这样会产生的大量的block,每条记录都对一个block,影响扫描性能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值